2 The driver binding for UEFI PXEBC protocol.
4 Copyright (c) 2007 - 2009, Intel Corporation.<BR>
5 All rights reserved. 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
;
156 Private
= AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA
));
157 if (Private
== NULL
) {
158 return EFI_OUT_OF_RESOURCES
;
161 Private
->Signature
= PXEBC_PRIVATE_DATA_SIGNATURE
;
162 Private
->Controller
= ControllerHandle
;
163 Private
->Image
= This
->DriverBindingHandle
;
164 CopyMem (&Private
->PxeBc
, &mPxeBcProtocolTemplate
, sizeof (Private
->PxeBc
));
165 Private
->PxeBc
.Mode
= &Private
->Mode
;
166 CopyMem (&Private
->LoadFile
, &mLoadFileProtocolTemplate
, sizeof (Private
->LoadFile
));
168 Private
->ProxyOffer
.Packet
.Offer
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
169 Private
->Dhcp4Ack
.Packet
.Ack
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
170 Private
->PxeReply
.Packet
.Ack
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
172 for (Index
= 0; Index
< PXEBC_MAX_OFFER_NUM
; Index
++) {
173 Private
->Dhcp4Offers
[Index
].Packet
.Offer
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
177 // Get the NII interface if it exists.
179 Status
= gBS
->OpenProtocol (
181 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
182 (VOID
**) &Private
->Nii
,
183 This
->DriverBindingHandle
,
185 EFI_OPEN_PROTOCOL_GET_PROTOCOL
187 if (EFI_ERROR (Status
)) {
191 Status
= NetLibCreateServiceChild (
193 This
->DriverBindingHandle
,
194 &gEfiArpServiceBindingProtocolGuid
,
197 if (EFI_ERROR (Status
)) {
201 Status
= gBS
->OpenProtocol (
203 &gEfiArpProtocolGuid
,
204 (VOID
**) &Private
->Arp
,
205 This
->DriverBindingHandle
,
207 EFI_OPEN_PROTOCOL_BY_DRIVER
209 if (EFI_ERROR (Status
)) {
213 Status
= NetLibCreateServiceChild (
215 This
->DriverBindingHandle
,
216 &gEfiDhcp4ServiceBindingProtocolGuid
,
219 if (EFI_ERROR (Status
)) {
223 Status
= gBS
->OpenProtocol (
225 &gEfiDhcp4ProtocolGuid
,
226 (VOID
**) &Private
->Dhcp4
,
227 This
->DriverBindingHandle
,
229 EFI_OPEN_PROTOCOL_BY_DRIVER
231 if (EFI_ERROR (Status
)) {
235 Status
= NetLibCreateServiceChild (
237 This
->DriverBindingHandle
,
238 &gEfiIp4ServiceBindingProtocolGuid
,
241 if (EFI_ERROR (Status
)) {
245 Status
= gBS
->OpenProtocol (
247 &gEfiIp4ProtocolGuid
,
248 (VOID
**) &Private
->Ip4
,
249 This
->DriverBindingHandle
,
251 EFI_OPEN_PROTOCOL_BY_DRIVER
253 if (EFI_ERROR (Status
)) {
257 Status
= NetLibCreateServiceChild (
259 This
->DriverBindingHandle
,
260 &gEfiMtftp4ServiceBindingProtocolGuid
,
261 &Private
->Mtftp4Child
264 if (EFI_ERROR (Status
)) {
268 Status
= gBS
->OpenProtocol (
269 Private
->Mtftp4Child
,
270 &gEfiMtftp4ProtocolGuid
,
271 (VOID
**) &Private
->Mtftp4
,
272 This
->DriverBindingHandle
,
274 EFI_OPEN_PROTOCOL_BY_DRIVER
277 if (EFI_ERROR (Status
)) {
281 Status
= NetLibCreateServiceChild (
283 This
->DriverBindingHandle
,
284 &gEfiUdp4ServiceBindingProtocolGuid
,
285 &Private
->Udp4ReadChild
288 if (EFI_ERROR (Status
)) {
293 // The UDP instance for EfiPxeBcUdpRead
295 Status
= gBS
->OpenProtocol (
296 Private
->Udp4ReadChild
,
297 &gEfiUdp4ProtocolGuid
,
298 (VOID
**) &Private
->Udp4Read
,
299 This
->DriverBindingHandle
,
301 EFI_OPEN_PROTOCOL_BY_DRIVER
304 if (EFI_ERROR (Status
)) {
309 // The UDP instance for EfiPxeBcUdpWrite
311 Status
= NetLibCreateServiceChild (
313 This
->DriverBindingHandle
,
314 &gEfiUdp4ServiceBindingProtocolGuid
,
315 &Private
->Udp4WriteChild
317 if (EFI_ERROR (Status
)) {
321 Status
= gBS
->OpenProtocol (
322 Private
->Udp4WriteChild
,
323 &gEfiUdp4ProtocolGuid
,
324 (VOID
**) &Private
->Udp4Write
,
325 This
->DriverBindingHandle
,
327 EFI_OPEN_PROTOCOL_BY_DRIVER
329 if (EFI_ERROR (Status
)) {
332 ZeroMem (&Private
->Udp4CfgData
, sizeof (EFI_UDP4_CONFIG_DATA
));
333 Private
->Udp4CfgData
.AcceptBroadcast
= TRUE
;
334 Private
->Udp4CfgData
.AcceptPromiscuous
= FALSE
;
335 Private
->Udp4CfgData
.AcceptAnyPort
= TRUE
;
336 Private
->Udp4CfgData
.AllowDuplicatePort
= TRUE
;
337 Private
->Udp4CfgData
.TypeOfService
= DEFAULT_ToS
;
338 Private
->Udp4CfgData
.TimeToLive
= DEFAULT_TTL
;
339 Private
->Udp4CfgData
.DoNotFragment
= FALSE
;
340 Private
->Udp4CfgData
.ReceiveTimeout
= 50000; // 50 milliseconds
341 Private
->Udp4CfgData
.UseDefaultAddress
= FALSE
;
343 PxeBcInitSeedPacket (&Private
->SeedPacket
, Private
->Udp4Read
);
344 Private
->MacLen
= Private
->SeedPacket
.Dhcp4
.Header
.HwAddrLen
;
345 CopyMem (&Private
->Mac
, &Private
->SeedPacket
.Dhcp4
.Header
.ClientHwAddr
[0], Private
->MacLen
);
348 ZeroMem (&Private
->Ip4ConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
349 Private
->Ip4ConfigData
.DefaultProtocol
= EFI_IP_PROTO_ICMP
;
350 Private
->Ip4ConfigData
.AcceptIcmpErrors
= TRUE
;
351 Private
->Ip4ConfigData
.TypeOfService
= DEFAULT_ToS
;
352 Private
->Ip4ConfigData
.TimeToLive
= DEFAULT_TTL
;
353 Private
->Ip4ConfigData
.DoNotFragment
= FALSE
;
354 Private
->Ip4ConfigData
.RawData
= FALSE
;
356 Status
= gBS
->InstallMultipleProtocolInterfaces (
358 &gEfiPxeBaseCodeProtocolGuid
,
360 &gEfiLoadFileProtocolGuid
,
364 if (EFI_ERROR (Status
)) {
372 if (Private
->Udp4WriteChild
!= NULL
) {
374 Private
->Udp4WriteChild
,
375 &gEfiUdp4ProtocolGuid
,
376 This
->DriverBindingHandle
,
379 NetLibDestroyServiceChild (
381 This
->DriverBindingHandle
,
382 &gEfiUdp4ServiceBindingProtocolGuid
,
383 Private
->Udp4WriteChild
387 if (Private
->Udp4ReadChild
!= NULL
) {
389 Private
->Udp4ReadChild
,
390 &gEfiUdp4ProtocolGuid
,
391 This
->DriverBindingHandle
,
394 NetLibDestroyServiceChild (
396 This
->DriverBindingHandle
,
397 &gEfiUdp4ServiceBindingProtocolGuid
,
398 Private
->Udp4ReadChild
402 if (Private
->Mtftp4Child
!= NULL
) {
404 Private
->Mtftp4Child
,
405 &gEfiMtftp4ProtocolGuid
,
406 This
->DriverBindingHandle
,
410 NetLibDestroyServiceChild (
412 This
->DriverBindingHandle
,
413 &gEfiMtftp4ServiceBindingProtocolGuid
,
418 if (Private
->Ip4Child
!= NULL
) {
421 &gEfiIp4ProtocolGuid
,
422 This
->DriverBindingHandle
,
426 NetLibDestroyServiceChild (
428 This
->DriverBindingHandle
,
429 &gEfiIp4ServiceBindingProtocolGuid
,
434 if (Private
->Dhcp4Child
!= NULL
) {
437 &gEfiDhcp4ProtocolGuid
,
438 This
->DriverBindingHandle
,
442 NetLibDestroyServiceChild (
444 This
->DriverBindingHandle
,
445 &gEfiDhcp4ServiceBindingProtocolGuid
,
450 if (Private
->ArpChild
!= NULL
) {
453 &gEfiArpProtocolGuid
,
454 This
->DriverBindingHandle
,
458 NetLibDestroyServiceChild (
460 This
->DriverBindingHandle
,
461 &gEfiArpServiceBindingProtocolGuid
,
466 gBS
->FreePool (Private
);
473 Stop this driver on ControllerHandle. This service is called by the
474 EFI boot service DisconnectController(). In order to
475 make drivers as small as possible, there are a few calling
476 restrictions for this service. DisconnectController()
477 must follow these calling restrictions. If any other agent wishes
478 to call Stop() it must also follow these calling restrictions.
480 @param This Protocol instance pointer.
481 @param ControllerHandle Handle of device to stop driver on
482 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
483 children is zero stop the entire bus driver.
484 @param ChildHandleBuffer List of Child Handles to Stop.
486 @retval EFI_SUCCESS This driver is removed ControllerHandle
487 @retval other This driver was not removed from this device
492 PxeBcDriverBindingStop (
493 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
494 IN EFI_HANDLE ControllerHandle
,
495 IN UINTN NumberOfChildren
,
496 IN EFI_HANDLE
*ChildHandleBuffer
499 PXEBC_PRIVATE_DATA
*Private
;
500 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
501 EFI_HANDLE NicHandle
;
504 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiArpProtocolGuid
);
505 if (NicHandle
== NULL
) {
506 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
508 if (NicHandle
== NULL
) {
509 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
511 if (NicHandle
== NULL
) {
512 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
514 if (NicHandle
== NULL
) {
515 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiMtftp4ProtocolGuid
);
517 if (NicHandle
== NULL
) {
518 return EFI_DEVICE_ERROR
;
525 Status
= gBS
->OpenProtocol (
527 &gEfiPxeBaseCodeProtocolGuid
,
529 This
->DriverBindingHandle
,
531 EFI_OPEN_PROTOCOL_GET_PROTOCOL
534 if (EFI_ERROR (Status
)) {
538 Private
= PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc
);
540 Status
= gBS
->UninstallMultipleProtocolInterfaces (
542 &gEfiPxeBaseCodeProtocolGuid
,
544 &gEfiLoadFileProtocolGuid
,
549 if (!EFI_ERROR (Status
)) {
552 Private
->Udp4WriteChild
,
553 &gEfiUdp4ProtocolGuid
,
554 This
->DriverBindingHandle
,
557 NetLibDestroyServiceChild (
559 This
->DriverBindingHandle
,
560 &gEfiUdp4ServiceBindingProtocolGuid
,
561 Private
->Udp4WriteChild
565 Private
->Udp4ReadChild
,
566 &gEfiUdp4ProtocolGuid
,
567 This
->DriverBindingHandle
,
570 NetLibDestroyServiceChild (
572 This
->DriverBindingHandle
,
573 &gEfiUdp4ServiceBindingProtocolGuid
,
574 Private
->Udp4ReadChild
579 &gEfiDhcp4ProtocolGuid
,
580 This
->DriverBindingHandle
,
583 NetLibDestroyServiceChild (
585 This
->DriverBindingHandle
,
586 &gEfiDhcp4ServiceBindingProtocolGuid
,
591 Private
->Mtftp4Child
,
592 &gEfiMtftp4ProtocolGuid
,
593 This
->DriverBindingHandle
,
596 NetLibDestroyServiceChild (
598 This
->DriverBindingHandle
,
599 &gEfiMtftp4ServiceBindingProtocolGuid
,
605 &gEfiIp4ProtocolGuid
,
606 This
->DriverBindingHandle
,
609 NetLibDestroyServiceChild (
611 This
->DriverBindingHandle
,
612 &gEfiIp4ServiceBindingProtocolGuid
,
618 &gEfiArpProtocolGuid
,
619 This
->DriverBindingHandle
,
622 NetLibDestroyServiceChild (
624 This
->DriverBindingHandle
,
625 &gEfiArpServiceBindingProtocolGuid
,
629 gBS
->FreePool (Private
);