]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
sync comments, fix function header, rename variable name to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcDriver.c
1 /** @file
2
3 Copyright (c) 2007 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PxeBcDriver.c
15
16 Abstract:
17
18 The driver binding for IP4 CONFIG protocol.
19
20
21 **/
22
23
24 #include "PxeBcImpl.h"
25
26
27 /**
28 The entry point for PxeBc driver which install the driver
29 binding and component name protocol on its image.
30
31 @param ImageHandle The Image handle of the driver
32 @param SystemTable The system table
33
34 @return EFI_SUCCESS
35 @return Others
36
37 **/
38 EFI_STATUS
39 PxeBcDriverEntryPoint (
40 IN EFI_HANDLE ImageHandle,
41 IN EFI_SYSTEM_TABLE *SystemTable
42 )
43 {
44 return EfiLibInstallDriverBindingComponentName2 (
45 ImageHandle,
46 SystemTable,
47 &gPxeBcDriverBinding,
48 ImageHandle,
49 &gPxeBcComponentName,
50 &gPxeBcComponentName2
51 );
52 }
53
54
55 /**
56 Test to see if this driver supports ControllerHandle.
57
58 @param This Protocol instance pointer.
59 @param ControllerHandle Handle of device to test
60 @param RemainingDevicePath Optional parameter use to pick a specific child
61 device to start.
62
63 @return EFI_SUCCES
64 @return EFI_ALREADY_STARTED
65 @return Others
66
67 **/
68 EFI_STATUS
69 EFIAPI
70 PxeBcDriverBindingSupported (
71 IN EFI_DRIVER_BINDING_PROTOCOL * This,
72 IN EFI_HANDLE ControllerHandle,
73 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
74 )
75 {
76 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
77 EFI_STATUS Status;
78
79 Status = gBS->OpenProtocol (
80 ControllerHandle,
81 &gEfiPxeBaseCodeProtocolGuid,
82 (VOID **) &PxeBc,
83 This->DriverBindingHandle,
84 ControllerHandle,
85 EFI_OPEN_PROTOCOL_GET_PROTOCOL
86 );
87
88 if (!EFI_ERROR (Status)) {
89 return EFI_ALREADY_STARTED;
90 }
91
92 Status = gBS->OpenProtocol (
93 ControllerHandle,
94 &gEfiDhcp4ServiceBindingProtocolGuid,
95 NULL,
96 This->DriverBindingHandle,
97 ControllerHandle,
98 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
99 );
100
101 if (!EFI_ERROR (Status)) {
102
103 Status = gBS->OpenProtocol (
104 ControllerHandle,
105 &gEfiMtftp4ServiceBindingProtocolGuid,
106 NULL,
107 This->DriverBindingHandle,
108 ControllerHandle,
109 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
110 );
111
112 }
113
114 return Status;
115 }
116
117
118 /**
119 Start this driver on ControllerHandle.
120
121 @param This Protocol instance pointer.
122 @param ControllerHandle Handle of device to bind driver to
123 @param RemainingDevicePath Optional parameter use to pick a specific child
124 device to start.
125
126 @return EFI_SUCCES
127 @return EFI_ALREADY_STARTED
128 @return EFI_OUT_OF_RESOURCES
129 @return Others
130
131 **/
132 EFI_STATUS
133 EFIAPI
134 PxeBcDriverBindingStart (
135 IN EFI_DRIVER_BINDING_PROTOCOL * This,
136 IN EFI_HANDLE ControllerHandle,
137 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
138 )
139 {
140 PXEBC_PRIVATE_DATA *Private;
141 UINTN Index;
142 EFI_STATUS Status;
143
144 Private = AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));
145 if (Private == NULL) {
146 return EFI_OUT_OF_RESOURCES;
147 }
148
149 Private->Signature = PXEBC_PRIVATE_DATA_SIGNATURE;
150 Private->Controller = ControllerHandle;
151 Private->Image = This->DriverBindingHandle;
152 CopyMem (&Private->PxeBc, &mPxeBcProtocolTemplate, sizeof (Private->PxeBc));
153 Private->PxeBc.Mode = &Private->Mode;
154 CopyMem (&Private->LoadFile, &mLoadFileProtocolTemplate, sizeof (Private->LoadFile));
155
156 Private->ProxyOffer.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
157 Private->Dhcp4Ack.Packet.Ack.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
158 Private->PxeReply.Packet.Ack.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
159
160 for (Index = 0; Index < PXEBC_MAX_OFFER_NUM; Index++) {
161 Private->Dhcp4Offers[Index].Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
162 }
163
164 //
165 // Get the NII interface
166 //
167 Status = gBS->OpenProtocol (
168 ControllerHandle,
169 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
170 (VOID **) &Private->Nii,
171 This->DriverBindingHandle,
172 ControllerHandle,
173 EFI_OPEN_PROTOCOL_GET_PROTOCOL
174 );
175 if (EFI_ERROR (Status)) {
176 goto ON_ERROR;
177 }
178
179 Status = NetLibCreateServiceChild (
180 ControllerHandle,
181 This->DriverBindingHandle,
182 &gEfiArpServiceBindingProtocolGuid,
183 &Private->ArpChild
184 );
185 if (EFI_ERROR (Status)) {
186 goto ON_ERROR;
187 }
188
189 Status = gBS->OpenProtocol (
190 Private->ArpChild,
191 &gEfiArpProtocolGuid,
192 (VOID **) &Private->Arp,
193 This->DriverBindingHandle,
194 ControllerHandle,
195 EFI_OPEN_PROTOCOL_BY_DRIVER
196 );
197 if (EFI_ERROR (Status)) {
198 goto ON_ERROR;
199 }
200
201 Status = NetLibCreateServiceChild (
202 ControllerHandle,
203 This->DriverBindingHandle,
204 &gEfiDhcp4ServiceBindingProtocolGuid,
205 &Private->Dhcp4Child
206 );
207 if (EFI_ERROR (Status)) {
208 goto ON_ERROR;
209 }
210
211 Status = gBS->OpenProtocol (
212 Private->Dhcp4Child,
213 &gEfiDhcp4ProtocolGuid,
214 (VOID **) &Private->Dhcp4,
215 This->DriverBindingHandle,
216 ControllerHandle,
217 EFI_OPEN_PROTOCOL_BY_DRIVER
218 );
219 if (EFI_ERROR (Status)) {
220 goto ON_ERROR;
221 }
222
223 Status = NetLibCreateServiceChild (
224 ControllerHandle,
225 This->DriverBindingHandle,
226 &gEfiIp4ServiceBindingProtocolGuid,
227 &Private->Ip4Child
228 );
229 if (EFI_ERROR (Status)) {
230 goto ON_ERROR;
231 }
232
233 Status = gBS->OpenProtocol (
234 Private->Ip4Child,
235 &gEfiIp4ProtocolGuid,
236 (VOID **) &Private->Ip4,
237 This->DriverBindingHandle,
238 ControllerHandle,
239 EFI_OPEN_PROTOCOL_BY_DRIVER
240 );
241 if (EFI_ERROR (Status)) {
242 goto ON_ERROR;
243 }
244
245 Status = NetLibCreateServiceChild (
246 ControllerHandle,
247 This->DriverBindingHandle,
248 &gEfiMtftp4ServiceBindingProtocolGuid,
249 &Private->Mtftp4Child
250 );
251
252 if (EFI_ERROR (Status)) {
253 goto ON_ERROR;
254 }
255
256 Status = gBS->OpenProtocol (
257 Private->Mtftp4Child,
258 &gEfiMtftp4ProtocolGuid,
259 (VOID **) &Private->Mtftp4,
260 This->DriverBindingHandle,
261 ControllerHandle,
262 EFI_OPEN_PROTOCOL_BY_DRIVER
263 );
264
265 if (EFI_ERROR (Status)) {
266 goto ON_ERROR;
267 }
268
269 Status = NetLibCreateServiceChild (
270 ControllerHandle,
271 This->DriverBindingHandle,
272 &gEfiUdp4ServiceBindingProtocolGuid,
273 &Private->Udp4ReadChild
274 );
275
276 if (EFI_ERROR (Status)) {
277 goto ON_ERROR;
278 }
279
280 //
281 // The UDP instance for EfiPxeBcUdpRead
282 //
283 Status = gBS->OpenProtocol (
284 Private->Udp4ReadChild,
285 &gEfiUdp4ProtocolGuid,
286 (VOID **) &Private->Udp4Read,
287 This->DriverBindingHandle,
288 ControllerHandle,
289 EFI_OPEN_PROTOCOL_BY_DRIVER
290 );
291
292 if (EFI_ERROR (Status)) {
293 goto ON_ERROR;
294 }
295
296 //
297 // The UDP instance for EfiPxeBcUdpWrite
298 //
299 Status = NetLibCreateServiceChild (
300 ControllerHandle,
301 This->DriverBindingHandle,
302 &gEfiUdp4ServiceBindingProtocolGuid,
303 &Private->Udp4WriteChild
304 );
305 if (EFI_ERROR (Status)) {
306 goto ON_ERROR;
307 }
308
309 Status = gBS->OpenProtocol (
310 Private->Udp4WriteChild,
311 &gEfiUdp4ProtocolGuid,
312 (VOID **) &Private->Udp4Write,
313 This->DriverBindingHandle,
314 ControllerHandle,
315 EFI_OPEN_PROTOCOL_BY_DRIVER
316 );
317 if (EFI_ERROR (Status)) {
318 goto ON_ERROR;
319 }
320 ZeroMem (&Private->Udp4CfgData, sizeof (EFI_UDP4_CONFIG_DATA));
321 Private->Udp4CfgData.AcceptBroadcast = FALSE;
322 Private->Udp4CfgData.AcceptPromiscuous = FALSE;
323 Private->Udp4CfgData.AcceptAnyPort = TRUE;
324 Private->Udp4CfgData.AllowDuplicatePort = TRUE;
325 Private->Udp4CfgData.TypeOfService = DEFAULT_ToS;
326 Private->Udp4CfgData.TimeToLive = DEFAULT_TTL;
327 Private->Udp4CfgData.DoNotFragment = FALSE;
328 Private->Udp4CfgData.ReceiveTimeout = 50000; // 50 milliseconds
329 Private->Udp4CfgData.UseDefaultAddress = FALSE;
330
331 PxeBcInitSeedPacket (&Private->SeedPacket, Private->Udp4Read);
332 Private->MacLen = Private->SeedPacket.Dhcp4.Header.HwAddrLen;
333 CopyMem (&Private->Mac, &Private->SeedPacket.Dhcp4.Header.ClientHwAddr[0], Private->MacLen);
334
335
336 ZeroMem (&Private->Ip4ConfigData, sizeof (EFI_IP4_CONFIG_DATA));
337 Private->Ip4ConfigData.DefaultProtocol = EFI_IP_PROTO_ICMP;
338 Private->Ip4ConfigData.AcceptIcmpErrors = TRUE;
339 Private->Ip4ConfigData.TypeOfService = DEFAULT_ToS;
340 Private->Ip4ConfigData.TimeToLive = DEFAULT_TTL;
341 Private->Ip4ConfigData.DoNotFragment = FALSE;
342 Private->Ip4ConfigData.RawData = FALSE;
343
344 Status = gBS->InstallMultipleProtocolInterfaces (
345 &ControllerHandle,
346 &gEfiPxeBaseCodeProtocolGuid,
347 &Private->PxeBc,
348 &gEfiLoadFileProtocolGuid,
349 &Private->LoadFile,
350 NULL
351 );
352 if (EFI_ERROR (Status)) {
353 goto ON_ERROR;
354 }
355
356 return EFI_SUCCESS;
357
358 ON_ERROR:
359
360 if (Private->Udp4WriteChild != NULL) {
361 gBS->CloseProtocol (
362 Private->Udp4WriteChild,
363 &gEfiUdp4ProtocolGuid,
364 This->DriverBindingHandle,
365 ControllerHandle
366 );
367 NetLibDestroyServiceChild (
368 ControllerHandle,
369 This->DriverBindingHandle,
370 &gEfiUdp4ServiceBindingProtocolGuid,
371 Private->Udp4WriteChild
372 );
373 }
374
375 if (Private->Udp4ReadChild != NULL) {
376 gBS->CloseProtocol (
377 Private->Udp4ReadChild,
378 &gEfiUdp4ProtocolGuid,
379 This->DriverBindingHandle,
380 ControllerHandle
381 );
382 NetLibDestroyServiceChild (
383 ControllerHandle,
384 This->DriverBindingHandle,
385 &gEfiUdp4ServiceBindingProtocolGuid,
386 Private->Udp4ReadChild
387 );
388 }
389
390 if (Private->Mtftp4Child != NULL) {
391 gBS->CloseProtocol (
392 Private->Mtftp4Child,
393 &gEfiMtftp4ProtocolGuid,
394 This->DriverBindingHandle,
395 ControllerHandle
396 );
397
398 NetLibDestroyServiceChild (
399 ControllerHandle,
400 This->DriverBindingHandle,
401 &gEfiMtftp4ServiceBindingProtocolGuid,
402 Private->Mtftp4Child
403 );
404 }
405
406 if (Private->Ip4Child != NULL) {
407 gBS->CloseProtocol (
408 Private->Ip4Child,
409 &gEfiIp4ProtocolGuid,
410 This->DriverBindingHandle,
411 ControllerHandle
412 );
413
414 NetLibDestroyServiceChild (
415 ControllerHandle,
416 This->DriverBindingHandle,
417 &gEfiIp4ServiceBindingProtocolGuid,
418 Private->Ip4Child
419 );
420 }
421
422 if (Private->Dhcp4Child != NULL) {
423 gBS->CloseProtocol (
424 Private->Dhcp4Child,
425 &gEfiDhcp4ProtocolGuid,
426 This->DriverBindingHandle,
427 ControllerHandle
428 );
429
430 NetLibDestroyServiceChild (
431 ControllerHandle,
432 This->DriverBindingHandle,
433 &gEfiDhcp4ServiceBindingProtocolGuid,
434 Private->Dhcp4Child
435 );
436 }
437
438 if (Private->ArpChild != NULL) {
439 gBS->CloseProtocol (
440 Private->ArpChild,
441 &gEfiArpProtocolGuid,
442 This->DriverBindingHandle,
443 ControllerHandle
444 );
445
446 NetLibDestroyServiceChild (
447 ControllerHandle,
448 This->DriverBindingHandle,
449 &gEfiArpServiceBindingProtocolGuid,
450 Private->ArpChild
451 );
452 }
453
454 gBS->FreePool (Private);
455
456 return Status;
457 }
458
459
460 /**
461 Stop this driver on ControllerHandle.
462
463 @param This Protocol instance pointer.
464 @param ControllerHandle Handle of device to stop driver on
465 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
466 children is zero stop the entire bus driver.
467 @param ChildHandleBuffer List of Child Handles to Stop.
468
469 @return EFI_SUCCESS
470 @return EFI_DEVICE_ERROR
471 @return Others
472
473 **/
474 EFI_STATUS
475 EFIAPI
476 PxeBcDriverBindingStop (
477 IN EFI_DRIVER_BINDING_PROTOCOL *This,
478 IN EFI_HANDLE ControllerHandle,
479 IN UINTN NumberOfChildren,
480 IN EFI_HANDLE *ChildHandleBuffer
481 )
482 {
483 PXEBC_PRIVATE_DATA *Private;
484 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
485 EFI_HANDLE NicHandle;
486 EFI_STATUS Status;
487
488 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
489 if (NicHandle == NULL) {
490 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
491
492 if (NicHandle == NULL) {
493 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
494
495 if (NicHandle == NULL) {
496 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
497
498 if (NicHandle == NULL) {
499 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
500
501 if (NicHandle == NULL) {
502 return EFI_DEVICE_ERROR;
503 }
504 }
505 }
506 }
507 }
508
509 Status = gBS->OpenProtocol (
510 NicHandle,
511 &gEfiPxeBaseCodeProtocolGuid,
512 (VOID **) &PxeBc,
513 This->DriverBindingHandle,
514 ControllerHandle,
515 EFI_OPEN_PROTOCOL_GET_PROTOCOL
516 );
517
518 if (EFI_ERROR (Status)) {
519 return Status;
520 }
521
522 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);
523
524 Status = gBS->UninstallMultipleProtocolInterfaces (
525 NicHandle,
526 &gEfiPxeBaseCodeProtocolGuid,
527 &Private->PxeBc,
528 &gEfiLoadFileProtocolGuid,
529 &Private->LoadFile,
530 NULL
531 );
532
533 if (!EFI_ERROR (Status)) {
534
535 gBS->CloseProtocol (
536 Private->Udp4WriteChild,
537 &gEfiUdp4ProtocolGuid,
538 This->DriverBindingHandle,
539 NicHandle
540 );
541 NetLibDestroyServiceChild (
542 ControllerHandle,
543 This->DriverBindingHandle,
544 &gEfiUdp4ServiceBindingProtocolGuid,
545 Private->Udp4WriteChild
546 );
547
548 gBS->CloseProtocol (
549 Private->Udp4ReadChild,
550 &gEfiUdp4ProtocolGuid,
551 This->DriverBindingHandle,
552 NicHandle
553 );
554 NetLibDestroyServiceChild (
555 NicHandle,
556 This->DriverBindingHandle,
557 &gEfiUdp4ServiceBindingProtocolGuid,
558 Private->Udp4ReadChild
559 );
560
561 gBS->CloseProtocol (
562 Private->Dhcp4Child,
563 &gEfiDhcp4ProtocolGuid,
564 This->DriverBindingHandle,
565 NicHandle
566 );
567 NetLibDestroyServiceChild (
568 NicHandle,
569 This->DriverBindingHandle,
570 &gEfiDhcp4ServiceBindingProtocolGuid,
571 Private->Dhcp4Child
572 );
573
574 gBS->CloseProtocol (
575 Private->Mtftp4Child,
576 &gEfiMtftp4ProtocolGuid,
577 This->DriverBindingHandle,
578 NicHandle
579 );
580 NetLibDestroyServiceChild (
581 NicHandle,
582 This->DriverBindingHandle,
583 &gEfiMtftp4ServiceBindingProtocolGuid,
584 Private->Mtftp4Child
585 );
586
587 gBS->CloseProtocol (
588 Private->Ip4Child,
589 &gEfiIp4ProtocolGuid,
590 This->DriverBindingHandle,
591 NicHandle
592 );
593 NetLibDestroyServiceChild (
594 NicHandle,
595 This->DriverBindingHandle,
596 &gEfiIp4ServiceBindingProtocolGuid,
597 Private->Ip4Child
598 );
599
600 gBS->CloseProtocol (
601 Private->ArpChild,
602 &gEfiArpProtocolGuid,
603 This->DriverBindingHandle,
604 NicHandle
605 );
606 NetLibDestroyServiceChild (
607 NicHandle,
608 This->DriverBindingHandle,
609 &gEfiArpServiceBindingProtocolGuid,
610 Private->ArpChild
611 );
612
613 gBS->FreePool (Private);
614 }
615
616 return Status;
617 }
618
619 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {
620 PxeBcDriverBindingSupported,
621 PxeBcDriverBindingStart,
622 PxeBcDriverBindingStop,
623 0xa,
624 NULL,
625 NULL
626 };
627
628