TianoCore EDK2 master
Loading...
Searching...
No Matches
PxeBcDriver.c
Go to the documentation of this file.
1
12#include "PxeBcImpl.h"
13
14EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp4DriverBinding = {
18 0xa,
19 NULL,
20 NULL
21};
22
23EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp6DriverBinding = {
27 0xa,
28 NULL,
29 NULL
30};
31
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
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
106VOID
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
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
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
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
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
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
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
288VOID
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
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 );
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 );
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
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
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
454 IN EFI_HANDLE ControllerHandle,
455 IN PXEBC_PRIVATE_DATA *Private,
456 OUT BOOLEAN *Ipv6Support
457 )
458{
459 EFI_HANDLE Handle;
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
552 IN EFI_HANDLE ControllerHandle,
553 IN PXEBC_PRIVATE_DATA *Private
554 )
555{
556 EFI_STATUS Status;
557 IPv4_DEVICE_PATH Ip4Node;
559 EFI_UDP4_CONFIG_DATA *Udp4CfgData;
560 EFI_IP4_CONFIG_DATA *Ip4CfgData;
561 EFI_IP4_MODE_DATA Ip4ModeData;
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,
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,
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
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;
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,
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
1240EFIAPI
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
1253 ImageHandle,
1254 SystemTable,
1255 &gPxeBcIp4DriverBinding,
1256 ImageHandle,
1257 &gPxeBcComponentName,
1258 &gPxeBcComponentName2
1259 );
1260 if (EFI_ERROR (Status)) {
1261 return Status;
1262 }
1263
1265 ImageHandle,
1266 SystemTable,
1267 &gPxeBcIp6DriverBinding,
1268 NULL,
1269 &gPxeBcComponentName,
1270 &gPxeBcComponentName2
1271 );
1272 if (EFI_ERROR (Status)) {
1274 &gPxeBcIp4DriverBinding,
1275 &gPxeBcComponentName,
1276 &gPxeBcComponentName2
1277 );
1278 }
1279
1280 return Status;
1281}
1282
1298EFIAPI
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
1375EFIAPI
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;
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,
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,
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
1541EFIAPI
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;
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
1668EFIAPI
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
1702EFIAPI
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
1737EFIAPI
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
1772EFIAPI
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
1806EFIAPI
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
1841EFIAPI
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}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MSG_IPv6_DP
Definition: DevicePath.h:607
#define MSG_IPv4_DP
Definition: DevicePath.h:566
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
EFI_HANDLE EFIAPI NetLibGetSnpHandle(IN EFI_HANDLE ServiceHandle, OUT EFI_SIMPLE_NETWORK_PROTOCOL **Snp OPTIONAL)
Definition: DxeNetLib.c:2073
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
Definition: DxeNetLib.c:1011
EFI_HANDLE EFIAPI NetLibGetNicHandle(IN EFI_HANDLE Controller, IN EFI_GUID *ProtocolGuid)
Definition: DxeNetLib.c:3019
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define DEFAULT_TTL
Definition: PxeBaseCode.h:37
EFI_STATUS EFIAPI PxeBcStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN UINT8 IpVersion)
Definition: PxeBcDriver.c:1376
EFI_STATUS EFIAPI PxeBcDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: PxeBcDriver.c:1241
EFI_STATUS EFIAPI PxeBcIp6DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: PxeBcDriver.c:1807
EFI_STATUS EFIAPI PxeBcIp4DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: PxeBcDriver.c:1703
EFI_STATUS EFIAPI PxeBcIp4DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: PxeBcDriver.c:1738
EFI_STATUS PxeBcCreateIp6Children(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN PXEBC_PRIVATE_DATA *Private)
Definition: PxeBcDriver.c:882
VOID PxeBcDestroyIp4Children(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN PXEBC_PRIVATE_DATA *Private)
Definition: PxeBcDriver.c:107
EFI_STATUS EFIAPI PxeBcIp6DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: PxeBcDriver.c:1773
EFI_STATUS EFIAPI PxeBcIp4DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: PxeBcDriver.c:1669
EFI_STATUS EFIAPI PxeBcIp6DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: PxeBcDriver.c:1842
EFI_STATUS PxeBcCheckIpv6Support(IN EFI_HANDLE ControllerHandle, IN PXEBC_PRIVATE_DATA *Private, OUT BOOLEAN *Ipv6Support)
Definition: PxeBcDriver.c:453
VOID PxeBcDestroyIp6Children(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN PXEBC_PRIVATE_DATA *Private)
Definition: PxeBcDriver.c:289
EFI_STATUS PxeBcCreateIp4Children(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN PXEBC_PRIVATE_DATA *Private)
Definition: PxeBcDriver.c:550
EFI_STATUS EFIAPI PxeBcSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN UINT8 IpVersion)
Definition: PxeBcDriver.c:1299
EFI_HANDLE PxeBcGetNicByIp6Children(IN EFI_HANDLE ControllerHandle)
Definition: PxeBcDriver.c:76
EFI_STATUS EFIAPI PxeBcStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer, IN UINT8 IpVersion)
Definition: PxeBcDriver.c:1542
EFI_HANDLE PxeBcGetNicByIp4Children(IN EFI_HANDLE ControllerHandle)
Definition: PxeBcDriver.c:41
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibUninstallDriverBindingComponentName2(IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_PXE_BASE_CODE_MODE * Mode
Definition: PxeBaseCode.h:928
UINT8 TypeOfService
Definition: Ip4.h:102
UINT32 ReceiveTimeout
Definition: Ip4.h:121
UINT8 TimeToLive
Definition: Ip4.h:106
UINT8 DefaultProtocol
Definition: Ip4.h:63
BOOLEAN AcceptIcmpErrors
Definition: Ip4.h:74
UINT32 TransmitTimeout
Definition: Ip4.h:127
UINT32 MaxPacketSize
Definition: Ip4.h:149
BOOLEAN AcceptIcmpErrors
Definition: Ip6.h:157
UINT32 ReceiveTimeout
Definition: Ip6.h:208
UINT8 DefaultProtocol
Definition: Ip6.h:144
UINT8 HopLimit
Definition: Ip6.h:197
UINT32 TransmitTimeout
Definition: Ip6.h:214
UINT32 MaxPacketSize
Definition: Ip6.h:315
EFI_IP6_NEIGHBOR_CACHE * NeighborCache
Definition: Ip6.h:366
EFI_IP6_ICMP_TYPE * IcmpTypeList
Definition: Ip6.h:386
EFI_IP6_ADDRESS_INFO * AddressList
Definition: Ip6.h:336
EFI_IP6_ROUTE_TABLE * RouteTable
Definition: Ip6.h:356
EFI_IPv6_ADDRESS * GroupTable
Definition: Ip6.h:347
EFI_IP6_ADDRESS_INFO * PrefixTable
Definition: Ip6.h:376
BOOLEAN AcceptAnyPort
Definition: Udp6.h:126
BOOLEAN AllowDuplicatePort
Definition: Udp6.h:131
UINT32 ReceiveTimeout
Definition: Udp6.h:144
UINT32 TransmitTimeout
Definition: Udp6.h:149
Definition: Base.h:213
BOOLEAN StaticIpAddress
Definition: DevicePath.h:593