2 The driver binding for UEFI PXEBC protocol.
4 Copyright (c) 2007 - 2008, 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.
40 PxeBcDriverEntryPoint (
41 IN EFI_HANDLE ImageHandle
,
42 IN EFI_SYSTEM_TABLE
*SystemTable
45 return EfiLibInstallDriverBindingComponentName2 (
57 Test to see if this driver supports ControllerHandle. This service
58 is called by the EFI boot service ConnectController(). In
59 order to make drivers as small as possible, there are a few calling
60 restrictions for this service. ConnectController() must
61 follow these calling restrictions. If any other agent wishes to call
62 Supported() it must also follow these calling restrictions.
63 PxeBc requires DHCP4 and MTFTP4 protocols.
65 @param This Protocol instance pointer.
66 @param ControllerHandle Handle of device to test
67 @param RemainingDevicePath Optional parameter use to pick a specific child
70 @retval EFI_SUCCESS This driver supports this device
71 @retval EFI_ALREADY_STARTED This driver is already running on this device
72 @retval other This driver does not support this device
77 PxeBcDriverBindingSupported (
78 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
79 IN EFI_HANDLE ControllerHandle
,
80 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
83 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
86 Status
= gBS
->OpenProtocol (
88 &gEfiPxeBaseCodeProtocolGuid
,
90 This
->DriverBindingHandle
,
92 EFI_OPEN_PROTOCOL_GET_PROTOCOL
95 if (!EFI_ERROR (Status
)) {
96 return EFI_ALREADY_STARTED
;
99 Status
= gBS
->OpenProtocol (
101 &gEfiDhcp4ServiceBindingProtocolGuid
,
103 This
->DriverBindingHandle
,
105 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
108 if (!EFI_ERROR (Status
)) {
110 Status
= gBS
->OpenProtocol (
112 &gEfiMtftp4ServiceBindingProtocolGuid
,
114 This
->DriverBindingHandle
,
116 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
126 Start this driver on ControllerHandle. This service is called by the
127 EFI boot service ConnectController(). In order to make
128 drivers as small as possible, there are a few calling restrictions for
129 this service. ConnectController() must follow these
130 calling restrictions. If any other agent wishes to call Start() it
131 must also follow these calling restrictions.
133 @param This Protocol instance pointer.
134 @param ControllerHandle Handle of device to bind driver to
135 @param RemainingDevicePath Optional parameter use to pick a specific child
138 @retval EFI_SUCCESS This driver is added to ControllerHandle
139 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
140 @retval other This driver does not support this device
145 PxeBcDriverBindingStart (
146 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
147 IN EFI_HANDLE ControllerHandle
,
148 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
151 PXEBC_PRIVATE_DATA
*Private
;
155 Private
= AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA
));
156 if (Private
== NULL
) {
157 return EFI_OUT_OF_RESOURCES
;
160 Private
->Signature
= PXEBC_PRIVATE_DATA_SIGNATURE
;
161 Private
->Controller
= ControllerHandle
;
162 Private
->Image
= This
->DriverBindingHandle
;
163 CopyMem (&Private
->PxeBc
, &mPxeBcProtocolTemplate
, sizeof (Private
->PxeBc
));
164 Private
->PxeBc
.Mode
= &Private
->Mode
;
165 CopyMem (&Private
->LoadFile
, &mLoadFileProtocolTemplate
, sizeof (Private
->LoadFile
));
167 Private
->ProxyOffer
.Packet
.Offer
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
168 Private
->Dhcp4Ack
.Packet
.Ack
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
169 Private
->PxeReply
.Packet
.Ack
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
171 for (Index
= 0; Index
< PXEBC_MAX_OFFER_NUM
; Index
++) {
172 Private
->Dhcp4Offers
[Index
].Packet
.Offer
.Size
= PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE
;
176 // Get the NII interface
178 Status
= gBS
->OpenProtocol (
180 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
181 (VOID
**) &Private
->Nii
,
182 This
->DriverBindingHandle
,
184 EFI_OPEN_PROTOCOL_GET_PROTOCOL
186 if (EFI_ERROR (Status
)) {
190 Status
= NetLibCreateServiceChild (
192 This
->DriverBindingHandle
,
193 &gEfiArpServiceBindingProtocolGuid
,
196 if (EFI_ERROR (Status
)) {
200 Status
= gBS
->OpenProtocol (
202 &gEfiArpProtocolGuid
,
203 (VOID
**) &Private
->Arp
,
204 This
->DriverBindingHandle
,
206 EFI_OPEN_PROTOCOL_BY_DRIVER
208 if (EFI_ERROR (Status
)) {
212 Status
= NetLibCreateServiceChild (
214 This
->DriverBindingHandle
,
215 &gEfiDhcp4ServiceBindingProtocolGuid
,
218 if (EFI_ERROR (Status
)) {
222 Status
= gBS
->OpenProtocol (
224 &gEfiDhcp4ProtocolGuid
,
225 (VOID
**) &Private
->Dhcp4
,
226 This
->DriverBindingHandle
,
228 EFI_OPEN_PROTOCOL_BY_DRIVER
230 if (EFI_ERROR (Status
)) {
234 Status
= NetLibCreateServiceChild (
236 This
->DriverBindingHandle
,
237 &gEfiIp4ServiceBindingProtocolGuid
,
240 if (EFI_ERROR (Status
)) {
244 Status
= gBS
->OpenProtocol (
246 &gEfiIp4ProtocolGuid
,
247 (VOID
**) &Private
->Ip4
,
248 This
->DriverBindingHandle
,
250 EFI_OPEN_PROTOCOL_BY_DRIVER
252 if (EFI_ERROR (Status
)) {
256 Status
= NetLibCreateServiceChild (
258 This
->DriverBindingHandle
,
259 &gEfiMtftp4ServiceBindingProtocolGuid
,
260 &Private
->Mtftp4Child
263 if (EFI_ERROR (Status
)) {
267 Status
= gBS
->OpenProtocol (
268 Private
->Mtftp4Child
,
269 &gEfiMtftp4ProtocolGuid
,
270 (VOID
**) &Private
->Mtftp4
,
271 This
->DriverBindingHandle
,
273 EFI_OPEN_PROTOCOL_BY_DRIVER
276 if (EFI_ERROR (Status
)) {
280 Status
= NetLibCreateServiceChild (
282 This
->DriverBindingHandle
,
283 &gEfiUdp4ServiceBindingProtocolGuid
,
284 &Private
->Udp4ReadChild
287 if (EFI_ERROR (Status
)) {
292 // The UDP instance for EfiPxeBcUdpRead
294 Status
= gBS
->OpenProtocol (
295 Private
->Udp4ReadChild
,
296 &gEfiUdp4ProtocolGuid
,
297 (VOID
**) &Private
->Udp4Read
,
298 This
->DriverBindingHandle
,
300 EFI_OPEN_PROTOCOL_BY_DRIVER
303 if (EFI_ERROR (Status
)) {
308 // The UDP instance for EfiPxeBcUdpWrite
310 Status
= NetLibCreateServiceChild (
312 This
->DriverBindingHandle
,
313 &gEfiUdp4ServiceBindingProtocolGuid
,
314 &Private
->Udp4WriteChild
316 if (EFI_ERROR (Status
)) {
320 Status
= gBS
->OpenProtocol (
321 Private
->Udp4WriteChild
,
322 &gEfiUdp4ProtocolGuid
,
323 (VOID
**) &Private
->Udp4Write
,
324 This
->DriverBindingHandle
,
326 EFI_OPEN_PROTOCOL_BY_DRIVER
328 if (EFI_ERROR (Status
)) {
331 ZeroMem (&Private
->Udp4CfgData
, sizeof (EFI_UDP4_CONFIG_DATA
));
332 Private
->Udp4CfgData
.AcceptBroadcast
= TRUE
;
333 Private
->Udp4CfgData
.AcceptPromiscuous
= FALSE
;
334 Private
->Udp4CfgData
.AcceptAnyPort
= TRUE
;
335 Private
->Udp4CfgData
.AllowDuplicatePort
= TRUE
;
336 Private
->Udp4CfgData
.TypeOfService
= DEFAULT_ToS
;
337 Private
->Udp4CfgData
.TimeToLive
= DEFAULT_TTL
;
338 Private
->Udp4CfgData
.DoNotFragment
= FALSE
;
339 Private
->Udp4CfgData
.ReceiveTimeout
= 50000; // 50 milliseconds
340 Private
->Udp4CfgData
.UseDefaultAddress
= FALSE
;
342 PxeBcInitSeedPacket (&Private
->SeedPacket
, Private
->Udp4Read
);
343 Private
->MacLen
= Private
->SeedPacket
.Dhcp4
.Header
.HwAddrLen
;
344 CopyMem (&Private
->Mac
, &Private
->SeedPacket
.Dhcp4
.Header
.ClientHwAddr
[0], Private
->MacLen
);
347 ZeroMem (&Private
->Ip4ConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
348 Private
->Ip4ConfigData
.DefaultProtocol
= EFI_IP_PROTO_ICMP
;
349 Private
->Ip4ConfigData
.AcceptIcmpErrors
= TRUE
;
350 Private
->Ip4ConfigData
.TypeOfService
= DEFAULT_ToS
;
351 Private
->Ip4ConfigData
.TimeToLive
= DEFAULT_TTL
;
352 Private
->Ip4ConfigData
.DoNotFragment
= FALSE
;
353 Private
->Ip4ConfigData
.RawData
= FALSE
;
355 Status
= gBS
->InstallMultipleProtocolInterfaces (
357 &gEfiPxeBaseCodeProtocolGuid
,
359 &gEfiLoadFileProtocolGuid
,
363 if (EFI_ERROR (Status
)) {
371 if (Private
->Udp4WriteChild
!= NULL
) {
373 Private
->Udp4WriteChild
,
374 &gEfiUdp4ProtocolGuid
,
375 This
->DriverBindingHandle
,
378 NetLibDestroyServiceChild (
380 This
->DriverBindingHandle
,
381 &gEfiUdp4ServiceBindingProtocolGuid
,
382 Private
->Udp4WriteChild
386 if (Private
->Udp4ReadChild
!= NULL
) {
388 Private
->Udp4ReadChild
,
389 &gEfiUdp4ProtocolGuid
,
390 This
->DriverBindingHandle
,
393 NetLibDestroyServiceChild (
395 This
->DriverBindingHandle
,
396 &gEfiUdp4ServiceBindingProtocolGuid
,
397 Private
->Udp4ReadChild
401 if (Private
->Mtftp4Child
!= NULL
) {
403 Private
->Mtftp4Child
,
404 &gEfiMtftp4ProtocolGuid
,
405 This
->DriverBindingHandle
,
409 NetLibDestroyServiceChild (
411 This
->DriverBindingHandle
,
412 &gEfiMtftp4ServiceBindingProtocolGuid
,
417 if (Private
->Ip4Child
!= NULL
) {
420 &gEfiIp4ProtocolGuid
,
421 This
->DriverBindingHandle
,
425 NetLibDestroyServiceChild (
427 This
->DriverBindingHandle
,
428 &gEfiIp4ServiceBindingProtocolGuid
,
433 if (Private
->Dhcp4Child
!= NULL
) {
436 &gEfiDhcp4ProtocolGuid
,
437 This
->DriverBindingHandle
,
441 NetLibDestroyServiceChild (
443 This
->DriverBindingHandle
,
444 &gEfiDhcp4ServiceBindingProtocolGuid
,
449 if (Private
->ArpChild
!= NULL
) {
452 &gEfiArpProtocolGuid
,
453 This
->DriverBindingHandle
,
457 NetLibDestroyServiceChild (
459 This
->DriverBindingHandle
,
460 &gEfiArpServiceBindingProtocolGuid
,
465 gBS
->FreePool (Private
);
472 Stop this driver on ControllerHandle. This service is called by the
473 EFI boot service DisconnectController(). In order to
474 make drivers as small as possible, there are a few calling
475 restrictions for this service. DisconnectController()
476 must follow these calling restrictions. If any other agent wishes
477 to call Stop() it must also follow these calling restrictions.
479 @param This Protocol instance pointer.
480 @param ControllerHandle Handle of device to stop driver on
481 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
482 children is zero stop the entire bus driver.
483 @param ChildHandleBuffer List of Child Handles to Stop.
485 @retval EFI_SUCCESS This driver is removed ControllerHandle
486 @retval other This driver was not removed from this device
491 PxeBcDriverBindingStop (
492 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
493 IN EFI_HANDLE ControllerHandle
,
494 IN UINTN NumberOfChildren
,
495 IN EFI_HANDLE
*ChildHandleBuffer
498 PXEBC_PRIVATE_DATA
*Private
;
499 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBc
;
500 EFI_HANDLE NicHandle
;
503 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiArpProtocolGuid
);
504 if (NicHandle
== NULL
) {
505 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
507 if (NicHandle
== NULL
) {
508 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
510 if (NicHandle
== NULL
) {
511 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
513 if (NicHandle
== NULL
) {
514 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiMtftp4ProtocolGuid
);
516 if (NicHandle
== NULL
) {
517 return EFI_DEVICE_ERROR
;
524 Status
= gBS
->OpenProtocol (
526 &gEfiPxeBaseCodeProtocolGuid
,
528 This
->DriverBindingHandle
,
530 EFI_OPEN_PROTOCOL_GET_PROTOCOL
533 if (EFI_ERROR (Status
)) {
537 Private
= PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc
);
539 Status
= gBS
->UninstallMultipleProtocolInterfaces (
541 &gEfiPxeBaseCodeProtocolGuid
,
543 &gEfiLoadFileProtocolGuid
,
548 if (!EFI_ERROR (Status
)) {
551 Private
->Udp4WriteChild
,
552 &gEfiUdp4ProtocolGuid
,
553 This
->DriverBindingHandle
,
556 NetLibDestroyServiceChild (
558 This
->DriverBindingHandle
,
559 &gEfiUdp4ServiceBindingProtocolGuid
,
560 Private
->Udp4WriteChild
564 Private
->Udp4ReadChild
,
565 &gEfiUdp4ProtocolGuid
,
566 This
->DriverBindingHandle
,
569 NetLibDestroyServiceChild (
571 This
->DriverBindingHandle
,
572 &gEfiUdp4ServiceBindingProtocolGuid
,
573 Private
->Udp4ReadChild
578 &gEfiDhcp4ProtocolGuid
,
579 This
->DriverBindingHandle
,
582 NetLibDestroyServiceChild (
584 This
->DriverBindingHandle
,
585 &gEfiDhcp4ServiceBindingProtocolGuid
,
590 Private
->Mtftp4Child
,
591 &gEfiMtftp4ProtocolGuid
,
592 This
->DriverBindingHandle
,
595 NetLibDestroyServiceChild (
597 This
->DriverBindingHandle
,
598 &gEfiMtftp4ServiceBindingProtocolGuid
,
604 &gEfiIp4ProtocolGuid
,
605 This
->DriverBindingHandle
,
608 NetLibDestroyServiceChild (
610 This
->DriverBindingHandle
,
611 &gEfiIp4ServiceBindingProtocolGuid
,
617 &gEfiArpProtocolGuid
,
618 This
->DriverBindingHandle
,
621 NetLibDestroyServiceChild (
623 This
->DriverBindingHandle
,
624 &gEfiArpServiceBindingProtocolGuid
,
628 gBS
->FreePool (Private
);