VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c@ 105670

最後變更 在這個檔案從105670是 105670,由 vboxsync 提交於 6 月 前

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 52.7 KB
 
1/** @file
2 Driver Binding functions implementation for UefiPxeBc Driver.
3
4 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
6 Copyright (c) Microsoft Corporation
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include "PxeBcImpl.h"
13
14EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp4DriverBinding = {
15 PxeBcIp4DriverBindingSupported,
16 PxeBcIp4DriverBindingStart,
17 PxeBcIp4DriverBindingStop,
18 0xa,
19 NULL,
20 NULL
21};
22
23EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp6DriverBinding = {
24 PxeBcIp6DriverBindingSupported,
25 PxeBcIp6DriverBindingStart,
26 PxeBcIp6DriverBindingStop,
27 0xa,
28 NULL,
29 NULL
30};
31
32/**
33 Get the Nic handle using any child handle in the IPv4 stack.
34
35 @param[in] ControllerHandle Pointer to child handle over IPv4.
36
37 @return NicHandle The pointer to the Nic handle.
38
39**/
40EFI_HANDLE
41PxeBcGetNicByIp4Children (
42 IN EFI_HANDLE ControllerHandle
43 )
44{
45 EFI_HANDLE NicHandle;
46
47 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
48 if (NicHandle == NULL) {
49 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
50 if (NicHandle == NULL) {
51 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
52 if (NicHandle == NULL) {
53 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
54 if (NicHandle == NULL) {
55 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
56 if (NicHandle == NULL) {
57 return NULL;
58 }
59 }
60 }
61 }
62 }
63
64 return NicHandle;
65}
66
67/**
68 Get the Nic handle using any child handle in the IPv6 stack.
69
70 @param[in] ControllerHandle Pointer to child handle over IPv6.
71
72 @return NicHandle The pointer to the Nic handle.
73
74**/
75EFI_HANDLE
76PxeBcGetNicByIp6Children (
77 IN EFI_HANDLE ControllerHandle
78 )
79{
80 EFI_HANDLE NicHandle;
81
82 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
83 if (NicHandle == NULL) {
84 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);
85 if (NicHandle == NULL) {
86 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
87 if (NicHandle == NULL) {
88 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp6ProtocolGuid);
89 if (NicHandle == NULL) {
90 return NULL;
91 }
92 }
93 }
94 }
95
96 return NicHandle;
97}
98
99/**
100 Destroy the opened instances based on IPv4.
101
102 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
103 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.
104
105**/
106VOID
107PxeBcDestroyIp4Children (
108 IN EFI_DRIVER_BINDING_PROTOCOL *This,
109 IN PXEBC_PRIVATE_DATA *Private
110 )
111{
112 ASSERT (Private != NULL);
113
114 if (Private->ArpChild != NULL) {
115 //
116 // Close Arp for PxeBc->Arp and destroy the instance.
117 //
118 gBS->CloseProtocol (
119 Private->ArpChild,
120 &gEfiArpProtocolGuid,
121 This->DriverBindingHandle,
122 Private->Controller
123 );
124
125 NetLibDestroyServiceChild (
126 Private->Controller,
127 This->DriverBindingHandle,
128 &gEfiArpServiceBindingProtocolGuid,
129 Private->ArpChild
130 );
131 }
132
133 if (Private->Ip4Child != NULL) {
134 //
135 // Close Ip4 for background ICMP error message and destroy the instance.
136 //
137 gBS->CloseProtocol (
138 Private->Ip4Child,
139 &gEfiIp4ProtocolGuid,
140 This->DriverBindingHandle,
141 Private->Controller
142 );
143
144 NetLibDestroyServiceChild (
145 Private->Controller,
146 This->DriverBindingHandle,
147 &gEfiIp4ServiceBindingProtocolGuid,
148 Private->Ip4Child
149 );
150 }
151
152 if (Private->Udp4WriteChild != NULL) {
153 //
154 // Close Udp4 for PxeBc->UdpWrite and destroy the instance.
155 //
156 gBS->CloseProtocol (
157 Private->Udp4WriteChild,
158 &gEfiUdp4ProtocolGuid,
159 This->DriverBindingHandle,
160 Private->Controller
161 );
162
163 NetLibDestroyServiceChild (
164 Private->Controller,
165 This->DriverBindingHandle,
166 &gEfiUdp4ServiceBindingProtocolGuid,
167 Private->Udp4WriteChild
168 );
169 }
170
171 if (Private->Udp4ReadChild != NULL) {
172 //
173 // Close Udp4 for PxeBc->UdpRead and destroy the instance.
174 //
175 gBS->CloseProtocol (
176 Private->Udp4ReadChild,
177 &gEfiUdp4ProtocolGuid,
178 This->DriverBindingHandle,
179 Private->Controller
180 );
181
182 NetLibDestroyServiceChild (
183 Private->Controller,
184 This->DriverBindingHandle,
185 &gEfiUdp4ServiceBindingProtocolGuid,
186 Private->Udp4ReadChild
187 );
188 }
189
190 if (Private->Mtftp4Child != NULL) {
191 //
192 // Close Mtftp4 for PxeBc->Mtftp4 and destroy the instance.
193 //
194 gBS->CloseProtocol (
195 Private->Mtftp4Child,
196 &gEfiMtftp4ProtocolGuid,
197 This->DriverBindingHandle,
198 Private->Controller
199 );
200
201 NetLibDestroyServiceChild (
202 Private->Controller,
203 This->DriverBindingHandle,
204 &gEfiMtftp4ServiceBindingProtocolGuid,
205 Private->Mtftp4Child
206 );
207 }
208
209 if (Private->Dhcp4Child != NULL) {
210 //
211 // Close Dhcp4 for PxeBc->Dhcp4 and destroy the instance.
212 //
213 gBS->CloseProtocol (
214 Private->Dhcp4Child,
215 &gEfiDhcp4ProtocolGuid,
216 This->DriverBindingHandle,
217 Private->Controller
218 );
219
220 NetLibDestroyServiceChild (
221 Private->Controller,
222 This->DriverBindingHandle,
223 &gEfiDhcp4ServiceBindingProtocolGuid,
224 Private->Dhcp4Child
225 );
226 }
227
228 if (Private->Ip4Nic != NULL) {
229 //
230 // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.
231 //
232 gBS->CloseProtocol (
233 Private->Controller,
234 &gEfiCallerIdGuid,
235 This->DriverBindingHandle,
236 Private->Ip4Nic->Controller
237 );
238
239 gBS->UninstallMultipleProtocolInterfaces (
240 Private->Ip4Nic->Controller,
241 &gEfiDevicePathProtocolGuid,
242 Private->Ip4Nic->DevicePath,
243 &gEfiLoadFileProtocolGuid,
244 &Private->Ip4Nic->LoadFile,
245 &gEfiPxeBaseCodeProtocolGuid,
246 &Private->PxeBc,
247 NULL
248 );
249 FreePool (Private->Ip4Nic->DevicePath);
250
251 if (Private->Snp != NULL) {
252 //
253 // Close SNP from the child virtual handle
254 //
255 gBS->CloseProtocol (
256 Private->Ip4Nic->Controller,
257 &gEfiSimpleNetworkProtocolGuid,
258 This->DriverBindingHandle,
259 Private->Ip4Nic->Controller
260 );
261
262 gBS->UninstallProtocolInterface (
263 Private->Ip4Nic->Controller,
264 &gEfiSimpleNetworkProtocolGuid,
265 Private->Snp
266 );
267 }
268
269 FreePool (Private->Ip4Nic);
270 }
271
272 Private->ArpChild = NULL;
273 Private->Ip4Child = NULL;
274 Private->Udp4WriteChild = NULL;
275 Private->Udp4ReadChild = NULL;
276 Private->Mtftp4Child = NULL;
277 Private->Dhcp4Child = NULL;
278 Private->Ip4Nic = NULL;
279}
280
281/**
282 Destroy the opened instances based on IPv6.
283
284 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
285 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.
286
287**/
288VOID
289PxeBcDestroyIp6Children (
290 IN EFI_DRIVER_BINDING_PROTOCOL *This,
291 IN PXEBC_PRIVATE_DATA *Private
292 )
293{
294 ASSERT (Private != NULL);
295
296 if (Private->Ip6Child != NULL) {
297 //
298 // Close Ip6 for Ip6->Ip6Config and destroy the instance.
299 //
300 gBS->CloseProtocol (
301 Private->Ip6Child,
302 &gEfiIp6ProtocolGuid,
303 This->DriverBindingHandle,
304 Private->Controller
305 );
306
307 NetLibDestroyServiceChild (
308 Private->Controller,
309 This->DriverBindingHandle,
310 &gEfiIp6ServiceBindingProtocolGuid,
311 Private->Ip6Child
312 );
313 }
314
315 if (Private->Udp6WriteChild != NULL) {
316 //
317 // Close Udp6 for PxeBc->UdpWrite and destroy the instance.
318 //
319 gBS->CloseProtocol (
320 Private->Udp6WriteChild,
321 &gEfiUdp6ProtocolGuid,
322 This->DriverBindingHandle,
323 Private->Controller
324 );
325 NetLibDestroyServiceChild (
326 Private->Controller,
327 This->DriverBindingHandle,
328 &gEfiUdp6ServiceBindingProtocolGuid,
329 Private->Udp6WriteChild
330 );
331 }
332
333 if (Private->Udp6ReadChild != NULL) {
334 //
335 // Close Udp6 for PxeBc->UdpRead and destroy the instance.
336 //
337 gBS->CloseProtocol (
338 Private->Udp6ReadChild,
339 &gEfiUdp6ProtocolGuid,
340 This->DriverBindingHandle,
341 Private->Controller
342 );
343 NetLibDestroyServiceChild (
344 Private->Controller,
345 This->DriverBindingHandle,
346 &gEfiUdp6ServiceBindingProtocolGuid,
347 Private->Udp6ReadChild
348 );
349 }
350
351 if (Private->Mtftp6Child != NULL) {
352 //
353 // Close Mtftp6 for PxeBc->Mtftp and destroy the instance.
354 //
355 gBS->CloseProtocol (
356 Private->Mtftp6Child,
357 &gEfiMtftp6ProtocolGuid,
358 This->DriverBindingHandle,
359 Private->Controller
360 );
361
362 NetLibDestroyServiceChild (
363 Private->Controller,
364 This->DriverBindingHandle,
365 &gEfiMtftp6ServiceBindingProtocolGuid,
366 Private->Mtftp6Child
367 );
368 }
369
370 if (Private->Dhcp6Child != NULL) {
371 //
372 // Close Dhcp6 for PxeBc->Dhcp and destroy the instance.
373 //
374 gBS->CloseProtocol (
375 Private->Dhcp6Child,
376 &gEfiDhcp6ProtocolGuid,
377 This->DriverBindingHandle,
378 Private->Controller
379 );
380
381 NetLibDestroyServiceChild (
382 Private->Controller,
383 This->DriverBindingHandle,
384 &gEfiDhcp6ServiceBindingProtocolGuid,
385 Private->Dhcp6Child
386 );
387 }
388
389 if (Private->Ip6Nic != NULL) {
390 //
391 // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.
392 //
393 gBS->CloseProtocol (
394 Private->Controller,
395 &gEfiCallerIdGuid,
396 This->DriverBindingHandle,
397 Private->Ip6Nic->Controller
398 );
399
400 gBS->UninstallMultipleProtocolInterfaces (
401 Private->Ip6Nic->Controller,
402 &gEfiDevicePathProtocolGuid,
403 Private->Ip6Nic->DevicePath,
404 &gEfiLoadFileProtocolGuid,
405 &Private->Ip6Nic->LoadFile,
406 &gEfiPxeBaseCodeProtocolGuid,
407 &Private->PxeBc,
408 NULL
409 );
410 FreePool (Private->Ip6Nic->DevicePath);
411
412 if (Private->Snp != NULL) {
413 //
414 // Close SNP from the child virtual handle
415 //
416 gBS->CloseProtocol (
417 Private->Ip6Nic->Controller,
418 &gEfiSimpleNetworkProtocolGuid,
419 This->DriverBindingHandle,
420 Private->Ip6Nic->Controller
421 );
422 gBS->UninstallProtocolInterface (
423 Private->Ip6Nic->Controller,
424 &gEfiSimpleNetworkProtocolGuid,
425 Private->Snp
426 );
427 }
428
429 FreePool (Private->Ip6Nic);
430 }
431
432 Private->Ip6Child = NULL;
433 Private->Udp6WriteChild = NULL;
434 Private->Udp6ReadChild = NULL;
435 Private->Mtftp6Child = NULL;
436 Private->Dhcp6Child = NULL;
437 Private->Ip6Nic = NULL;
438 Private->Mode.Ipv6Available = FALSE;
439}
440
441/**
442 Check whether UNDI protocol supports IPv6.
443
444 @param[in] ControllerHandle Controller handle.
445 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.
446 @param[out] Ipv6Support TRUE if UNDI supports IPv6.
447
448 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
449 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
450
451**/
452EFI_STATUS
453PxeBcCheckIpv6Support (
454 IN EFI_HANDLE ControllerHandle,
455 IN PXEBC_PRIVATE_DATA *Private,
456 OUT BOOLEAN *Ipv6Support
457 )
458{
459 EFI_HANDLE Handle;
460 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
461 EFI_STATUS Status;
462 EFI_GUID *InfoTypesBuffer;
463 UINTN InfoTypeBufferCount;
464 UINTN TypeIndex;
465 BOOLEAN Supported;
466 VOID *InfoBlock;
467 UINTN InfoBlockSize;
468
469 ASSERT (Private != NULL && Ipv6Support != NULL);
470
471 //
472 // Check whether the UNDI supports IPv6 by NII protocol.
473 //
474 if (Private->Nii != NULL) {
475 *Ipv6Support = Private->Nii->Ipv6Supported;
476 return EFI_SUCCESS;
477 }
478
479 //
480 // Check whether the UNDI supports IPv6 by AIP protocol.
481 //
482
483 //
484 // Get the NIC handle by SNP protocol.
485 //
486 Handle = NetLibGetSnpHandle (ControllerHandle, NULL);
487 if (Handle == NULL) {
488 return EFI_NOT_FOUND;
489 }
490
491 Aip = NULL;
492 Status = gBS->HandleProtocol (
493 Handle,
494 &gEfiAdapterInformationProtocolGuid,
495 (VOID *)&Aip
496 );
497 if (EFI_ERROR (Status) || (Aip == NULL)) {
498 return EFI_NOT_FOUND;
499 }
500
501 InfoTypesBuffer = NULL;
502 InfoTypeBufferCount = 0;
503 Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
504 if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {
505 FreePool (InfoTypesBuffer);
506 return EFI_NOT_FOUND;
507 }
508
509 Supported = FALSE;
510 for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
511 if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
512 Supported = TRUE;
513 break;
514 }
515 }
516
517 FreePool (InfoTypesBuffer);
518 if (!Supported) {
519 return EFI_NOT_FOUND;
520 }
521
522 //
523 // We now have adapter information block.
524 //
525 InfoBlock = NULL;
526 InfoBlockSize = 0;
527 Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);
528 if (EFI_ERROR (Status) || (InfoBlock == NULL)) {
529 FreePool (InfoBlock);
530 return EFI_NOT_FOUND;
531 }
532
533 *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InfoBlock)->Ipv6Support;
534 FreePool (InfoBlock);
535 return EFI_SUCCESS;
536}
537
538/**
539 Create the opened instances based on IPv4.
540
541 @param[in] This Pointer to EFI_DRIVER_BINDING_PROTOCOL.
542 @param[in] ControllerHandle Handle of the child to destroy.
543 @param[in] Private Handle Pointer to PXEBC_PRIVATE_DATA.
544
545 @retval EFI_SUCCESS The instances based on IPv4 were all created successfully.
546 @retval Others An unexpected error occurred.
547
548**/
549EFI_STATUS
550PxeBcCreateIp4Children (
551 IN EFI_DRIVER_BINDING_PROTOCOL *This,
552 IN EFI_HANDLE ControllerHandle,
553 IN PXEBC_PRIVATE_DATA *Private
554 )
555{
556 EFI_STATUS Status;
557 IPv4_DEVICE_PATH Ip4Node;
558 EFI_PXE_BASE_CODE_MODE *Mode;
559 EFI_UDP4_CONFIG_DATA *Udp4CfgData;
560 EFI_IP4_CONFIG_DATA *Ip4CfgData;
561 EFI_IP4_MODE_DATA Ip4ModeData;
562 PXEBC_PRIVATE_PROTOCOL *Id;
563 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
564
565 if (Private->Ip4Nic != NULL) {
566 //
567 // Already created before.
568 //
569 return EFI_SUCCESS;
570 }
571
572 //
573 // Create Dhcp4 child and open Dhcp4 protocol for PxeBc->Dhcp.
574 //
575 Status = NetLibCreateServiceChild (
576 ControllerHandle,
577 This->DriverBindingHandle,
578 &gEfiDhcp4ServiceBindingProtocolGuid,
579 &Private->Dhcp4Child
580 );
581 if (EFI_ERROR (Status)) {
582 goto ON_ERROR;
583 }
584
585 Status = gBS->OpenProtocol (
586 Private->Dhcp4Child,
587 &gEfiDhcp4ProtocolGuid,
588 (VOID **)&Private->Dhcp4,
589 This->DriverBindingHandle,
590 ControllerHandle,
591 EFI_OPEN_PROTOCOL_BY_DRIVER
592 );
593 if (EFI_ERROR (Status)) {
594 goto ON_ERROR;
595 }
596
597 //
598 // Create Mtftp4 child and open Mtftp4 protocol for PxeBc->Mtftp.
599 //
600 Status = NetLibCreateServiceChild (
601 ControllerHandle,
602 This->DriverBindingHandle,
603 &gEfiMtftp4ServiceBindingProtocolGuid,
604 &Private->Mtftp4Child
605 );
606 if (EFI_ERROR (Status)) {
607 goto ON_ERROR;
608 }
609
610 Status = gBS->OpenProtocol (
611 Private->Mtftp4Child,
612 &gEfiMtftp4ProtocolGuid,
613 (VOID **)&Private->Mtftp4,
614 This->DriverBindingHandle,
615 ControllerHandle,
616 EFI_OPEN_PROTOCOL_BY_DRIVER
617 );
618 if (EFI_ERROR (Status)) {
619 goto ON_ERROR;
620 }
621
622 //
623 // Create Udp4 child and open Udp4 protocol for PxeBc->UdpRead.
624 //
625 Status = NetLibCreateServiceChild (
626 ControllerHandle,
627 This->DriverBindingHandle,
628 &gEfiUdp4ServiceBindingProtocolGuid,
629 &Private->Udp4ReadChild
630 );
631 if (EFI_ERROR (Status)) {
632 goto ON_ERROR;
633 }
634
635 Status = gBS->OpenProtocol (
636 Private->Udp4ReadChild,
637 &gEfiUdp4ProtocolGuid,
638 (VOID **)&Private->Udp4Read,
639 This->DriverBindingHandle,
640 ControllerHandle,
641 EFI_OPEN_PROTOCOL_BY_DRIVER
642 );
643 if (EFI_ERROR (Status)) {
644 goto ON_ERROR;
645 }
646
647 //
648 // Create Udp4 child and open Udp4 protocol for PxeBc->UdpWrite.
649 //
650 Status = NetLibCreateServiceChild (
651 ControllerHandle,
652 This->DriverBindingHandle,
653 &gEfiUdp4ServiceBindingProtocolGuid,
654 &Private->Udp4WriteChild
655 );
656 if (EFI_ERROR (Status)) {
657 goto ON_ERROR;
658 }
659
660 Status = gBS->OpenProtocol (
661 Private->Udp4WriteChild,
662 &gEfiUdp4ProtocolGuid,
663 (VOID **)&Private->Udp4Write,
664 This->DriverBindingHandle,
665 ControllerHandle,
666 EFI_OPEN_PROTOCOL_BY_DRIVER
667 );
668 if (EFI_ERROR (Status)) {
669 goto ON_ERROR;
670 }
671
672 //
673 // Create Arp child and open Arp protocol for PxeBc->Arp.
674 //
675 Status = NetLibCreateServiceChild (
676 ControllerHandle,
677 This->DriverBindingHandle,
678 &gEfiArpServiceBindingProtocolGuid,
679 &Private->ArpChild
680 );
681 if (EFI_ERROR (Status)) {
682 goto ON_ERROR;
683 }
684
685 Status = gBS->OpenProtocol (
686 Private->ArpChild,
687 &gEfiArpProtocolGuid,
688 (VOID **)&Private->Arp,
689 This->DriverBindingHandle,
690 ControllerHandle,
691 EFI_OPEN_PROTOCOL_BY_DRIVER
692 );
693 if (EFI_ERROR (Status)) {
694 goto ON_ERROR;
695 }
696
697 //
698 // Create Ip4 child and open Ip4 protocol for background ICMP packets.
699 //
700 Status = NetLibCreateServiceChild (
701 ControllerHandle,
702 This->DriverBindingHandle,
703 &gEfiIp4ServiceBindingProtocolGuid,
704 &Private->Ip4Child
705 );
706 if (EFI_ERROR (Status)) {
707 goto ON_ERROR;
708 }
709
710 Status = gBS->OpenProtocol (
711 Private->Ip4Child,
712 &gEfiIp4ProtocolGuid,
713 (VOID **)&Private->Ip4,
714 This->DriverBindingHandle,
715 ControllerHandle,
716 EFI_OPEN_PROTOCOL_BY_DRIVER
717 );
718 if (EFI_ERROR (Status)) {
719 goto ON_ERROR;
720 }
721
722 //
723 // Get max packet size from Ip4 to calculate block size for Tftp later.
724 //
725 Status = Private->Ip4->GetModeData (Private->Ip4, &Ip4ModeData, NULL, NULL);
726 if (EFI_ERROR (Status)) {
727 goto ON_ERROR;
728 }
729
730 Private->Ip4MaxPacketSize = Ip4ModeData.MaxPacketSize;
731
732 Private->Ip4Nic = AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC));
733 if (Private->Ip4Nic == NULL) {
734 return EFI_OUT_OF_RESOURCES;
735 }
736
737 Private->Ip4Nic->Private = Private;
738 Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;
739
740 //
741 // Locate Ip4->Ip4Config2 and store it for set IPv4 Policy.
742 //
743 Status = gBS->HandleProtocol (
744 ControllerHandle,
745 &gEfiIp4Config2ProtocolGuid,
746 (VOID **)&Private->Ip4Config2
747 );
748 if (EFI_ERROR (Status)) {
749 goto ON_ERROR;
750 }
751
752 //
753 // Create a device path node for Ipv4 virtual nic, and append it.
754 //
755 ZeroMem (&Ip4Node, sizeof (IPv4_DEVICE_PATH));
756 Ip4Node.Header.Type = MESSAGING_DEVICE_PATH;
757 Ip4Node.Header.SubType = MSG_IPv4_DP;
758 Ip4Node.StaticIpAddress = FALSE;
759
760 SetDevicePathNodeLength (&Ip4Node.Header, sizeof (Ip4Node));
761
762 Private->Ip4Nic->DevicePath = AppendDevicePathNode (Private->DevicePath, &Ip4Node.Header);
763
764 if (Private->Ip4Nic->DevicePath == NULL) {
765 Status = EFI_OUT_OF_RESOURCES;
766 goto ON_ERROR;
767 }
768
769 CopyMem (
770 &Private->Ip4Nic->LoadFile,
771 &gLoadFileProtocolTemplate,
772 sizeof (EFI_LOAD_FILE_PROTOCOL)
773 );
774
775 //
776 // Create a new handle for IPv4 virtual nic,
777 // and install PxeBaseCode, LoadFile and DevicePath protocols.
778 //
779 Status = gBS->InstallMultipleProtocolInterfaces (
780 &Private->Ip4Nic->Controller,
781 &gEfiDevicePathProtocolGuid,
782 Private->Ip4Nic->DevicePath,
783 &gEfiLoadFileProtocolGuid,
784 &Private->Ip4Nic->LoadFile,
785 &gEfiPxeBaseCodeProtocolGuid,
786 &Private->PxeBc,
787 NULL
788 );
789 if (EFI_ERROR (Status)) {
790 goto ON_ERROR;
791 }
792
793 if (Private->Snp != NULL) {
794 //
795 // Install SNP protocol on purpose is for some OS loader backward
796 // compatibility consideration.
797 //
798 Status = gBS->InstallProtocolInterface (
799 &Private->Ip4Nic->Controller,
800 &gEfiSimpleNetworkProtocolGuid,
801 EFI_NATIVE_INTERFACE,
802 Private->Snp
803 );
804 if (EFI_ERROR (Status)) {
805 goto ON_ERROR;
806 }
807
808 //
809 // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally
810 // layering to perform the experiment.
811 //
812 Status = gBS->OpenProtocol (
813 Private->Ip4Nic->Controller,
814 &gEfiSimpleNetworkProtocolGuid,
815 (VOID **)&Snp,
816 This->DriverBindingHandle,
817 Private->Ip4Nic->Controller,
818 EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE
819 );
820 if (EFI_ERROR (Status)) {
821 goto ON_ERROR;
822 }
823 }
824
825 //
826 // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between
827 // real NIC handle and the virtual IPv4 NIC handle.
828 //
829 Status = gBS->OpenProtocol (
830 ControllerHandle,
831 &gEfiCallerIdGuid,
832 (VOID **)&Id,
833 This->DriverBindingHandle,
834 Private->Ip4Nic->Controller,
835 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
836 );
837 if (EFI_ERROR (Status)) {
838 goto ON_ERROR;
839 }
840
841 //
842 // Set default configure data for Udp4Read and Ip4 instance.
843 //
844 Mode = Private->PxeBc.Mode;
845 Udp4CfgData = &Private->Udp4CfgData;
846 Ip4CfgData = &Private->Ip4CfgData;
847
848 Udp4CfgData->AcceptBroadcast = FALSE;
849 Udp4CfgData->AcceptAnyPort = TRUE;
850 Udp4CfgData->AllowDuplicatePort = TRUE;
851 Udp4CfgData->TypeOfService = Mode->ToS;
852 Udp4CfgData->TimeToLive = Mode->TTL;
853 Udp4CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
854 Udp4CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
855
856 Ip4CfgData->AcceptIcmpErrors = TRUE;
857 Ip4CfgData->DefaultProtocol = EFI_IP_PROTO_ICMP;
858 Ip4CfgData->TypeOfService = Mode->ToS;
859 Ip4CfgData->TimeToLive = Mode->TTL;
860 Ip4CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
861 Ip4CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
862
863 return EFI_SUCCESS;
864
865ON_ERROR:
866 PxeBcDestroyIp4Children (This, Private);
867 return Status;
868}
869
870/**
871 Create the opened instances based on IPv6.
872
873 @param[in] This Pointer to EFI_DRIVER_BINDING_PROTOCOL.
874 @param[in] ControllerHandle Handle of the child to destroy.
875 @param[in] Private Handle Pointer to PXEBC_PRIVATE_DATA.
876
877 @retval EFI_SUCCESS The instances based on IPv6 were all created successfully.
878 @retval Others An unexpected error occurred.
879
880**/
881EFI_STATUS
882PxeBcCreateIp6Children (
883 IN EFI_DRIVER_BINDING_PROTOCOL *This,
884 IN EFI_HANDLE ControllerHandle,
885 IN PXEBC_PRIVATE_DATA *Private
886 )
887{
888 EFI_STATUS Status;
889 IPv6_DEVICE_PATH Ip6Node;
890 EFI_UDP6_CONFIG_DATA *Udp6CfgData;
891 EFI_IP6_CONFIG_DATA *Ip6CfgData;
892 EFI_IP6_MODE_DATA Ip6ModeData;
893 PXEBC_PRIVATE_PROTOCOL *Id;
894 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
895 UINTN Index;
896 UINT32 Random;
897
898 Status = PseudoRandomU32 (&Random);
899 if (EFI_ERROR (Status)) {
900 DEBUG ((DEBUG_ERROR, "Failed to generate random number using EFI_RNG_PROTOCOL: %r\n", Status));
901 return Status;
902 }
903
904 if (Private->Ip6Nic != NULL) {
905 //
906 // Already created before.
907 //
908 return EFI_SUCCESS;
909 }
910
911 Private->Ip6Nic = AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC));
912
913 if (Private->Ip6Nic == NULL) {
914 return EFI_OUT_OF_RESOURCES;
915 }
916
917 Private->Ip6Nic->Private = Private;
918 Private->Ip6Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;
919
920 //
921 // Create Dhcp6 child and open Dhcp6 protocol for PxeBc->Dhcp.
922 //
923 Status = NetLibCreateServiceChild (
924 ControllerHandle,
925 This->DriverBindingHandle,
926 &gEfiDhcp6ServiceBindingProtocolGuid,
927 &Private->Dhcp6Child
928 );
929 if (EFI_ERROR (Status)) {
930 goto ON_ERROR;
931 }
932
933 Status = gBS->OpenProtocol (
934 Private->Dhcp6Child,
935 &gEfiDhcp6ProtocolGuid,
936 (VOID **)&Private->Dhcp6,
937 This->DriverBindingHandle,
938 ControllerHandle,
939 EFI_OPEN_PROTOCOL_BY_DRIVER
940 );
941 if (EFI_ERROR (Status)) {
942 goto ON_ERROR;
943 }
944
945 //
946 // Set a random IAID for the Dhcp6 assigned address.
947 //
948 Private->IaId = Random;
949 if (Private->Snp != NULL) {
950 for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) {
951 Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31));
952 }
953 }
954
955 //
956 // Create Mtftp6 child and open Mtftp6 protocol for PxeBc->Mtftp.
957 //
958 Status = NetLibCreateServiceChild (
959 ControllerHandle,
960 This->DriverBindingHandle,
961 &gEfiMtftp6ServiceBindingProtocolGuid,
962 &Private->Mtftp6Child
963 );
964 if (EFI_ERROR (Status)) {
965 goto ON_ERROR;
966 }
967
968 Status = gBS->OpenProtocol (
969 Private->Mtftp6Child,
970 &gEfiMtftp6ProtocolGuid,
971 (VOID **)&Private->Mtftp6,
972 This->DriverBindingHandle,
973 ControllerHandle,
974 EFI_OPEN_PROTOCOL_BY_DRIVER
975 );
976 if (EFI_ERROR (Status)) {
977 goto ON_ERROR;
978 }
979
980 //
981 // Create Udp6 child and open Udp6 protocol for PxeBc->UdpRead.
982 //
983 Status = NetLibCreateServiceChild (
984 ControllerHandle,
985 This->DriverBindingHandle,
986 &gEfiUdp6ServiceBindingProtocolGuid,
987 &Private->Udp6ReadChild
988 );
989 if (EFI_ERROR (Status)) {
990 goto ON_ERROR;
991 }
992
993 Status = gBS->OpenProtocol (
994 Private->Udp6ReadChild,
995 &gEfiUdp6ProtocolGuid,
996 (VOID **)&Private->Udp6Read,
997 This->DriverBindingHandle,
998 ControllerHandle,
999 EFI_OPEN_PROTOCOL_BY_DRIVER
1000 );
1001 if (EFI_ERROR (Status)) {
1002 goto ON_ERROR;
1003 }
1004
1005 //
1006 // Create Udp6 child and open Udp6 protocol for PxeBc->UdpWrite.
1007 //
1008 Status = NetLibCreateServiceChild (
1009 ControllerHandle,
1010 This->DriverBindingHandle,
1011 &gEfiUdp6ServiceBindingProtocolGuid,
1012 &Private->Udp6WriteChild
1013 );
1014 if (EFI_ERROR (Status)) {
1015 goto ON_ERROR;
1016 }
1017
1018 Status = gBS->OpenProtocol (
1019 Private->Udp6WriteChild,
1020 &gEfiUdp6ProtocolGuid,
1021 (VOID **)&Private->Udp6Write,
1022 This->DriverBindingHandle,
1023 ControllerHandle,
1024 EFI_OPEN_PROTOCOL_BY_DRIVER
1025 );
1026 if (EFI_ERROR (Status)) {
1027 goto ON_ERROR;
1028 }
1029
1030 //
1031 // Create Ip6 child and open Ip6 protocol for background ICMP6 packets.
1032 //
1033 Status = NetLibCreateServiceChild (
1034 ControllerHandle,
1035 This->DriverBindingHandle,
1036 &gEfiIp6ServiceBindingProtocolGuid,
1037 &Private->Ip6Child
1038 );
1039 if (EFI_ERROR (Status)) {
1040 goto ON_ERROR;
1041 }
1042
1043 Status = gBS->OpenProtocol (
1044 Private->Ip6Child,
1045 &gEfiIp6ProtocolGuid,
1046 (VOID **)&Private->Ip6,
1047 This->DriverBindingHandle,
1048 ControllerHandle,
1049 EFI_OPEN_PROTOCOL_BY_DRIVER
1050 );
1051 if (EFI_ERROR (Status)) {
1052 goto ON_ERROR;
1053 }
1054
1055 //
1056 // Get max packet size from Ip6 to calculate block size for Tftp later.
1057 //
1058 Status = Private->Ip6->GetModeData (Private->Ip6, &Ip6ModeData, NULL, NULL);
1059 if (EFI_ERROR (Status)) {
1060 goto ON_ERROR;
1061 }
1062
1063 Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize;
1064
1065 if (Ip6ModeData.AddressList != NULL) {
1066 FreePool (Ip6ModeData.AddressList);
1067 }
1068
1069 if (Ip6ModeData.GroupTable != NULL) {
1070 FreePool (Ip6ModeData.GroupTable);
1071 }
1072
1073 if (Ip6ModeData.RouteTable != NULL) {
1074 FreePool (Ip6ModeData.RouteTable);
1075 }
1076
1077 if (Ip6ModeData.NeighborCache != NULL) {
1078 FreePool (Ip6ModeData.NeighborCache);
1079 }
1080
1081 if (Ip6ModeData.PrefixTable != NULL) {
1082 FreePool (Ip6ModeData.PrefixTable);
1083 }
1084
1085 if (Ip6ModeData.IcmpTypeList != NULL) {
1086 FreePool (Ip6ModeData.IcmpTypeList);
1087 }
1088
1089 //
1090 // Locate Ip6->Ip6Config and store it for set IPv6 address.
1091 //
1092 Status = gBS->HandleProtocol (
1093 ControllerHandle,
1094 &gEfiIp6ConfigProtocolGuid,
1095 (VOID **)&Private->Ip6Cfg
1096 );
1097 if (EFI_ERROR (Status)) {
1098 goto ON_ERROR;
1099 }
1100
1101 //
1102 // Create a device path node for Ipv6 virtual nic, and append it.
1103 //
1104 ZeroMem (&Ip6Node, sizeof (IPv6_DEVICE_PATH));
1105 Ip6Node.Header.Type = MESSAGING_DEVICE_PATH;
1106 Ip6Node.Header.SubType = MSG_IPv6_DP;
1107 Ip6Node.PrefixLength = IP6_PREFIX_LENGTH;
1108
1109 SetDevicePathNodeLength (&Ip6Node.Header, sizeof (Ip6Node));
1110
1111 Private->Ip6Nic->DevicePath = AppendDevicePathNode (Private->DevicePath, &Ip6Node.Header);
1112
1113 if (Private->Ip6Nic->DevicePath == NULL) {
1114 Status = EFI_OUT_OF_RESOURCES;
1115 goto ON_ERROR;
1116 }
1117
1118 CopyMem (
1119 &Private->Ip6Nic->LoadFile,
1120 &gLoadFileProtocolTemplate,
1121 sizeof (EFI_LOAD_FILE_PROTOCOL)
1122 );
1123
1124 //
1125 // Create a new handle for IPv6 virtual nic,
1126 // and install PxeBaseCode, LoadFile and DevicePath protocols.
1127 //
1128 Status = gBS->InstallMultipleProtocolInterfaces (
1129 &Private->Ip6Nic->Controller,
1130 &gEfiDevicePathProtocolGuid,
1131 Private->Ip6Nic->DevicePath,
1132 &gEfiLoadFileProtocolGuid,
1133 &Private->Ip6Nic->LoadFile,
1134 &gEfiPxeBaseCodeProtocolGuid,
1135 &Private->PxeBc,
1136 NULL
1137 );
1138 if (EFI_ERROR (Status)) {
1139 goto ON_ERROR;
1140 }
1141
1142 if (Private->Snp != NULL) {
1143 //
1144 // Install SNP protocol on purpose is for some OS loader backward
1145 // compatibility consideration.
1146 //
1147 Status = gBS->InstallProtocolInterface (
1148 &Private->Ip6Nic->Controller,
1149 &gEfiSimpleNetworkProtocolGuid,
1150 EFI_NATIVE_INTERFACE,
1151 Private->Snp
1152 );
1153 if (EFI_ERROR (Status)) {
1154 goto ON_ERROR;
1155 }
1156
1157 //
1158 // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally
1159 // layering to perform the experiment.
1160 //
1161 Status = gBS->OpenProtocol (
1162 Private->Ip6Nic->Controller,
1163 &gEfiSimpleNetworkProtocolGuid,
1164 (VOID **)&Snp,
1165 This->DriverBindingHandle,
1166 Private->Ip6Nic->Controller,
1167 EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE
1168 );
1169 if (EFI_ERROR (Status)) {
1170 goto ON_ERROR;
1171 }
1172 }
1173
1174 //
1175 // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between
1176 // real NIC handle and the virtual IPv6 NIC handle.
1177 //
1178 Status = gBS->OpenProtocol (
1179 ControllerHandle,
1180 &gEfiCallerIdGuid,
1181 (VOID **)&Id,
1182 This->DriverBindingHandle,
1183 Private->Ip6Nic->Controller,
1184 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1185 );
1186 if (EFI_ERROR (Status)) {
1187 goto ON_ERROR;
1188 }
1189
1190 //
1191 // Set IPv6 available flag and set default configure data for
1192 // Udp6Read and Ip6 instance.
1193 //
1194 Status = PxeBcCheckIpv6Support (ControllerHandle, Private, &Private->Mode.Ipv6Available);
1195 if (EFI_ERROR (Status)) {
1196 //
1197 // Fail to get the data whether UNDI supports IPv6. Set default value.
1198 //
1199 Private->Mode.Ipv6Available = TRUE;
1200 }
1201
1202 if (!Private->Mode.Ipv6Available) {
1203 goto ON_ERROR;
1204 }
1205
1206 Udp6CfgData = &Private->Udp6CfgData;
1207 Ip6CfgData = &Private->Ip6CfgData;
1208
1209 Udp6CfgData->AcceptAnyPort = TRUE;
1210 Udp6CfgData->AllowDuplicatePort = TRUE;
1211 Udp6CfgData->HopLimit = PXEBC_DEFAULT_HOPLIMIT;
1212 Udp6CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
1213 Udp6CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
1214
1215 Ip6CfgData->AcceptIcmpErrors = TRUE;
1216 Ip6CfgData->DefaultProtocol = IP6_ICMP;
1217 Ip6CfgData->HopLimit = PXEBC_DEFAULT_HOPLIMIT;
1218 Ip6CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
1219 Ip6CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
1220
1221 return EFI_SUCCESS;
1222
1223ON_ERROR:
1224 PxeBcDestroyIp6Children (This, Private);
1225 return Status;
1226}
1227
1228/**
1229 The entry point for UefiPxeBc driver that installs the driver
1230 binding and component name protocol on its image.
1231
1232 @param[in] ImageHandle The Image handle of the driver.
1233 @param[in] SystemTable The system table.
1234
1235 @return EFI_SUCCESS
1236 @return Others
1237
1238**/
1239EFI_STATUS
1240EFIAPI
1241PxeBcDriverEntryPoint (
1242 IN EFI_HANDLE ImageHandle,
1243 IN EFI_SYSTEM_TABLE *SystemTable
1244 )
1245{
1246 EFI_STATUS Status;
1247
1248 if ((PcdGet8 (PcdIPv4PXESupport) == PXE_DISABLED) && (PcdGet8 (PcdIPv6PXESupport) == PXE_DISABLED)) {
1249 return EFI_UNSUPPORTED;
1250 }
1251
1252 Status = EfiLibInstallDriverBindingComponentName2 (
1253 ImageHandle,
1254 SystemTable,
1255 &gPxeBcIp4DriverBinding,
1256 ImageHandle,
1257 &gPxeBcComponentName,
1258 &gPxeBcComponentName2
1259 );
1260 if (EFI_ERROR (Status)) {
1261 return Status;
1262 }
1263
1264 Status = EfiLibInstallDriverBindingComponentName2 (
1265 ImageHandle,
1266 SystemTable,
1267 &gPxeBcIp6DriverBinding,
1268 NULL,
1269 &gPxeBcComponentName,
1270 &gPxeBcComponentName2
1271 );
1272 if (EFI_ERROR (Status)) {
1273 EfiLibUninstallDriverBindingComponentName2 (
1274 &gPxeBcIp4DriverBinding,
1275 &gPxeBcComponentName,
1276 &gPxeBcComponentName2
1277 );
1278 }
1279
1280 return Status;
1281}
1282
1283/**
1284 Test to see if this driver supports ControllerHandle. This is the worker function for
1285 PxeBcIp4(6)DriverBindingSupported.
1286
1287 @param[in] This The pointer to the driver binding protocol.
1288 @param[in] ControllerHandle The handle of device to be tested.
1289 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
1290 device to be started.
1291 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1292
1293 @retval EFI_SUCCESS This driver supports this device.
1294 @retval EFI_UNSUPPORTED This driver does not support this device.
1295
1296**/
1297EFI_STATUS
1298EFIAPI
1299PxeBcSupported (
1300 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1301 IN EFI_HANDLE ControllerHandle,
1302 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
1303 IN UINT8 IpVersion
1304 )
1305{
1306 EFI_STATUS Status;
1307 EFI_GUID *DhcpServiceBindingGuid;
1308 EFI_GUID *MtftpServiceBindingGuid;
1309
1310 if (IpVersion == IP_VERSION_4) {
1311 if (PcdGet8 (PcdIPv4PXESupport) == PXE_DISABLED) {
1312 return EFI_UNSUPPORTED;
1313 }
1314
1315 DhcpServiceBindingGuid = &gEfiDhcp4ServiceBindingProtocolGuid;
1316 MtftpServiceBindingGuid = &gEfiMtftp4ServiceBindingProtocolGuid;
1317 } else {
1318 if (PcdGet8 (PcdIPv6PXESupport) == PXE_DISABLED) {
1319 return EFI_UNSUPPORTED;
1320 }
1321
1322 DhcpServiceBindingGuid = &gEfiDhcp6ServiceBindingProtocolGuid;
1323 MtftpServiceBindingGuid = &gEfiMtftp6ServiceBindingProtocolGuid;
1324 }
1325
1326 //
1327 // Try to open the Mtftp and Dhcp protocol to test whether IP stack is ready.
1328 //
1329 Status = gBS->OpenProtocol (
1330 ControllerHandle,
1331 DhcpServiceBindingGuid,
1332 NULL,
1333 This->DriverBindingHandle,
1334 ControllerHandle,
1335 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1336 );
1337 if (!EFI_ERROR (Status)) {
1338 Status = gBS->OpenProtocol (
1339 ControllerHandle,
1340 MtftpServiceBindingGuid,
1341 NULL,
1342 This->DriverBindingHandle,
1343 ControllerHandle,
1344 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1345 );
1346 }
1347
1348 //
1349 // It's unsupported case if IP stack are not ready.
1350 //
1351 if (EFI_ERROR (Status)) {
1352 return EFI_UNSUPPORTED;
1353 }
1354
1355 return EFI_SUCCESS;
1356}
1357
1358/**
1359 Start this driver on ControllerHandle. This is the worker function for
1360 PxeBcIp4(6)DriverBindingStart.
1361
1362 @param[in] This The pointer to the driver binding protocol.
1363 @param[in] ControllerHandle The handle of device to be started.
1364 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
1365 device to be started.
1366 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1367
1368
1369 @retval EFI_SUCCESS This driver is installed to ControllerHandle.
1370 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
1371 @retval other This driver does not support this device.
1372
1373**/
1374EFI_STATUS
1375EFIAPI
1376PxeBcStart (
1377 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1378 IN EFI_HANDLE ControllerHandle,
1379 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
1380 IN UINT8 IpVersion
1381 )
1382{
1383 PXEBC_PRIVATE_DATA *Private;
1384 EFI_STATUS Status;
1385 PXEBC_PRIVATE_PROTOCOL *Id;
1386 BOOLEAN FirstStart;
1387
1388 FirstStart = FALSE;
1389 Status = gBS->OpenProtocol (
1390 ControllerHandle,
1391 &gEfiCallerIdGuid,
1392 (VOID **)&Id,
1393 This->DriverBindingHandle,
1394 ControllerHandle,
1395 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1396 );
1397 if (!EFI_ERROR (Status)) {
1398 //
1399 // Skip the initialization if the driver has been started already.
1400 //
1401 Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);
1402 } else {
1403 FirstStart = TRUE;
1404 //
1405 // If the driver has not been started yet, it should do initialization.
1406 //
1407 Private = AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));
1408 if (Private == NULL) {
1409 return EFI_OUT_OF_RESOURCES;
1410 }
1411
1412 CopyMem (
1413 &Private->PxeBc,
1414 &gPxeBcProtocolTemplate,
1415 sizeof (EFI_PXE_BASE_CODE_PROTOCOL)
1416 );
1417
1418 Private->Signature = PXEBC_PRIVATE_DATA_SIGNATURE;
1419 Private->Controller = ControllerHandle;
1420 Private->Image = This->ImageHandle;
1421 Private->PxeBc.Mode = &Private->Mode;
1422 Private->Mode.Ipv6Supported = TRUE;
1423 Private->Mode.AutoArp = TRUE;
1424 Private->Mode.TTL = DEFAULT_TTL;
1425 Private->Mode.ToS = DEFAULT_ToS;
1426
1427 //
1428 // Open device path to prepare for appending virtual NIC node.
1429 //
1430 Status = gBS->OpenProtocol (
1431 ControllerHandle,
1432 &gEfiDevicePathProtocolGuid,
1433 (VOID **)&Private->DevicePath,
1434 This->DriverBindingHandle,
1435 ControllerHandle,
1436 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1437 );
1438
1439 if (EFI_ERROR (Status)) {
1440 goto ON_ERROR;
1441 }
1442
1443 //
1444 // Get the NII interface if it exists, it's not required.
1445 //
1446 Status = gBS->OpenProtocol (
1447 ControllerHandle,
1448 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
1449 (VOID **)&Private->Nii,
1450 This->DriverBindingHandle,
1451 ControllerHandle,
1452 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1453 );
1454 if (EFI_ERROR (Status)) {
1455 Private->Nii = NULL;
1456 }
1457
1458 //
1459 // Install PxeBaseCodePrivate protocol onto the real NIC handler.
1460 // PxeBaseCodePrivate protocol is only used to keep the relationship between
1461 // NIC handle and virtual child handles.
1462 // gEfiCallerIdGuid will be used as its protocol guid.
1463 //
1464 Status = gBS->InstallProtocolInterface (
1465 &ControllerHandle,
1466 &gEfiCallerIdGuid,
1467 EFI_NATIVE_INTERFACE,
1468 &Private->Id
1469 );
1470 if (EFI_ERROR (Status)) {
1471 goto ON_ERROR;
1472 }
1473
1474 //
1475 // Try to locate SNP protocol.
1476 //
1477 NetLibGetSnpHandle (ControllerHandle, &Private->Snp);
1478 }
1479
1480 if (IpVersion == IP_VERSION_4) {
1481 //
1482 // Try to create virtual NIC handle for IPv4.
1483 //
1484 Status = PxeBcCreateIp4Children (This, ControllerHandle, Private);
1485 } else {
1486 //
1487 // Try to create virtual NIC handle for IPv6.
1488 //
1489 Status = PxeBcCreateIp6Children (This, ControllerHandle, Private);
1490 }
1491
1492 if (EFI_ERROR (Status)) {
1493 //
1494 // Failed to start PXE driver if IPv4 and IPv6 stack are both not available.
1495 //
1496 Status = EFI_DEVICE_ERROR;
1497 goto ON_ERROR;
1498 }
1499
1500 return EFI_SUCCESS;
1501
1502ON_ERROR:
1503 if (FirstStart) {
1504 gBS->UninstallProtocolInterface (
1505 ControllerHandle,
1506 &gEfiCallerIdGuid,
1507 &Private->Id
1508 );
1509 }
1510
1511 if (IpVersion == IP_VERSION_4) {
1512 PxeBcDestroyIp4Children (This, Private);
1513 } else {
1514 PxeBcDestroyIp6Children (This, Private);
1515 }
1516
1517 if (FirstStart && (Private != NULL)) {
1518 FreePool (Private);
1519 }
1520
1521 return Status;
1522}
1523
1524/**
1525 Stop this driver on ControllerHandle. This is the worker function for
1526 PxeBcIp4(6)DriverBindingStop.
1527
1528 @param[in] This Protocol instance pointer.
1529 @param[in] ControllerHandle Handle of device to stop driver on.
1530 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1531 children is zero stop the entire bus driver.
1532 @param[in] ChildHandleBuffer List of Child Handles to Stop.
1533 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1534
1535 @retval EFI_SUCCESS This driver was removed ControllerHandle.
1536 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
1537 @retval Others This driver was not removed from this device
1538
1539**/
1540EFI_STATUS
1541EFIAPI
1542PxeBcStop (
1543 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1544 IN EFI_HANDLE ControllerHandle,
1545 IN UINTN NumberOfChildren,
1546 IN EFI_HANDLE *ChildHandleBuffer,
1547 IN UINT8 IpVersion
1548 )
1549{
1550 PXEBC_PRIVATE_DATA *Private;
1551 PXEBC_VIRTUAL_NIC *VirtualNic;
1552 EFI_LOAD_FILE_PROTOCOL *LoadFile;
1553 EFI_STATUS Status;
1554 EFI_HANDLE NicHandle;
1555 PXEBC_PRIVATE_PROTOCOL *Id;
1556
1557 Private = NULL;
1558 NicHandle = NULL;
1559 VirtualNic = NULL;
1560 LoadFile = NULL;
1561 Id = NULL;
1562
1563 Status = gBS->OpenProtocol (
1564 ControllerHandle,
1565 &gEfiLoadFileProtocolGuid,
1566 (VOID **)&LoadFile,
1567 This->DriverBindingHandle,
1568 ControllerHandle,
1569 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1570 );
1571 if (EFI_ERROR (Status)) {
1572 //
1573 // Get the Nic handle by any pass-over service child handle.
1574 //
1575 if (IpVersion == IP_VERSION_4) {
1576 NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);
1577 } else {
1578 NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
1579 }
1580
1581 if (NicHandle == NULL) {
1582 return EFI_SUCCESS;
1583 }
1584
1585 //
1586 // Try to retrieve the private data by PxeBcPrivate protocol.
1587 //
1588 Status = gBS->OpenProtocol (
1589 NicHandle,
1590 &gEfiCallerIdGuid,
1591 (VOID **)&Id,
1592 This->DriverBindingHandle,
1593 ControllerHandle,
1594 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1595 );
1596 if (EFI_ERROR (Status)) {
1597 return Status;
1598 }
1599
1600 Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);
1601 } else {
1602 //
1603 // It's a virtual handle with LoadFileProtocol.
1604 //
1605 Status = gBS->OpenProtocol (
1606 ControllerHandle,
1607 &gEfiLoadFileProtocolGuid,
1608 (VOID **)&LoadFile,
1609 This->DriverBindingHandle,
1610 ControllerHandle,
1611 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1612 );
1613 if (EFI_ERROR (Status)) {
1614 return Status;
1615 }
1616
1617 VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile);
1618 Private = VirtualNic->Private;
1619 NicHandle = Private->Controller;
1620 }
1621
1622 //
1623 // Stop functionality of PXE Base Code protocol
1624 //
1625 Status = Private->PxeBc.Stop (&Private->PxeBc);
1626 if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_STARTED)) {
1627 return Status;
1628 }
1629
1630 if ((Private->Ip4Nic != NULL) && (IpVersion == IP_VERSION_4)) {
1631 PxeBcDestroyIp4Children (This, Private);
1632 }
1633
1634 if ((Private->Ip6Nic != NULL) && (IpVersion == IP_VERSION_6)) {
1635 PxeBcDestroyIp6Children (This, Private);
1636 }
1637
1638 if ((Private->Ip4Nic == NULL) && (Private->Ip6Nic == NULL)) {
1639 gBS->UninstallProtocolInterface (
1640 NicHandle,
1641 &gEfiCallerIdGuid,
1642 &Private->Id
1643 );
1644 FreePool (Private);
1645 }
1646
1647 return EFI_SUCCESS;
1648}
1649
1650/**
1651 Test to see if this driver supports ControllerHandle. This service
1652 is called by the EFI boot service ConnectController(). In
1653 order to make drivers as small as possible, there are a few calling
1654 restrictions for this service. ConnectController() must
1655 follow these calling restrictions. If any other agent wishes to call
1656 Supported() it must also follow these calling restrictions.
1657
1658 @param[in] This The pointer to the driver binding protocol.
1659 @param[in] ControllerHandle The handle of device to be tested.
1660 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
1661 device to be started.
1662
1663 @retval EFI_SUCCESS This driver supports this device.
1664 @retval EFI_UNSUPPORTED This driver does not support this device.
1665
1666**/
1667EFI_STATUS
1668EFIAPI
1669PxeBcIp4DriverBindingSupported (
1670 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1671 IN EFI_HANDLE ControllerHandle,
1672 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1673 )
1674{
1675 return PxeBcSupported (
1676 This,
1677 ControllerHandle,
1678 RemainingDevicePath,
1679 IP_VERSION_4
1680 );
1681}
1682
1683/**
1684 Start this driver on ControllerHandle. This service is called by the
1685 EFI boot service ConnectController(). In order to make
1686 drivers as small as possible, there are a few calling restrictions for
1687 this service. ConnectController() must follow these
1688 calling restrictions. If any other agent wishes to call Start() it
1689 must also follow these calling restrictions.
1690
1691 @param[in] This The pointer to the driver binding protocol.
1692 @param[in] ControllerHandle The handle of device to be started.
1693 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
1694 device to be started.
1695
1696 @retval EFI_SUCCESS This driver is installed to ControllerHandle.
1697 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
1698 @retval other This driver does not support this device.
1699
1700**/
1701EFI_STATUS
1702EFIAPI
1703PxeBcIp4DriverBindingStart (
1704 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1705 IN EFI_HANDLE ControllerHandle,
1706 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1707 )
1708{
1709 return PxeBcStart (
1710 This,
1711 ControllerHandle,
1712 RemainingDevicePath,
1713 IP_VERSION_4
1714 );
1715}
1716
1717/**
1718 Stop this driver on ControllerHandle. This service is called by the
1719 EFI boot service DisconnectController(). In order to
1720 make drivers as small as possible, there are a few calling
1721 restrictions for this service. DisconnectController()
1722 must follow these calling restrictions. If any other agent wishes
1723 to call Stop() it must also follow these calling restrictions.
1724
1725 @param[in] This Protocol instance pointer.
1726 @param[in] ControllerHandle Handle of device to stop driver on
1727 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1728 children is zero stop the entire bus driver.
1729 @param[in] ChildHandleBuffer List of Child Handles to Stop.
1730
1731 @retval EFI_SUCCESS This driver is removed ControllerHandle
1732 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
1733 @retval Others This driver was not removed from this device.
1734
1735**/
1736EFI_STATUS
1737EFIAPI
1738PxeBcIp4DriverBindingStop (
1739 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1740 IN EFI_HANDLE ControllerHandle,
1741 IN UINTN NumberOfChildren,
1742 IN EFI_HANDLE *ChildHandleBuffer
1743 )
1744{
1745 return PxeBcStop (
1746 This,
1747 ControllerHandle,
1748 NumberOfChildren,
1749 ChildHandleBuffer,
1750 IP_VERSION_4
1751 );
1752}
1753
1754/**
1755 Test to see if this driver supports ControllerHandle. This service
1756 is called by the EFI boot service ConnectController(). In
1757 order to make drivers as small as possible, there are a few calling
1758 restrictions for this service. ConnectController() must
1759 follow these calling restrictions. If any other agent wishes to call
1760 Supported() it must also follow these calling restrictions.
1761
1762 @param[in] This The pointer to the driver binding protocol.
1763 @param[in] ControllerHandle The handle of device to be tested.
1764 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
1765 device to be started.
1766
1767 @retval EFI_SUCCESS This driver supports this device.
1768 @retval EFI_UNSUPPORTED This driver does not support this device.
1769
1770**/
1771EFI_STATUS
1772EFIAPI
1773PxeBcIp6DriverBindingSupported (
1774 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1775 IN EFI_HANDLE ControllerHandle,
1776 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1777 )
1778{
1779 return PxeBcSupported (
1780 This,
1781 ControllerHandle,
1782 RemainingDevicePath,
1783 IP_VERSION_6
1784 );
1785}
1786
1787/**
1788 Start this driver on ControllerHandle. This service is called by the
1789 EFI boot service ConnectController(). In order to make
1790 drivers as small as possible, there are a few calling restrictions for
1791 this service. ConnectController() must follow these
1792 calling restrictions. If any other agent wishes to call Start() it
1793 must also follow these calling restrictions.
1794
1795 @param[in] This The pointer to the driver binding protocol.
1796 @param[in] ControllerHandle The handle of device to be started.
1797 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
1798 device to be started.
1799
1800 @retval EFI_SUCCESS This driver is installed to ControllerHandle.
1801 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
1802 @retval other This driver does not support this device.
1803
1804**/
1805EFI_STATUS
1806EFIAPI
1807PxeBcIp6DriverBindingStart (
1808 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1809 IN EFI_HANDLE ControllerHandle,
1810 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1811 )
1812{
1813 return PxeBcStart (
1814 This,
1815 ControllerHandle,
1816 RemainingDevicePath,
1817 IP_VERSION_6
1818 );
1819}
1820
1821/**
1822 Stop this driver on ControllerHandle. This service is called by the
1823 EFI boot service DisconnectController(). In order to
1824 make drivers as small as possible, there are a few calling
1825 restrictions for this service. DisconnectController()
1826 must follow these calling restrictions. If any other agent wishes
1827 to call Stop() it must also follow these calling restrictions.
1828
1829 @param[in] This Protocol instance pointer.
1830 @param[in] ControllerHandle Handle of device to stop driver on
1831 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1832 children is zero stop the entire bus driver.
1833 @param[in] ChildHandleBuffer List of Child Handles to Stop.
1834
1835 @retval EFI_SUCCESS This driver is removed ControllerHandle
1836 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
1837 @retval Others This driver was not removed from this device.
1838
1839**/
1840EFI_STATUS
1841EFIAPI
1842PxeBcIp6DriverBindingStop (
1843 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1844 IN EFI_HANDLE ControllerHandle,
1845 IN UINTN NumberOfChildren,
1846 IN EFI_HANDLE *ChildHandleBuffer
1847 )
1848{
1849 return PxeBcStop (
1850 This,
1851 ControllerHandle,
1852 NumberOfChildren,
1853 ChildHandleBuffer,
1854 IP_VERSION_6
1855 );
1856}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette