2 The driver binding for UEFI PXEBC protocol.
4 Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PxeBcImpl.h"
18 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding
= {
19 PxeBcDriverBindingSupported
,
20 PxeBcDriverBindingStart
,
21 PxeBcDriverBindingStop
,
28 This is the declaration of an EFI image entry point. This entry point is
29 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
30 both device drivers and bus drivers.
32 @param ImageHandle The firmware allocated handle for the UEFI image.
33 @param SystemTable A pointer to the EFI System Table.
35 @retval EFI_SUCCESS The operation completed successfully.
36 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
41 PxeBcDriverEntryPoint (
42 IN EFI_HANDLE ImageHandle
,
43 IN EFI_SYSTEM_TABLE
*SystemTable
46 return EfiLibInstallDriverBindingComponentName2 (
58 Test to see if this driver supports ControllerHandle. This service
59 is called by the EFI boot service ConnectController(). In
60 order to make drivers as small as possible, there are a few calling
61 restrictions for this service. ConnectController() must
62 follow these calling restrictions. If any other agent wishes to call
63 Supported() it must also follow these calling restrictions.
64 PxeBc requires DHCP4 and MTFTP4 protocols.
66 @param This Protocol instance pointer.
67 @param ControllerHandle Handle of device to test
68 @param RemainingDevicePath Optional parameter use to pick a specific child
71 @retval EFI_SUCCESS This driver supports this device
72 @retval EFI_ALREADY_STARTED This driver is already running on this device
73 @retval other This driver does not support this device
78 PxeBcDriverBindingSupported (
79 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
80 IN EFI_HANDLE ControllerHandle
,
81 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
84 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
87 Status
= gBS
->OpenProtocol (
89 &gEfiPxeBaseCodeProtocolGuid
,
91 This
->DriverBindingHandle
,
93 EFI_OPEN_PROTOCOL_GET_PROTOCOL
96 if (!EFI_ERROR (Status
)) {
97 return EFI_ALREADY_STARTED
;
100 Status
= gBS
->OpenProtocol (
102 &gEfiDhcp4ServiceBindingProtocolGuid
,
104 This
->DriverBindingHandle
,
106 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
109 if (!EFI_ERROR (Status
)) {
111 Status
= gBS
->OpenProtocol (
113 &gEfiMtftp4ServiceBindingProtocolGuid
,
115 This
->DriverBindingHandle
,
117 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
127 Start this driver on ControllerHandle. This service is called by the
128 EFI boot service ConnectController(). In order to make
129 drivers as small as possible, there are a few calling restrictions for
130 this service. ConnectController() must follow these
131 calling restrictions. If any other agent wishes to call Start() it
132 must also follow these calling restrictions.
134 @param This Protocol instance pointer.
135 @param ControllerHandle Handle of device to bind driver to
136 @param RemainingDevicePath Optional parameter use to pick a specific child
139 @retval EFI_SUCCESS This driver is added to ControllerHandle
140 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
141 @retval other This driver does not support this device
146 PxeBcDriverBindingStart (
147 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
148 IN EFI_HANDLE ControllerHandle
,
149 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
152 PXEBC_PRIVATE_DATA
*Private
;
155 EFI_IP4_MODE_DATA Ip4ModeData
;
157 Private
= AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA
));
158 if (Private
== NULL
) {
159 return EFI_OUT_OF_RESOURCES
;
162 Private
->Signature
= PXEBC_PRIVATE_DATA_SIGNATURE
;
163 Private
->Controller
= ControllerHandle
;
164 Private
->Image
= This
->DriverBindingHandle
;
165 CopyMem (&Private
->PxeBc
, &mPxeBcProtocolTemplate
, sizeof (Private
->PxeBc
));
166 Private
->PxeBc
.Mode
= &Private
->Mode
;
167 CopyMem (&Private
->LoadFile
, &mLoadFileProtocolTemplate
, sizeof (Private
->LoadFile
));
169 Private
->ProxyOffer
.Packet
.Offer
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
170 Private
->Dhcp4Ack
.Packet
.Ack
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
171 Private
->PxeReply
.Packet
.Ack
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
173 for (Index
= 0; Index
< PXEBC_MAX_OFFER_NUM
; Index
++) {
174 Private
->Dhcp4Offers
[Index
].Packet
.Offer
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
178 // Get the NII interface if it exists.
180 Status
= gBS
->OpenProtocol (
182 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
183 (VOID
**) &Private
->Nii
,
184 This
->DriverBindingHandle
,
186 EFI_OPEN_PROTOCOL_GET_PROTOCOL
188 if (EFI_ERROR (Status
)) {
192 Status
= NetLibCreateServiceChild (
194 This
->DriverBindingHandle
,
195 &gEfiArpServiceBindingProtocolGuid
,
198 if (EFI_ERROR (Status
)) {
202 Status
= gBS
->OpenProtocol (
204 &gEfiArpProtocolGuid
,
205 (VOID
**) &Private
->Arp
,
206 This
->DriverBindingHandle
,
208 EFI_OPEN_PROTOCOL_BY_DRIVER
210 if (EFI_ERROR (Status
)) {
214 Status
= NetLibCreateServiceChild (
216 This
->DriverBindingHandle
,
217 &gEfiDhcp4ServiceBindingProtocolGuid
,
220 if (EFI_ERROR (Status
)) {
224 Status
= gBS
->OpenProtocol (
226 &gEfiDhcp4ProtocolGuid
,
227 (VOID
**) &Private
->Dhcp4
,
228 This
->DriverBindingHandle
,
230 EFI_OPEN_PROTOCOL_BY_DRIVER
232 if (EFI_ERROR (Status
)) {
236 Status
= NetLibCreateServiceChild (
238 This
->DriverBindingHandle
,
239 &gEfiIp4ServiceBindingProtocolGuid
,
242 if (EFI_ERROR (Status
)) {
246 Status
= gBS
->OpenProtocol (
248 &gEfiIp4ProtocolGuid
,
249 (VOID
**) &Private
->Ip4
,
250 This
->DriverBindingHandle
,
252 EFI_OPEN_PROTOCOL_BY_DRIVER
254 if (EFI_ERROR (Status
)) {
259 // Get max packet size from Ip4 to calculate block size for Tftp later.
261 Status
= Private
->Ip4
->GetModeData (Private
->Ip4
, &Ip4ModeData
, NULL
, NULL
);
262 if (EFI_ERROR (Status
)) {
266 Private
->Ip4MaxPacketSize
= Ip4ModeData
.MaxPacketSize
;
268 Status
= NetLibCreateServiceChild (
270 This
->DriverBindingHandle
,
271 &gEfiMtftp4ServiceBindingProtocolGuid
,
272 &Private
->Mtftp4Child
275 if (EFI_ERROR (Status
)) {
279 Status
= gBS
->OpenProtocol (
280 Private
->Mtftp4Child
,
281 &gEfiMtftp4ProtocolGuid
,
282 (VOID
**) &Private
->Mtftp4
,
283 This
->DriverBindingHandle
,
285 EFI_OPEN_PROTOCOL_BY_DRIVER
288 if (EFI_ERROR (Status
)) {
292 Status
= NetLibCreateServiceChild (
294 This
->DriverBindingHandle
,
295 &gEfiUdp4ServiceBindingProtocolGuid
,
296 &Private
->Udp4ReadChild
299 if (EFI_ERROR (Status
)) {
304 // The UDP instance for EfiPxeBcUdpRead
306 Status
= gBS
->OpenProtocol (
307 Private
->Udp4ReadChild
,
308 &gEfiUdp4ProtocolGuid
,
309 (VOID
**) &Private
->Udp4Read
,
310 This
->DriverBindingHandle
,
312 EFI_OPEN_PROTOCOL_BY_DRIVER
315 if (EFI_ERROR (Status
)) {
320 // The UDP instance for EfiPxeBcUdpWrite
322 Status
= NetLibCreateServiceChild (
324 This
->DriverBindingHandle
,
325 &gEfiUdp4ServiceBindingProtocolGuid
,
326 &Private
->Udp4WriteChild
328 if (EFI_ERROR (Status
)) {
332 Status
= gBS
->OpenProtocol (
333 Private
->Udp4WriteChild
,
334 &gEfiUdp4ProtocolGuid
,
335 (VOID
**) &Private
->Udp4Write
,
336 This
->DriverBindingHandle
,
338 EFI_OPEN_PROTOCOL_BY_DRIVER
340 if (EFI_ERROR (Status
)) {
343 ZeroMem (&Private
->Udp4CfgData
, sizeof (EFI_UDP4_CONFIG_DATA
));
344 Private
->Udp4CfgData
.AcceptBroadcast
= FALSE
;
345 Private
->Udp4CfgData
.AcceptPromiscuous
= FALSE
;
346 Private
->Udp4CfgData
.AcceptAnyPort
= TRUE
;
347 Private
->Udp4CfgData
.AllowDuplicatePort
= TRUE
;
348 Private
->Udp4CfgData
.TypeOfService
= DEFAULT_ToS
;
349 Private
->Udp4CfgData
.TimeToLive
= DEFAULT_TTL
;
350 Private
->Udp4CfgData
.DoNotFragment
= FALSE
;
351 Private
->Udp4CfgData
.ReceiveTimeout
= PXEBC_DEFAULT_LIFETIME
;
352 Private
->Udp4CfgData
.UseDefaultAddress
= FALSE
;
354 PxeBcInitSeedPacket (&Private
->SeedPacket
, Private
->Udp4Read
);
355 Private
->MacLen
= Private
->SeedPacket
.Dhcp4
.Header
.HwAddrLen
;
356 CopyMem (&Private
->Mac
, &Private
->SeedPacket
.Dhcp4
.Header
.ClientHwAddr
[0], Private
->MacLen
);
359 ZeroMem (&Private
->Ip4ConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
360 Private
->Ip4ConfigData
.DefaultProtocol
= EFI_IP_PROTO_ICMP
;
361 Private
->Ip4ConfigData
.AcceptIcmpErrors
= TRUE
;
362 Private
->Ip4ConfigData
.TypeOfService
= DEFAULT_ToS
;
363 Private
->Ip4ConfigData
.TimeToLive
= DEFAULT_TTL
;
364 Private
->Ip4ConfigData
.DoNotFragment
= FALSE
;
365 Private
->Ip4ConfigData
.RawData
= FALSE
;
367 Status
= gBS
->InstallMultipleProtocolInterfaces (
369 &gEfiPxeBaseCodeProtocolGuid
,
371 &gEfiLoadFileProtocolGuid
,
375 if (EFI_ERROR (Status
)) {
379 // Locate Ip4->Ip4Config2 and store it for set IPv4 Policy.
381 Status
= gBS
->HandleProtocol (
383 &gEfiIp4Config2ProtocolGuid
,
384 (VOID
**) &Private
->Ip4Config2
386 if (EFI_ERROR (Status
)) {
394 if (Private
->Udp4WriteChild
!= NULL
) {
396 Private
->Udp4WriteChild
,
397 &gEfiUdp4ProtocolGuid
,
398 This
->DriverBindingHandle
,
401 NetLibDestroyServiceChild (
403 This
->DriverBindingHandle
,
404 &gEfiUdp4ServiceBindingProtocolGuid
,
405 Private
->Udp4WriteChild
409 if (Private
->Udp4ReadChild
!= NULL
) {
411 Private
->Udp4ReadChild
,
412 &gEfiUdp4ProtocolGuid
,
413 This
->DriverBindingHandle
,
416 NetLibDestroyServiceChild (
418 This
->DriverBindingHandle
,
419 &gEfiUdp4ServiceBindingProtocolGuid
,
420 Private
->Udp4ReadChild
424 if (Private
->Mtftp4Child
!= NULL
) {
426 Private
->Mtftp4Child
,
427 &gEfiMtftp4ProtocolGuid
,
428 This
->DriverBindingHandle
,
432 NetLibDestroyServiceChild (
434 This
->DriverBindingHandle
,
435 &gEfiMtftp4ServiceBindingProtocolGuid
,
440 if (Private
->Ip4Child
!= NULL
) {
443 &gEfiIp4ProtocolGuid
,
444 This
->DriverBindingHandle
,
448 NetLibDestroyServiceChild (
450 This
->DriverBindingHandle
,
451 &gEfiIp4ServiceBindingProtocolGuid
,
456 if (Private
->Dhcp4Child
!= NULL
) {
459 &gEfiDhcp4ProtocolGuid
,
460 This
->DriverBindingHandle
,
464 NetLibDestroyServiceChild (
466 This
->DriverBindingHandle
,
467 &gEfiDhcp4ServiceBindingProtocolGuid
,
472 if (Private
->ArpChild
!= NULL
) {
475 &gEfiArpProtocolGuid
,
476 This
->DriverBindingHandle
,
480 NetLibDestroyServiceChild (
482 This
->DriverBindingHandle
,
483 &gEfiArpServiceBindingProtocolGuid
,
495 Stop this driver on ControllerHandle. This service is called by the
496 EFI boot service DisconnectController(). In order to
497 make drivers as small as possible, there are a few calling
498 restrictions for this service. DisconnectController()
499 must follow these calling restrictions. If any other agent wishes
500 to call Stop() it must also follow these calling restrictions.
502 @param This Protocol instance pointer.
503 @param ControllerHandle Handle of device to stop driver on
504 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
505 children is zero stop the entire bus driver.
506 @param ChildHandleBuffer List of Child Handles to Stop.
508 @retval EFI_SUCCESS This driver is removed ControllerHandle
509 @retval other This driver was not removed from this device
514 PxeBcDriverBindingStop (
515 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
516 IN EFI_HANDLE ControllerHandle
,
517 IN UINTN NumberOfChildren
,
518 IN EFI_HANDLE
*ChildHandleBuffer
521 PXEBC_PRIVATE_DATA
*Private
;
522 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
523 EFI_HANDLE NicHandle
;
526 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiArpProtocolGuid
);
527 if (NicHandle
== NULL
) {
528 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
530 if (NicHandle
== NULL
) {
531 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
533 if (NicHandle
== NULL
) {
534 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
536 if (NicHandle
== NULL
) {
537 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiMtftp4ProtocolGuid
);
539 if (NicHandle
== NULL
) {
547 Status
= gBS
->OpenProtocol (
549 &gEfiPxeBaseCodeProtocolGuid
,
551 This
->DriverBindingHandle
,
553 EFI_OPEN_PROTOCOL_GET_PROTOCOL
556 if (EFI_ERROR (Status
)) {
561 // Stop functionality of PXE Base Code protocol
563 Status
= PxeBc
->Stop (PxeBc
);
564 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_NOT_STARTED
) {
568 Private
= PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc
);
570 Status
= gBS
->UninstallMultipleProtocolInterfaces (
572 &gEfiPxeBaseCodeProtocolGuid
,
574 &gEfiLoadFileProtocolGuid
,
579 if (!EFI_ERROR (Status
)) {
582 Private
->Udp4WriteChild
,
583 &gEfiUdp4ProtocolGuid
,
584 This
->DriverBindingHandle
,
587 NetLibDestroyServiceChild (
589 This
->DriverBindingHandle
,
590 &gEfiUdp4ServiceBindingProtocolGuid
,
591 Private
->Udp4WriteChild
595 Private
->Udp4ReadChild
,
596 &gEfiUdp4ProtocolGuid
,
597 This
->DriverBindingHandle
,
600 NetLibDestroyServiceChild (
602 This
->DriverBindingHandle
,
603 &gEfiUdp4ServiceBindingProtocolGuid
,
604 Private
->Udp4ReadChild
609 &gEfiDhcp4ProtocolGuid
,
610 This
->DriverBindingHandle
,
613 NetLibDestroyServiceChild (
615 This
->DriverBindingHandle
,
616 &gEfiDhcp4ServiceBindingProtocolGuid
,
621 Private
->Mtftp4Child
,
622 &gEfiMtftp4ProtocolGuid
,
623 This
->DriverBindingHandle
,
626 NetLibDestroyServiceChild (
628 This
->DriverBindingHandle
,
629 &gEfiMtftp4ServiceBindingProtocolGuid
,
635 &gEfiIp4ProtocolGuid
,
636 This
->DriverBindingHandle
,
639 NetLibDestroyServiceChild (
641 This
->DriverBindingHandle
,
642 &gEfiIp4ServiceBindingProtocolGuid
,
648 &gEfiArpProtocolGuid
,
649 This
->DriverBindingHandle
,
652 NetLibDestroyServiceChild (
654 This
->DriverBindingHandle
,
655 &gEfiArpServiceBindingProtocolGuid
,