2 The driver binding for UEFI PXEBC protocol.
4 Copyright (c) 2007 - 2012, 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
)) {
383 if (Private
->Udp4WriteChild
!= NULL
) {
385 Private
->Udp4WriteChild
,
386 &gEfiUdp4ProtocolGuid
,
387 This
->DriverBindingHandle
,
390 NetLibDestroyServiceChild (
392 This
->DriverBindingHandle
,
393 &gEfiUdp4ServiceBindingProtocolGuid
,
394 Private
->Udp4WriteChild
398 if (Private
->Udp4ReadChild
!= NULL
) {
400 Private
->Udp4ReadChild
,
401 &gEfiUdp4ProtocolGuid
,
402 This
->DriverBindingHandle
,
405 NetLibDestroyServiceChild (
407 This
->DriverBindingHandle
,
408 &gEfiUdp4ServiceBindingProtocolGuid
,
409 Private
->Udp4ReadChild
413 if (Private
->Mtftp4Child
!= NULL
) {
415 Private
->Mtftp4Child
,
416 &gEfiMtftp4ProtocolGuid
,
417 This
->DriverBindingHandle
,
421 NetLibDestroyServiceChild (
423 This
->DriverBindingHandle
,
424 &gEfiMtftp4ServiceBindingProtocolGuid
,
429 if (Private
->Ip4Child
!= NULL
) {
432 &gEfiIp4ProtocolGuid
,
433 This
->DriverBindingHandle
,
437 NetLibDestroyServiceChild (
439 This
->DriverBindingHandle
,
440 &gEfiIp4ServiceBindingProtocolGuid
,
445 if (Private
->Dhcp4Child
!= NULL
) {
448 &gEfiDhcp4ProtocolGuid
,
449 This
->DriverBindingHandle
,
453 NetLibDestroyServiceChild (
455 This
->DriverBindingHandle
,
456 &gEfiDhcp4ServiceBindingProtocolGuid
,
461 if (Private
->ArpChild
!= NULL
) {
464 &gEfiArpProtocolGuid
,
465 This
->DriverBindingHandle
,
469 NetLibDestroyServiceChild (
471 This
->DriverBindingHandle
,
472 &gEfiArpServiceBindingProtocolGuid
,
484 Stop this driver on ControllerHandle. This service is called by the
485 EFI boot service DisconnectController(). In order to
486 make drivers as small as possible, there are a few calling
487 restrictions for this service. DisconnectController()
488 must follow these calling restrictions. If any other agent wishes
489 to call Stop() it must also follow these calling restrictions.
491 @param This Protocol instance pointer.
492 @param ControllerHandle Handle of device to stop driver on
493 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
494 children is zero stop the entire bus driver.
495 @param ChildHandleBuffer List of Child Handles to Stop.
497 @retval EFI_SUCCESS This driver is removed ControllerHandle
498 @retval other This driver was not removed from this device
503 PxeBcDriverBindingStop (
504 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
505 IN EFI_HANDLE ControllerHandle
,
506 IN UINTN NumberOfChildren
,
507 IN EFI_HANDLE
*ChildHandleBuffer
510 PXEBC_PRIVATE_DATA
*Private
;
511 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
512 EFI_HANDLE NicHandle
;
515 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiArpProtocolGuid
);
516 if (NicHandle
== NULL
) {
517 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
519 if (NicHandle
== NULL
) {
520 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
522 if (NicHandle
== NULL
) {
523 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
525 if (NicHandle
== NULL
) {
526 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiMtftp4ProtocolGuid
);
528 if (NicHandle
== NULL
) {
536 Status
= gBS
->OpenProtocol (
538 &gEfiPxeBaseCodeProtocolGuid
,
540 This
->DriverBindingHandle
,
542 EFI_OPEN_PROTOCOL_GET_PROTOCOL
545 if (EFI_ERROR (Status
)) {
550 // Stop functionality of PXE Base Code protocol
552 Status
= PxeBc
->Stop (PxeBc
);
553 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_NOT_STARTED
) {
557 Private
= PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc
);
559 Status
= gBS
->UninstallMultipleProtocolInterfaces (
561 &gEfiPxeBaseCodeProtocolGuid
,
563 &gEfiLoadFileProtocolGuid
,
568 if (!EFI_ERROR (Status
)) {
571 Private
->Udp4WriteChild
,
572 &gEfiUdp4ProtocolGuid
,
573 This
->DriverBindingHandle
,
576 NetLibDestroyServiceChild (
578 This
->DriverBindingHandle
,
579 &gEfiUdp4ServiceBindingProtocolGuid
,
580 Private
->Udp4WriteChild
584 Private
->Udp4ReadChild
,
585 &gEfiUdp4ProtocolGuid
,
586 This
->DriverBindingHandle
,
589 NetLibDestroyServiceChild (
591 This
->DriverBindingHandle
,
592 &gEfiUdp4ServiceBindingProtocolGuid
,
593 Private
->Udp4ReadChild
598 &gEfiDhcp4ProtocolGuid
,
599 This
->DriverBindingHandle
,
602 NetLibDestroyServiceChild (
604 This
->DriverBindingHandle
,
605 &gEfiDhcp4ServiceBindingProtocolGuid
,
610 Private
->Mtftp4Child
,
611 &gEfiMtftp4ProtocolGuid
,
612 This
->DriverBindingHandle
,
615 NetLibDestroyServiceChild (
617 This
->DriverBindingHandle
,
618 &gEfiMtftp4ServiceBindingProtocolGuid
,
624 &gEfiIp4ProtocolGuid
,
625 This
->DriverBindingHandle
,
628 NetLibDestroyServiceChild (
630 This
->DriverBindingHandle
,
631 &gEfiIp4ServiceBindingProtocolGuid
,
637 &gEfiArpProtocolGuid
,
638 This
->DriverBindingHandle
,
641 NetLibDestroyServiceChild (
643 This
->DriverBindingHandle
,
644 &gEfiArpServiceBindingProtocolGuid
,