2 Driver Binding functions implementationfor for UefiPxeBc Driver.
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PxeBcImpl.h"
19 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding
= {
20 PxeBcDriverBindingSupported
,
21 PxeBcDriverBindingStart
,
22 PxeBcDriverBindingStop
,
30 Get the Nic handle using any child handle in the IPv4 stack.
32 @param[in] ControllerHandle Pointer to child handle over IPv4.
34 @return NicHandle The pointer to the Nic handle.
38 PxeBcGetNicByIp4Children (
39 IN EFI_HANDLE ControllerHandle
44 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiArpProtocolGuid
);
45 if (NicHandle
== NULL
) {
46 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
47 if (NicHandle
== NULL
) {
48 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
49 if (NicHandle
== NULL
) {
50 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
51 if (NicHandle
== NULL
) {
52 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiMtftp4ProtocolGuid
);
53 if (NicHandle
== NULL
) {
66 Get the Nic handle using any child handle in the IPv6 stack.
68 @param[in] ControllerHandle Pointer to child handle over IPv6.
70 @return NicHandle The pointer to the Nic handle.
74 PxeBcGetNicByIp6Children (
75 IN EFI_HANDLE ControllerHandle
80 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp6ProtocolGuid
);
81 if (NicHandle
== NULL
) {
82 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp6ProtocolGuid
);
83 if (NicHandle
== NULL
) {
84 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp6ProtocolGuid
);
85 if (NicHandle
== NULL
) {
86 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiMtftp6ProtocolGuid
);
87 if (NicHandle
== NULL
) {
99 Destroy the opened instances based on IPv4.
101 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
102 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.
106 PxeBcDestroyIp4Children (
107 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
108 IN PXEBC_PRIVATE_DATA
*Private
111 ASSERT(Private
!= NULL
);
113 if (Private
->ArpChild
!= NULL
) {
115 // Close Arp for PxeBc->Arp and destroy the instance.
119 &gEfiArpProtocolGuid
,
120 This
->DriverBindingHandle
,
124 NetLibDestroyServiceChild (
126 This
->DriverBindingHandle
,
127 &gEfiArpServiceBindingProtocolGuid
,
132 if (Private
->Ip4Child
!= NULL
) {
134 // Close Ip4 for background ICMP error message and destroy the instance.
138 &gEfiIp4ProtocolGuid
,
139 This
->DriverBindingHandle
,
143 NetLibDestroyServiceChild (
145 This
->DriverBindingHandle
,
146 &gEfiIp4ServiceBindingProtocolGuid
,
151 if (Private
->Udp4WriteChild
!= NULL
) {
153 // Close Udp4 for PxeBc->UdpWrite and destroy the instance.
156 Private
->Udp4WriteChild
,
157 &gEfiUdp4ProtocolGuid
,
158 This
->DriverBindingHandle
,
162 NetLibDestroyServiceChild (
164 This
->DriverBindingHandle
,
165 &gEfiUdp4ServiceBindingProtocolGuid
,
166 Private
->Udp4WriteChild
170 if (Private
->Udp4ReadChild
!= NULL
) {
172 // Close Udp4 for PxeBc->UdpRead and destroy the instance.
175 Private
->Udp4ReadChild
,
176 &gEfiUdp4ProtocolGuid
,
177 This
->DriverBindingHandle
,
181 NetLibDestroyServiceChild (
183 This
->DriverBindingHandle
,
184 &gEfiUdp4ServiceBindingProtocolGuid
,
185 Private
->Udp4ReadChild
189 if (Private
->Mtftp4Child
!= NULL
) {
191 // Close Mtftp4 for PxeBc->Mtftp4 and destroy the instance.
194 Private
->Mtftp4Child
,
195 &gEfiMtftp4ProtocolGuid
,
196 This
->DriverBindingHandle
,
200 NetLibDestroyServiceChild (
202 This
->DriverBindingHandle
,
203 &gEfiMtftp4ServiceBindingProtocolGuid
,
208 if (Private
->Dhcp4Child
!= NULL
) {
210 // Close Dhcp4 for PxeBc->Dhcp4 and destroy the instance.
214 &gEfiDhcp4ProtocolGuid
,
215 This
->DriverBindingHandle
,
219 NetLibDestroyServiceChild (
221 This
->DriverBindingHandle
,
222 &gEfiDhcp4ServiceBindingProtocolGuid
,
227 if (Private
->Ip4Nic
!= NULL
) {
229 // Close PxeBc from the parent Nic handle and destroy the virtual handle.
233 &gEfiPxeBaseCodeProtocolGuid
,
234 This
->DriverBindingHandle
,
235 Private
->Ip4Nic
->Controller
238 gBS
->UninstallMultipleProtocolInterfaces (
239 Private
->Ip4Nic
->Controller
,
240 &gEfiDevicePathProtocolGuid
,
241 Private
->Ip4Nic
->DevicePath
,
242 &gEfiLoadFileProtocolGuid
,
243 &Private
->Ip4Nic
->LoadFile
,
246 FreePool (Private
->Ip4Nic
);
249 Private
->ArpChild
= NULL
;
250 Private
->Ip4Child
= NULL
;
251 Private
->Udp4WriteChild
= NULL
;
252 Private
->Udp4ReadChild
= NULL
;
253 Private
->Mtftp4Child
= NULL
;
254 Private
->Dhcp4Child
= NULL
;
255 Private
->Ip4Nic
= NULL
;
260 Destroy the opened instances based on IPv6.
262 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
263 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.
267 PxeBcDestroyIp6Children (
268 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
269 IN PXEBC_PRIVATE_DATA
*Private
272 ASSERT(Private
!= NULL
);
274 if (Private
->Ip6Child
!= NULL
) {
276 // Close Ip6 for Ip6->Ip6Config and destroy the instance.
280 &gEfiIp6ProtocolGuid
,
281 This
->DriverBindingHandle
,
285 NetLibDestroyServiceChild (
287 This
->DriverBindingHandle
,
288 &gEfiIp6ServiceBindingProtocolGuid
,
293 if (Private
->Udp6WriteChild
!= NULL
) {
295 // Close Udp6 for PxeBc->UdpWrite and destroy the instance.
298 Private
->Udp6WriteChild
,
299 &gEfiUdp6ProtocolGuid
,
300 This
->DriverBindingHandle
,
303 NetLibDestroyServiceChild (
305 This
->DriverBindingHandle
,
306 &gEfiUdp6ServiceBindingProtocolGuid
,
307 Private
->Udp6WriteChild
311 if (Private
->Udp6ReadChild
!= NULL
) {
313 // Close Udp6 for PxeBc->UdpRead and destroy the instance.
316 Private
->Udp6ReadChild
,
317 &gEfiUdp6ProtocolGuid
,
318 This
->DriverBindingHandle
,
321 NetLibDestroyServiceChild (
323 This
->DriverBindingHandle
,
324 &gEfiUdp6ServiceBindingProtocolGuid
,
325 Private
->Udp6ReadChild
329 if (Private
->Mtftp6Child
!= NULL
) {
331 // Close Mtftp6 for PxeBc->Mtftp and destroy the instance.
334 Private
->Mtftp6Child
,
335 &gEfiMtftp6ProtocolGuid
,
336 This
->DriverBindingHandle
,
340 NetLibDestroyServiceChild (
342 This
->DriverBindingHandle
,
343 &gEfiMtftp6ServiceBindingProtocolGuid
,
348 if (Private
->Dhcp6Child
!= NULL
) {
350 // Close Dhcp6 for PxeBc->Dhcp and destroy the instance.
354 &gEfiDhcp6ProtocolGuid
,
355 This
->DriverBindingHandle
,
359 NetLibDestroyServiceChild (
361 This
->DriverBindingHandle
,
362 &gEfiDhcp6ServiceBindingProtocolGuid
,
367 if (Private
->Ip6Nic
!= NULL
) {
369 // Close PxeBc from the parent Nic handle and destroy the virtual handle.
373 &gEfiPxeBaseCodeProtocolGuid
,
374 This
->DriverBindingHandle
,
375 Private
->Ip6Nic
->Controller
377 gBS
->UninstallMultipleProtocolInterfaces (
378 Private
->Ip6Nic
->Controller
,
379 &gEfiDevicePathProtocolGuid
,
380 Private
->Ip6Nic
->DevicePath
,
381 &gEfiLoadFileProtocolGuid
,
382 &Private
->Ip6Nic
->LoadFile
,
385 FreePool (Private
->Ip6Nic
);
388 Private
->Ip6Child
= NULL
;
389 Private
->Udp6WriteChild
= NULL
;
390 Private
->Udp6ReadChild
= NULL
;
391 Private
->Mtftp6Child
= NULL
;
392 Private
->Dhcp6Child
= NULL
;
393 Private
->Ip6Nic
= NULL
;
394 Private
->Mode
.Ipv6Available
= FALSE
;
399 Create the opened instances based on IPv4.
401 @param[in] This Pointer to EFI_DRIVER_BINDING_PROTOCOL.
402 @param[in] ControllerHandle Handle of the child to destroy.
403 @param[in] Private Handle Pointer to PXEBC_PRIVATE_DATA.
405 @retval EFI_SUCCESS The instances based on IPv4 were all created successfully.
406 @retval Others An unexpected error occurred.
410 PxeBcCreateIp4Children (
411 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
412 IN EFI_HANDLE ControllerHandle
,
413 IN PXEBC_PRIVATE_DATA
*Private
417 IPv4_DEVICE_PATH Ip4Node
;
418 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
419 EFI_PXE_BASE_CODE_MODE
*Mode
;
420 EFI_UDP4_CONFIG_DATA
*Udp4CfgData
;
421 EFI_IP4_CONFIG_DATA
*Ip4CfgData
;
422 EFI_IP4_MODE_DATA Ip4ModeData
;
424 if (Private
->Ip4Nic
!= NULL
) {
426 // Already created before.
432 // Create Dhcp4 child and open Dhcp4 protocol for PxeBc->Dhcp.
434 Status
= NetLibCreateServiceChild (
436 This
->DriverBindingHandle
,
437 &gEfiDhcp4ServiceBindingProtocolGuid
,
440 if (EFI_ERROR (Status
)) {
444 Status
= gBS
->OpenProtocol (
446 &gEfiDhcp4ProtocolGuid
,
447 (VOID
**) &Private
->Dhcp4
,
448 This
->DriverBindingHandle
,
450 EFI_OPEN_PROTOCOL_BY_DRIVER
452 if (EFI_ERROR (Status
)) {
457 // Create Mtftp4 child and open Mtftp4 protocol for PxeBc->Mtftp.
459 Status
= NetLibCreateServiceChild (
461 This
->DriverBindingHandle
,
462 &gEfiMtftp4ServiceBindingProtocolGuid
,
463 &Private
->Mtftp4Child
465 if (EFI_ERROR (Status
)) {
469 Status
= gBS
->OpenProtocol (
470 Private
->Mtftp4Child
,
471 &gEfiMtftp4ProtocolGuid
,
472 (VOID
**) &Private
->Mtftp4
,
473 This
->DriverBindingHandle
,
475 EFI_OPEN_PROTOCOL_BY_DRIVER
477 if (EFI_ERROR (Status
)) {
482 // Create Udp4 child and open Udp4 protocol for PxeBc->UdpRead.
484 Status
= NetLibCreateServiceChild (
486 This
->DriverBindingHandle
,
487 &gEfiUdp4ServiceBindingProtocolGuid
,
488 &Private
->Udp4ReadChild
490 if (EFI_ERROR (Status
)) {
494 Status
= gBS
->OpenProtocol (
495 Private
->Udp4ReadChild
,
496 &gEfiUdp4ProtocolGuid
,
497 (VOID
**) &Private
->Udp4Read
,
498 This
->DriverBindingHandle
,
500 EFI_OPEN_PROTOCOL_BY_DRIVER
502 if (EFI_ERROR (Status
)) {
507 // Create Udp4 child and open Udp4 protocol for PxeBc->UdpWrite.
509 Status
= NetLibCreateServiceChild (
511 This
->DriverBindingHandle
,
512 &gEfiUdp4ServiceBindingProtocolGuid
,
513 &Private
->Udp4WriteChild
515 if (EFI_ERROR (Status
)) {
519 Status
= gBS
->OpenProtocol (
520 Private
->Udp4WriteChild
,
521 &gEfiUdp4ProtocolGuid
,
522 (VOID
**) &Private
->Udp4Write
,
523 This
->DriverBindingHandle
,
525 EFI_OPEN_PROTOCOL_BY_DRIVER
527 if (EFI_ERROR (Status
)) {
532 // Create Arp child and open Arp protocol for PxeBc->Arp.
534 Status
= NetLibCreateServiceChild (
536 This
->DriverBindingHandle
,
537 &gEfiArpServiceBindingProtocolGuid
,
540 if (EFI_ERROR (Status
)) {
544 Status
= gBS
->OpenProtocol (
546 &gEfiArpProtocolGuid
,
547 (VOID
**) &Private
->Arp
,
548 This
->DriverBindingHandle
,
550 EFI_OPEN_PROTOCOL_BY_DRIVER
552 if (EFI_ERROR (Status
)) {
557 // Create Ip4 child and open Ip4 protocol for background ICMP packets.
559 Status
= NetLibCreateServiceChild (
561 This
->DriverBindingHandle
,
562 &gEfiIp4ServiceBindingProtocolGuid
,
565 if (EFI_ERROR (Status
)) {
569 Status
= gBS
->OpenProtocol (
571 &gEfiIp4ProtocolGuid
,
572 (VOID
**) &Private
->Ip4
,
573 This
->DriverBindingHandle
,
575 EFI_OPEN_PROTOCOL_BY_DRIVER
577 if (EFI_ERROR (Status
)) {
582 // Get max packet size from Ip4 to calculate block size for Tftp later.
584 Status
= Private
->Ip4
->GetModeData (Private
->Ip4
, &Ip4ModeData
, NULL
, NULL
);
585 if (EFI_ERROR (Status
)) {
589 Private
->Ip4MaxPacketSize
= Ip4ModeData
.MaxPacketSize
;
591 Private
->Ip4Nic
= AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC
));
592 if (Private
->Ip4Nic
== NULL
) {
593 return EFI_OUT_OF_RESOURCES
;
596 Private
->Ip4Nic
->Private
= Private
;
597 Private
->Ip4Nic
->Signature
= PXEBC_VIRTUAL_NIC_SIGNATURE
;
600 // Create a device path node for Ipv4 virtual nic, and append it.
602 ZeroMem (&Ip4Node
, sizeof (IPv4_DEVICE_PATH
));
603 Ip4Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
604 Ip4Node
.Header
.SubType
= MSG_IPv4_DP
;
605 Ip4Node
.StaticIpAddress
= FALSE
;
607 SetDevicePathNodeLength (&Ip4Node
.Header
, sizeof (Ip4Node
));
609 Private
->Ip4Nic
->DevicePath
= AppendDevicePathNode (Private
->DevicePath
, &Ip4Node
.Header
);
611 if (Private
->Ip4Nic
->DevicePath
== NULL
) {
612 Status
= EFI_OUT_OF_RESOURCES
;
617 &Private
->Ip4Nic
->LoadFile
,
618 &gLoadFileProtocolTemplate
,
619 sizeof (EFI_LOAD_FILE_PROTOCOL
)
623 // Create a new handle for IPv4 virtual nic,
624 // and install PxeBaseCode, LoadFile and DevicePath protocols.
626 Status
= gBS
->InstallMultipleProtocolInterfaces (
627 &Private
->Ip4Nic
->Controller
,
628 &gEfiDevicePathProtocolGuid
,
629 Private
->Ip4Nic
->DevicePath
,
630 &gEfiLoadFileProtocolGuid
,
631 &Private
->Ip4Nic
->LoadFile
,
634 if (EFI_ERROR (Status
)) {
639 // Open PxeBaseCode protocol by child to setup a parent-child relationship between
640 // real NIC handle and the virtual IPv4 NIC handle.
642 Status
= gBS
->OpenProtocol (
644 &gEfiPxeBaseCodeProtocolGuid
,
646 This
->DriverBindingHandle
,
647 Private
->Ip4Nic
->Controller
,
648 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
650 if (EFI_ERROR (Status
)) {
655 // Set default configure data for Udp4Read and Ip4 instance.
658 Udp4CfgData
= &Private
->Udp4CfgData
;
659 Ip4CfgData
= &Private
->Ip4CfgData
;
661 Udp4CfgData
->AcceptBroadcast
= TRUE
;
662 Udp4CfgData
->AcceptAnyPort
= TRUE
;
663 Udp4CfgData
->AllowDuplicatePort
= TRUE
;
664 Udp4CfgData
->TypeOfService
= Mode
->ToS
;
665 Udp4CfgData
->TimeToLive
= Mode
->TTL
;
666 Udp4CfgData
->ReceiveTimeout
= PXEBC_DEFAULT_LIFETIME
;
667 Udp4CfgData
->TransmitTimeout
= PXEBC_DEFAULT_LIFETIME
;
669 Ip4CfgData
->AcceptIcmpErrors
= TRUE
;
670 Ip4CfgData
->DefaultProtocol
= EFI_IP_PROTO_ICMP
;
671 Ip4CfgData
->TypeOfService
= Mode
->ToS
;
672 Ip4CfgData
->TimeToLive
= Mode
->TTL
;
673 Ip4CfgData
->ReceiveTimeout
= PXEBC_DEFAULT_LIFETIME
;
674 Ip4CfgData
->TransmitTimeout
= PXEBC_DEFAULT_LIFETIME
;
679 PxeBcDestroyIp4Children (This
, Private
);
685 Create the opened instances based on IPv6.
687 @param[in] This Pointer to EFI_DRIVER_BINDING_PROTOCOL.
688 @param[in] ControllerHandle Handle of the child to destroy.
689 @param[in] Private Handle Pointer to PXEBC_PRIVATE_DATA.
691 @retval EFI_SUCCESS The instances based on IPv6 were all created successfully.
692 @retval Others An unexpected error occurred.
696 PxeBcCreateIp6Children (
697 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
698 IN EFI_HANDLE ControllerHandle
,
699 IN PXEBC_PRIVATE_DATA
*Private
703 IPv6_DEVICE_PATH Ip6Node
;
704 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
705 EFI_UDP6_CONFIG_DATA
*Udp6CfgData
;
706 EFI_IP6_CONFIG_DATA
*Ip6CfgData
;
707 EFI_IP6_MODE_DATA Ip6ModeData
;
709 if (Private
->Ip6Nic
!= NULL
) {
711 // Already created before.
716 Private
->Ip6Nic
= AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC
));
718 if (Private
->Ip6Nic
== NULL
) {
719 return EFI_OUT_OF_RESOURCES
;
722 Private
->Ip6Nic
->Private
= Private
;
723 Private
->Ip6Nic
->Signature
= PXEBC_VIRTUAL_NIC_SIGNATURE
;
726 // Create Dhcp6 child and open Dhcp6 protocol for PxeBc->Dhcp.
728 Status
= NetLibCreateServiceChild (
730 This
->DriverBindingHandle
,
731 &gEfiDhcp6ServiceBindingProtocolGuid
,
734 if (EFI_ERROR (Status
)) {
738 Status
= gBS
->OpenProtocol (
740 &gEfiDhcp6ProtocolGuid
,
741 (VOID
**) &Private
->Dhcp6
,
742 This
->DriverBindingHandle
,
744 EFI_OPEN_PROTOCOL_BY_DRIVER
746 if (EFI_ERROR (Status
)) {
751 // Create Mtftp6 child and open Mtftp6 protocol for PxeBc->Mtftp.
753 Status
= NetLibCreateServiceChild (
755 This
->DriverBindingHandle
,
756 &gEfiMtftp6ServiceBindingProtocolGuid
,
757 &Private
->Mtftp6Child
759 if (EFI_ERROR (Status
)) {
763 Status
= gBS
->OpenProtocol (
764 Private
->Mtftp6Child
,
765 &gEfiMtftp6ProtocolGuid
,
766 (VOID
**) &Private
->Mtftp6
,
767 This
->DriverBindingHandle
,
769 EFI_OPEN_PROTOCOL_BY_DRIVER
771 if (EFI_ERROR (Status
)) {
776 // Create Udp6 child and open Udp6 protocol for PxeBc->UdpRead.
778 Status
= NetLibCreateServiceChild (
780 This
->DriverBindingHandle
,
781 &gEfiUdp6ServiceBindingProtocolGuid
,
782 &Private
->Udp6ReadChild
784 if (EFI_ERROR (Status
)) {
788 Status
= gBS
->OpenProtocol (
789 Private
->Udp6ReadChild
,
790 &gEfiUdp6ProtocolGuid
,
791 (VOID
**) &Private
->Udp6Read
,
792 This
->DriverBindingHandle
,
794 EFI_OPEN_PROTOCOL_BY_DRIVER
796 if (EFI_ERROR (Status
)) {
801 // Create Udp6 child and open Udp6 protocol for PxeBc->UdpWrite.
803 Status
= NetLibCreateServiceChild (
805 This
->DriverBindingHandle
,
806 &gEfiUdp6ServiceBindingProtocolGuid
,
807 &Private
->Udp6WriteChild
809 if (EFI_ERROR (Status
)) {
813 Status
= gBS
->OpenProtocol (
814 Private
->Udp6WriteChild
,
815 &gEfiUdp6ProtocolGuid
,
816 (VOID
**) &Private
->Udp6Write
,
817 This
->DriverBindingHandle
,
819 EFI_OPEN_PROTOCOL_BY_DRIVER
821 if (EFI_ERROR (Status
)) {
826 // Create Ip6 child and open Ip6 protocol for background ICMP6 packets.
828 Status
= NetLibCreateServiceChild (
830 This
->DriverBindingHandle
,
831 &gEfiIp6ServiceBindingProtocolGuid
,
834 if (EFI_ERROR (Status
)) {
838 Status
= gBS
->OpenProtocol (
840 &gEfiIp6ProtocolGuid
,
841 (VOID
**) &Private
->Ip6
,
842 This
->DriverBindingHandle
,
844 EFI_OPEN_PROTOCOL_BY_DRIVER
846 if (EFI_ERROR (Status
)) {
851 // Get max packet size from Ip6 to calculate block size for Tftp later.
853 Status
= Private
->Ip6
->GetModeData (Private
->Ip6
, &Ip6ModeData
, NULL
, NULL
);
854 if (EFI_ERROR (Status
)) {
858 Private
->Ip6MaxPacketSize
= Ip6ModeData
.MaxPacketSize
;
861 // Locate Ip6->Ip6Config and store it for set IPv6 address.
863 Status
= gBS
->HandleProtocol (
865 &gEfiIp6ConfigProtocolGuid
,
866 (VOID
**) &Private
->Ip6Cfg
868 if (EFI_ERROR (Status
)) {
873 // Create a device path node for Ipv6 virtual nic, and append it.
875 ZeroMem (&Ip6Node
, sizeof (IPv6_DEVICE_PATH
));
876 Ip6Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
877 Ip6Node
.Header
.SubType
= MSG_IPv6_DP
;
878 Ip6Node
.StaticIpAddress
= FALSE
;
880 SetDevicePathNodeLength (&Ip6Node
.Header
, sizeof (Ip6Node
));
882 Private
->Ip6Nic
->DevicePath
= AppendDevicePathNode (Private
->DevicePath
, &Ip6Node
.Header
);
884 if (Private
->Ip6Nic
->DevicePath
== NULL
) {
885 Status
= EFI_OUT_OF_RESOURCES
;
890 &Private
->Ip6Nic
->LoadFile
,
891 &gLoadFileProtocolTemplate
,
892 sizeof (EFI_LOAD_FILE_PROTOCOL
)
896 // Create a new handle for IPv6 virtual nic,
897 // and install PxeBaseCode, LoadFile and DevicePath protocols.
899 Status
= gBS
->InstallMultipleProtocolInterfaces (
900 &Private
->Ip6Nic
->Controller
,
901 &gEfiDevicePathProtocolGuid
,
902 Private
->Ip6Nic
->DevicePath
,
903 &gEfiLoadFileProtocolGuid
,
904 &Private
->Ip6Nic
->LoadFile
,
907 if (EFI_ERROR (Status
)) {
912 // Open PxeBaseCode protocol by child to setup a parent-child relationship between
913 // real NIC handle and the virtual IPv6 NIC handle.
915 Status
= gBS
->OpenProtocol (
917 &gEfiPxeBaseCodeProtocolGuid
,
919 This
->DriverBindingHandle
,
920 Private
->Ip6Nic
->Controller
,
921 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
923 if (EFI_ERROR (Status
)) {
928 // Set IPv6 avaiable flag and set default configure data for
929 // Udp6Read and Ip6 instance.
931 Private
->Mode
.Ipv6Available
= TRUE
;
932 Udp6CfgData
= &Private
->Udp6CfgData
;
933 Ip6CfgData
= &Private
->Ip6CfgData
;
935 Udp6CfgData
->AcceptAnyPort
= TRUE
;
936 Udp6CfgData
->AllowDuplicatePort
= TRUE
;
937 Udp6CfgData
->HopLimit
= PXEBC_DEFAULT_HOPLIMIT
;
938 Udp6CfgData
->ReceiveTimeout
= PXEBC_DEFAULT_LIFETIME
;
939 Udp6CfgData
->TransmitTimeout
= PXEBC_DEFAULT_LIFETIME
;
941 Ip6CfgData
->AcceptIcmpErrors
= TRUE
;
942 Ip6CfgData
->DefaultProtocol
= IP6_ICMP
;
943 Ip6CfgData
->HopLimit
= PXEBC_DEFAULT_HOPLIMIT
;
944 Ip6CfgData
->ReceiveTimeout
= PXEBC_DEFAULT_LIFETIME
;
945 Ip6CfgData
->TransmitTimeout
= PXEBC_DEFAULT_LIFETIME
;
950 PxeBcDestroyIp6Children (This
, Private
);
956 The entry point for UefiPxeBc driver that installs the driver
957 binding and component name protocol on its image.
959 @param[in] ImageHandle The Image handle of the driver.
960 @param[in] SystemTable The system table.
968 PxeBcDriverEntryPoint (
969 IN EFI_HANDLE ImageHandle
,
970 IN EFI_SYSTEM_TABLE
*SystemTable
973 return EfiLibInstallDriverBindingComponentName2 (
976 &gPxeBcDriverBinding
,
978 &gPxeBcComponentName
,
979 &gPxeBcComponentName2
985 Test to see if this driver supports ControllerHandle. This service
986 is called by the EFI boot service ConnectController(). In
987 order to make drivers as small as possible, there are a few calling
988 restrictions for this service. ConnectController() must
989 follow these calling restrictions. If any other agent wishes to call
990 Supported() it must also follow these calling restrictions.
992 @param[in] This The pointer to the driver binding protocol.
993 @param[in] ControllerHandle The handle of device to be tested.
994 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
995 device to be started.
997 @retval EFI_SUCCESS This driver supports this device.
998 @retval EFI_UNSUPPORTED This driver does not support this device.
1003 PxeBcDriverBindingSupported (
1004 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1005 IN EFI_HANDLE ControllerHandle
,
1006 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
1009 EFI_STATUS Ip4Status
;
1010 EFI_STATUS Ip6Status
;
1013 // Try to open the Mtftp4 and Dhcp4 protocol to test whether IPv4 stack is ready.
1015 Ip4Status
= gBS
->OpenProtocol (
1017 &gEfiDhcp4ServiceBindingProtocolGuid
,
1019 This
->DriverBindingHandle
,
1021 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1023 if (!EFI_ERROR (Ip4Status
)) {
1024 Ip4Status
= gBS
->OpenProtocol (
1026 &gEfiMtftp4ServiceBindingProtocolGuid
,
1028 This
->DriverBindingHandle
,
1030 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1035 // Try to open the Mtftp6 and Dhcp6 protocol to test whether IPv4 stack is ready.
1037 Ip6Status
= gBS
->OpenProtocol (
1039 &gEfiDhcp6ServiceBindingProtocolGuid
,
1041 This
->DriverBindingHandle
,
1043 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1045 if (!EFI_ERROR (Ip6Status
)) {
1046 Ip6Status
= gBS
->OpenProtocol (
1048 &gEfiMtftp6ServiceBindingProtocolGuid
,
1050 This
->DriverBindingHandle
,
1052 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1057 // It's unsupported case if both stack are not ready.
1059 if (EFI_ERROR (Ip4Status
) && EFI_ERROR (Ip6Status
)) {
1060 return EFI_UNSUPPORTED
;
1068 Start this driver on ControllerHandle. This service is called by the
1069 EFI boot service ConnectController(). In order to make
1070 drivers as small as possible, there are a few calling restrictions for
1071 this service. ConnectController() must follow these
1072 calling restrictions. If any other agent wishes to call Start() it
1073 must also follow these calling restrictions.
1075 @param[in] This The pointer to the driver binding protocol.
1076 @param[in] ControllerHandle The handle of device to be started.
1077 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
1078 device to be started.
1080 @retval EFI_SUCCESS This driver is installed to ControllerHandle.
1081 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
1082 @retval other This driver does not support this device.
1087 PxeBcDriverBindingStart (
1088 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1089 IN EFI_HANDLE ControllerHandle
,
1090 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
1093 PXEBC_PRIVATE_DATA
*Private
;
1094 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
1096 EFI_STATUS Ip4Status
;
1097 EFI_STATUS Ip6Status
;
1099 Status
= gBS
->OpenProtocol (
1101 &gEfiPxeBaseCodeProtocolGuid
,
1103 This
->DriverBindingHandle
,
1105 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1107 if (!EFI_ERROR (Status
)) {
1109 // Skip the initialization if the driver has been started already.
1111 Private
= PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc
);
1114 // If the driver has not been started yet, it should do initialization.
1116 Private
= AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA
));
1117 if (Private
== NULL
) {
1118 return EFI_OUT_OF_RESOURCES
;
1123 &gPxeBcProtocolTemplate
,
1124 sizeof (EFI_PXE_BASE_CODE_PROTOCOL
)
1127 Private
->Signature
= PXEBC_PRIVATE_DATA_SIGNATURE
;
1128 Private
->Controller
= ControllerHandle
;
1129 Private
->Image
= This
->ImageHandle
;
1130 Private
->PxeBc
.Mode
= &Private
->Mode
;
1131 Private
->Mode
.Ipv6Supported
= TRUE
;
1132 Private
->Mode
.AutoArp
= TRUE
;
1133 Private
->Mode
.TTL
= DEFAULT_TTL
;
1134 Private
->Mode
.ToS
= DEFAULT_ToS
;
1137 // Open device path to prepare for appending virtual NIC node.
1139 Status
= gBS
->OpenProtocol (
1141 &gEfiDevicePathProtocolGuid
,
1142 (VOID
**) &Private
->DevicePath
,
1143 This
->DriverBindingHandle
,
1145 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1148 if (EFI_ERROR (Status
)) {
1153 // Get the NII interface if it exists, it's not required.
1155 Status
= gBS
->OpenProtocol (
1157 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1158 (VOID
**) &Private
->Nii
,
1159 This
->DriverBindingHandle
,
1161 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1163 if (EFI_ERROR (Status
)) {
1164 Private
->Nii
= NULL
;
1168 // Install PxeBaseCode protocol onto the real NIC handler.
1170 Status
= gBS
->InstallProtocolInterface (
1172 &gEfiPxeBaseCodeProtocolGuid
,
1173 EFI_NATIVE_INTERFACE
,
1176 if (EFI_ERROR (Status
)) {
1182 // Try to create virtual NIC handle for IPv4.
1184 Ip4Status
= PxeBcCreateIp4Children (This
, ControllerHandle
, Private
);
1187 // Try to create virtual NIC handle for IPv6.
1189 Ip6Status
= PxeBcCreateIp6Children (This
, ControllerHandle
, Private
);
1191 if (EFI_ERROR (Ip4Status
) && EFI_ERROR (Ip6Status
)) {
1193 // Failed to start PXE driver if IPv4 and IPv6 stack are both not available.
1195 Status
= EFI_DEVICE_ERROR
;
1202 gBS
->UninstallProtocolInterface (
1204 &gEfiPxeBaseCodeProtocolGuid
,
1207 PxeBcDestroyIp4Children (This
, Private
);
1208 PxeBcDestroyIp6Children (This
, Private
);
1216 Stop this driver on ControllerHandle. This service is called by the
1217 EFI boot service DisconnectController(). In order to
1218 make drivers as small as possible, there are a few calling
1219 restrictions for this service. DisconnectController()
1220 must follow these calling restrictions. If any other agent wishes
1221 to call Stop() it must also follow these calling restrictions.
1223 @param[in] This Protocol instance pointer.
1224 @param[in] ControllerHandle Handle of device to stop driver on.
1225 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1226 children is zero stop the entire bus driver.
1227 @param[in] ChildHandleBuffer List of Child Handles to Stop.
1229 @retval EFI_SUCCESS This driver was removed ControllerHandle.
1230 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
1231 @retval Others This driver was not removed from this device
1236 PxeBcDriverBindingStop (
1237 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1238 IN EFI_HANDLE ControllerHandle
,
1239 IN UINTN NumberOfChildren
,
1240 IN EFI_HANDLE
*ChildHandleBuffer
1243 PXEBC_PRIVATE_DATA
*Private
;
1244 PXEBC_VIRTUAL_NIC
*VirtualNic
;
1245 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
1246 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
1248 EFI_HANDLE NicHandle
;
1258 Status
= gBS
->OpenProtocol (
1260 &gEfiLoadFileProtocolGuid
,
1261 (VOID
**) &LoadFile
,
1262 This
->DriverBindingHandle
,
1264 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1266 if (EFI_ERROR (Status
)) {
1268 // Get the Nic handle by any pass-over service child handle.
1270 NicHandle
= PxeBcGetNicByIp4Children (ControllerHandle
);
1271 if (NicHandle
== NULL
) {
1272 NicHandle
= PxeBcGetNicByIp6Children (ControllerHandle
);
1273 if (NicHandle
== NULL
) {
1274 return EFI_DEVICE_ERROR
;
1281 // Try to retrieve the private data by PxeBc protocol.
1283 Status
= gBS
->OpenProtocol (
1285 &gEfiPxeBaseCodeProtocolGuid
,
1287 This
->DriverBindingHandle
,
1289 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1291 if (EFI_ERROR (Status
)) {
1294 Private
= PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc
);
1298 // It's a virtual handle with LoadFileProtocol.
1300 Status
= gBS
->OpenProtocol (
1302 &gEfiLoadFileProtocolGuid
,
1303 (VOID
**) &LoadFile
,
1304 This
->DriverBindingHandle
,
1306 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1308 if (EFI_ERROR (Status
)) {
1312 VirtualNic
= PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile
);
1313 Private
= VirtualNic
->Private
;
1314 NicHandle
= Private
->Controller
;
1316 if (Private
->Ip6Nic
== VirtualNic
) {
1321 if (Private
->Ip4Nic
!= NULL
&& !IsIpv6
) {
1322 PxeBcDestroyIp4Children (This
, Private
);
1325 if (Private
->Ip6Nic
!= NULL
&& IsIpv6
) {
1326 PxeBcDestroyIp6Children (This
, Private
);
1329 if (Private
->Ip4Nic
== NULL
&& Private
->Ip6Nic
== NULL
) {
1330 gBS
->UninstallProtocolInterface (
1332 &gEfiPxeBaseCodeProtocolGuid
,