]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
Roll back the DEBUG mask change which cause SerialIo read_conf test item failure.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcDriver.c
1 /** @file
2 The driver binding for UEFI PXEBC protocol.
3
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
9
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.
12
13 **/
14
15
16 #include "PxeBcImpl.h"
17
18 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {
19 PxeBcDriverBindingSupported,
20 PxeBcDriverBindingStart,
21 PxeBcDriverBindingStop,
22 0xa,
23 NULL,
24 NULL
25 };
26
27 /**
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.
31
32 @param ImageHandle The firmware allocated handle for the UEFI image.
33 @param SystemTable A pointer to the EFI System Table.
34
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.
37
38 **/
39 EFI_STATUS
40 PxeBcDriverEntryPoint (
41 IN EFI_HANDLE ImageHandle,
42 IN EFI_SYSTEM_TABLE *SystemTable
43 )
44 {
45 return EfiLibInstallDriverBindingComponentName2 (
46 ImageHandle,
47 SystemTable,
48 &gPxeBcDriverBinding,
49 ImageHandle,
50 &gPxeBcComponentName,
51 &gPxeBcComponentName2
52 );
53 }
54
55
56 /**
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.
64
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
68 device to start.
69
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
73
74 **/
75 EFI_STATUS
76 EFIAPI
77 PxeBcDriverBindingSupported (
78 IN EFI_DRIVER_BINDING_PROTOCOL * This,
79 IN EFI_HANDLE ControllerHandle,
80 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
81 )
82 {
83 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
84 EFI_STATUS Status;
85
86 Status = gBS->OpenProtocol (
87 ControllerHandle,
88 &gEfiPxeBaseCodeProtocolGuid,
89 (VOID **) &PxeBc,
90 This->DriverBindingHandle,
91 ControllerHandle,
92 EFI_OPEN_PROTOCOL_GET_PROTOCOL
93 );
94
95 if (!EFI_ERROR (Status)) {
96 return EFI_ALREADY_STARTED;
97 }
98
99 Status = gBS->OpenProtocol (
100 ControllerHandle,
101 &gEfiDhcp4ServiceBindingProtocolGuid,
102 NULL,
103 This->DriverBindingHandle,
104 ControllerHandle,
105 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
106 );
107
108 if (!EFI_ERROR (Status)) {
109
110 Status = gBS->OpenProtocol (
111 ControllerHandle,
112 &gEfiMtftp4ServiceBindingProtocolGuid,
113 NULL,
114 This->DriverBindingHandle,
115 ControllerHandle,
116 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
117 );
118
119 }
120
121 return Status;
122 }
123
124
125 /**
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.
132
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
136 device to start.
137
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
141
142 **/
143 EFI_STATUS
144 EFIAPI
145 PxeBcDriverBindingStart (
146 IN EFI_DRIVER_BINDING_PROTOCOL * This,
147 IN EFI_HANDLE ControllerHandle,
148 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
149 )
150 {
151 PXEBC_PRIVATE_DATA *Private;
152 UINTN Index;
153 EFI_STATUS Status;
154
155 Private = AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));
156 if (Private == NULL) {
157 return EFI_OUT_OF_RESOURCES;
158 }
159
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));
166
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;
170
171 for (Index = 0; Index < PXEBC_MAX_OFFER_NUM; Index++) {
172 Private->Dhcp4Offers[Index].Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
173 }
174
175 //
176 // Get the NII interface
177 //
178 Status = gBS->OpenProtocol (
179 ControllerHandle,
180 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
181 (VOID **) &Private->Nii,
182 This->DriverBindingHandle,
183 ControllerHandle,
184 EFI_OPEN_PROTOCOL_GET_PROTOCOL
185 );
186 if (EFI_ERROR (Status)) {
187 goto ON_ERROR;
188 }
189
190 Status = NetLibCreateServiceChild (
191 ControllerHandle,
192 This->DriverBindingHandle,
193 &gEfiArpServiceBindingProtocolGuid,
194 &Private->ArpChild
195 );
196 if (EFI_ERROR (Status)) {
197 goto ON_ERROR;
198 }
199
200 Status = gBS->OpenProtocol (
201 Private->ArpChild,
202 &gEfiArpProtocolGuid,
203 (VOID **) &Private->Arp,
204 This->DriverBindingHandle,
205 ControllerHandle,
206 EFI_OPEN_PROTOCOL_BY_DRIVER
207 );
208 if (EFI_ERROR (Status)) {
209 goto ON_ERROR;
210 }
211
212 Status = NetLibCreateServiceChild (
213 ControllerHandle,
214 This->DriverBindingHandle,
215 &gEfiDhcp4ServiceBindingProtocolGuid,
216 &Private->Dhcp4Child
217 );
218 if (EFI_ERROR (Status)) {
219 goto ON_ERROR;
220 }
221
222 Status = gBS->OpenProtocol (
223 Private->Dhcp4Child,
224 &gEfiDhcp4ProtocolGuid,
225 (VOID **) &Private->Dhcp4,
226 This->DriverBindingHandle,
227 ControllerHandle,
228 EFI_OPEN_PROTOCOL_BY_DRIVER
229 );
230 if (EFI_ERROR (Status)) {
231 goto ON_ERROR;
232 }
233
234 Status = NetLibCreateServiceChild (
235 ControllerHandle,
236 This->DriverBindingHandle,
237 &gEfiIp4ServiceBindingProtocolGuid,
238 &Private->Ip4Child
239 );
240 if (EFI_ERROR (Status)) {
241 goto ON_ERROR;
242 }
243
244 Status = gBS->OpenProtocol (
245 Private->Ip4Child,
246 &gEfiIp4ProtocolGuid,
247 (VOID **) &Private->Ip4,
248 This->DriverBindingHandle,
249 ControllerHandle,
250 EFI_OPEN_PROTOCOL_BY_DRIVER
251 );
252 if (EFI_ERROR (Status)) {
253 goto ON_ERROR;
254 }
255
256 Status = NetLibCreateServiceChild (
257 ControllerHandle,
258 This->DriverBindingHandle,
259 &gEfiMtftp4ServiceBindingProtocolGuid,
260 &Private->Mtftp4Child
261 );
262
263 if (EFI_ERROR (Status)) {
264 goto ON_ERROR;
265 }
266
267 Status = gBS->OpenProtocol (
268 Private->Mtftp4Child,
269 &gEfiMtftp4ProtocolGuid,
270 (VOID **) &Private->Mtftp4,
271 This->DriverBindingHandle,
272 ControllerHandle,
273 EFI_OPEN_PROTOCOL_BY_DRIVER
274 );
275
276 if (EFI_ERROR (Status)) {
277 goto ON_ERROR;
278 }
279
280 Status = NetLibCreateServiceChild (
281 ControllerHandle,
282 This->DriverBindingHandle,
283 &gEfiUdp4ServiceBindingProtocolGuid,
284 &Private->Udp4ReadChild
285 );
286
287 if (EFI_ERROR (Status)) {
288 goto ON_ERROR;
289 }
290
291 //
292 // The UDP instance for EfiPxeBcUdpRead
293 //
294 Status = gBS->OpenProtocol (
295 Private->Udp4ReadChild,
296 &gEfiUdp4ProtocolGuid,
297 (VOID **) &Private->Udp4Read,
298 This->DriverBindingHandle,
299 ControllerHandle,
300 EFI_OPEN_PROTOCOL_BY_DRIVER
301 );
302
303 if (EFI_ERROR (Status)) {
304 goto ON_ERROR;
305 }
306
307 //
308 // The UDP instance for EfiPxeBcUdpWrite
309 //
310 Status = NetLibCreateServiceChild (
311 ControllerHandle,
312 This->DriverBindingHandle,
313 &gEfiUdp4ServiceBindingProtocolGuid,
314 &Private->Udp4WriteChild
315 );
316 if (EFI_ERROR (Status)) {
317 goto ON_ERROR;
318 }
319
320 Status = gBS->OpenProtocol (
321 Private->Udp4WriteChild,
322 &gEfiUdp4ProtocolGuid,
323 (VOID **) &Private->Udp4Write,
324 This->DriverBindingHandle,
325 ControllerHandle,
326 EFI_OPEN_PROTOCOL_BY_DRIVER
327 );
328 if (EFI_ERROR (Status)) {
329 goto ON_ERROR;
330 }
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 = 10000; // 10 milliseconds
340 Private->Udp4CfgData.UseDefaultAddress = FALSE;
341
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);
345
346
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;
354
355 Status = gBS->InstallMultipleProtocolInterfaces (
356 &ControllerHandle,
357 &gEfiPxeBaseCodeProtocolGuid,
358 &Private->PxeBc,
359 &gEfiLoadFileProtocolGuid,
360 &Private->LoadFile,
361 NULL
362 );
363 if (EFI_ERROR (Status)) {
364 goto ON_ERROR;
365 }
366
367 return EFI_SUCCESS;
368
369 ON_ERROR:
370
371 if (Private->Udp4WriteChild != NULL) {
372 gBS->CloseProtocol (
373 Private->Udp4WriteChild,
374 &gEfiUdp4ProtocolGuid,
375 This->DriverBindingHandle,
376 ControllerHandle
377 );
378 NetLibDestroyServiceChild (
379 ControllerHandle,
380 This->DriverBindingHandle,
381 &gEfiUdp4ServiceBindingProtocolGuid,
382 Private->Udp4WriteChild
383 );
384 }
385
386 if (Private->Udp4ReadChild != NULL) {
387 gBS->CloseProtocol (
388 Private->Udp4ReadChild,
389 &gEfiUdp4ProtocolGuid,
390 This->DriverBindingHandle,
391 ControllerHandle
392 );
393 NetLibDestroyServiceChild (
394 ControllerHandle,
395 This->DriverBindingHandle,
396 &gEfiUdp4ServiceBindingProtocolGuid,
397 Private->Udp4ReadChild
398 );
399 }
400
401 if (Private->Mtftp4Child != NULL) {
402 gBS->CloseProtocol (
403 Private->Mtftp4Child,
404 &gEfiMtftp4ProtocolGuid,
405 This->DriverBindingHandle,
406 ControllerHandle
407 );
408
409 NetLibDestroyServiceChild (
410 ControllerHandle,
411 This->DriverBindingHandle,
412 &gEfiMtftp4ServiceBindingProtocolGuid,
413 Private->Mtftp4Child
414 );
415 }
416
417 if (Private->Ip4Child != NULL) {
418 gBS->CloseProtocol (
419 Private->Ip4Child,
420 &gEfiIp4ProtocolGuid,
421 This->DriverBindingHandle,
422 ControllerHandle
423 );
424
425 NetLibDestroyServiceChild (
426 ControllerHandle,
427 This->DriverBindingHandle,
428 &gEfiIp4ServiceBindingProtocolGuid,
429 Private->Ip4Child
430 );
431 }
432
433 if (Private->Dhcp4Child != NULL) {
434 gBS->CloseProtocol (
435 Private->Dhcp4Child,
436 &gEfiDhcp4ProtocolGuid,
437 This->DriverBindingHandle,
438 ControllerHandle
439 );
440
441 NetLibDestroyServiceChild (
442 ControllerHandle,
443 This->DriverBindingHandle,
444 &gEfiDhcp4ServiceBindingProtocolGuid,
445 Private->Dhcp4Child
446 );
447 }
448
449 if (Private->ArpChild != NULL) {
450 gBS->CloseProtocol (
451 Private->ArpChild,
452 &gEfiArpProtocolGuid,
453 This->DriverBindingHandle,
454 ControllerHandle
455 );
456
457 NetLibDestroyServiceChild (
458 ControllerHandle,
459 This->DriverBindingHandle,
460 &gEfiArpServiceBindingProtocolGuid,
461 Private->ArpChild
462 );
463 }
464
465 gBS->FreePool (Private);
466
467 return Status;
468 }
469
470
471 /**
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.
478
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.
484
485 @retval EFI_SUCCESS This driver is removed ControllerHandle
486 @retval other This driver was not removed from this device
487
488 **/
489 EFI_STATUS
490 EFIAPI
491 PxeBcDriverBindingStop (
492 IN EFI_DRIVER_BINDING_PROTOCOL *This,
493 IN EFI_HANDLE ControllerHandle,
494 IN UINTN NumberOfChildren,
495 IN EFI_HANDLE *ChildHandleBuffer
496 )
497 {
498 PXEBC_PRIVATE_DATA *Private;
499 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
500 EFI_HANDLE NicHandle;
501 EFI_STATUS Status;
502
503 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
504 if (NicHandle == NULL) {
505 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
506
507 if (NicHandle == NULL) {
508 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
509
510 if (NicHandle == NULL) {
511 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
512
513 if (NicHandle == NULL) {
514 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
515
516 if (NicHandle == NULL) {
517 return EFI_DEVICE_ERROR;
518 }
519 }
520 }
521 }
522 }
523
524 Status = gBS->OpenProtocol (
525 NicHandle,
526 &gEfiPxeBaseCodeProtocolGuid,
527 (VOID **) &PxeBc,
528 This->DriverBindingHandle,
529 ControllerHandle,
530 EFI_OPEN_PROTOCOL_GET_PROTOCOL
531 );
532
533 if (EFI_ERROR (Status)) {
534 return Status;
535 }
536
537 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);
538
539 Status = gBS->UninstallMultipleProtocolInterfaces (
540 NicHandle,
541 &gEfiPxeBaseCodeProtocolGuid,
542 &Private->PxeBc,
543 &gEfiLoadFileProtocolGuid,
544 &Private->LoadFile,
545 NULL
546 );
547
548 if (!EFI_ERROR (Status)) {
549
550 gBS->CloseProtocol (
551 Private->Udp4WriteChild,
552 &gEfiUdp4ProtocolGuid,
553 This->DriverBindingHandle,
554 NicHandle
555 );
556 NetLibDestroyServiceChild (
557 ControllerHandle,
558 This->DriverBindingHandle,
559 &gEfiUdp4ServiceBindingProtocolGuid,
560 Private->Udp4WriteChild
561 );
562
563 gBS->CloseProtocol (
564 Private->Udp4ReadChild,
565 &gEfiUdp4ProtocolGuid,
566 This->DriverBindingHandle,
567 NicHandle
568 );
569 NetLibDestroyServiceChild (
570 NicHandle,
571 This->DriverBindingHandle,
572 &gEfiUdp4ServiceBindingProtocolGuid,
573 Private->Udp4ReadChild
574 );
575
576 gBS->CloseProtocol (
577 Private->Dhcp4Child,
578 &gEfiDhcp4ProtocolGuid,
579 This->DriverBindingHandle,
580 NicHandle
581 );
582 NetLibDestroyServiceChild (
583 NicHandle,
584 This->DriverBindingHandle,
585 &gEfiDhcp4ServiceBindingProtocolGuid,
586 Private->Dhcp4Child
587 );
588
589 gBS->CloseProtocol (
590 Private->Mtftp4Child,
591 &gEfiMtftp4ProtocolGuid,
592 This->DriverBindingHandle,
593 NicHandle
594 );
595 NetLibDestroyServiceChild (
596 NicHandle,
597 This->DriverBindingHandle,
598 &gEfiMtftp4ServiceBindingProtocolGuid,
599 Private->Mtftp4Child
600 );
601
602 gBS->CloseProtocol (
603 Private->Ip4Child,
604 &gEfiIp4ProtocolGuid,
605 This->DriverBindingHandle,
606 NicHandle
607 );
608 NetLibDestroyServiceChild (
609 NicHandle,
610 This->DriverBindingHandle,
611 &gEfiIp4ServiceBindingProtocolGuid,
612 Private->Ip4Child
613 );
614
615 gBS->CloseProtocol (
616 Private->ArpChild,
617 &gEfiArpProtocolGuid,
618 This->DriverBindingHandle,
619 NicHandle
620 );
621 NetLibDestroyServiceChild (
622 NicHandle,
623 This->DriverBindingHandle,
624 &gEfiArpServiceBindingProtocolGuid,
625 Private->ArpChild
626 );
627
628 gBS->FreePool (Private);
629 }
630
631 return Status;
632 }
633
634