]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
NetworkPkg: Source fixes and cleanup for ARMGCC compiles
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDriver.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 Driver Binding functions implementationfor for UefiPxeBc Driver.\r
3\r
8f586b85 4 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
6879581d 5 Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
a3bcde70
HT
6\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php.\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "PxeBcImpl.h"\r
18\r
19\r
6879581d 20EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp4DriverBinding = {\r
21 PxeBcIp4DriverBindingSupported,\r
22 PxeBcIp4DriverBindingStart,\r
23 PxeBcIp4DriverBindingStop,\r
24 0xa,\r
25 NULL,\r
26 NULL\r
27};\r
28\r
29EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp6DriverBinding = {\r
30 PxeBcIp6DriverBindingSupported,\r
31 PxeBcIp6DriverBindingStart,\r
32 PxeBcIp6DriverBindingStop,\r
a3bcde70
HT
33 0xa,\r
34 NULL,\r
35 NULL\r
36};\r
37\r
a3bcde70
HT
38/**\r
39 Get the Nic handle using any child handle in the IPv4 stack.\r
40\r
41 @param[in] ControllerHandle Pointer to child handle over IPv4.\r
42\r
43 @return NicHandle The pointer to the Nic handle.\r
44\r
45**/\r
46EFI_HANDLE\r
47PxeBcGetNicByIp4Children (\r
48 IN EFI_HANDLE ControllerHandle\r
49 )\r
50{\r
51 EFI_HANDLE NicHandle;\r
52\r
53 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);\r
54 if (NicHandle == NULL) {\r
55 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
56 if (NicHandle == NULL) {\r
57 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);\r
58 if (NicHandle == NULL) {\r
59 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);\r
60 if (NicHandle == NULL) {\r
61 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);\r
62 if (NicHandle == NULL) {\r
63 return NULL;\r
64 }\r
65 }\r
66 }\r
67 }\r
68 }\r
69\r
70 return NicHandle;\r
71}\r
72\r
73\r
74/**\r
75 Get the Nic handle using any child handle in the IPv6 stack.\r
76\r
77 @param[in] ControllerHandle Pointer to child handle over IPv6.\r
78\r
79 @return NicHandle The pointer to the Nic handle.\r
80\r
81**/\r
82EFI_HANDLE\r
83PxeBcGetNicByIp6Children (\r
84 IN EFI_HANDLE ControllerHandle\r
85 )\r
86{\r
87 EFI_HANDLE NicHandle;\r
88\r
89 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);\r
90 if (NicHandle == NULL) {\r
91 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);\r
92 if (NicHandle == NULL) {\r
93 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);\r
94 if (NicHandle == NULL) {\r
95 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp6ProtocolGuid);\r
96 if (NicHandle == NULL) {\r
97 return NULL;\r
98 }\r
99 }\r
100 }\r
101 }\r
102\r
103 return NicHandle;\r
104}\r
105\r
106\r
107/**\r
108 Destroy the opened instances based on IPv4.\r
109\r
110 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.\r
111 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.\r
112\r
113**/\r
114VOID\r
115PxeBcDestroyIp4Children (\r
116 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
117 IN PXEBC_PRIVATE_DATA *Private\r
118 )\r
119{\r
120 ASSERT(Private != NULL);\r
121\r
122 if (Private->ArpChild != NULL) {\r
123 //\r
124 // Close Arp for PxeBc->Arp and destroy the instance.\r
125 //\r
126 gBS->CloseProtocol (\r
127 Private->ArpChild,\r
128 &gEfiArpProtocolGuid,\r
129 This->DriverBindingHandle,\r
130 Private->Controller\r
131 );\r
132\r
133 NetLibDestroyServiceChild (\r
134 Private->Controller,\r
135 This->DriverBindingHandle,\r
136 &gEfiArpServiceBindingProtocolGuid,\r
137 Private->ArpChild\r
138 );\r
139 }\r
140\r
141 if (Private->Ip4Child != NULL) {\r
142 //\r
143 // Close Ip4 for background ICMP error message and destroy the instance.\r
144 //\r
145 gBS->CloseProtocol (\r
146 Private->Ip4Child,\r
147 &gEfiIp4ProtocolGuid,\r
148 This->DriverBindingHandle,\r
149 Private->Controller\r
150 );\r
151\r
152 NetLibDestroyServiceChild (\r
153 Private->Controller,\r
154 This->DriverBindingHandle,\r
155 &gEfiIp4ServiceBindingProtocolGuid,\r
156 Private->Ip4Child\r
157 );\r
158 }\r
159\r
160 if (Private->Udp4WriteChild != NULL) {\r
161 //\r
162 // Close Udp4 for PxeBc->UdpWrite and destroy the instance.\r
163 //\r
164 gBS->CloseProtocol (\r
165 Private->Udp4WriteChild,\r
166 &gEfiUdp4ProtocolGuid,\r
167 This->DriverBindingHandle,\r
168 Private->Controller\r
169 );\r
170\r
171 NetLibDestroyServiceChild (\r
172 Private->Controller,\r
173 This->DriverBindingHandle,\r
174 &gEfiUdp4ServiceBindingProtocolGuid,\r
175 Private->Udp4WriteChild\r
176 );\r
177 }\r
178\r
179 if (Private->Udp4ReadChild != NULL) {\r
180 //\r
181 // Close Udp4 for PxeBc->UdpRead and destroy the instance.\r
182 //\r
183 gBS->CloseProtocol (\r
184 Private->Udp4ReadChild,\r
185 &gEfiUdp4ProtocolGuid,\r
186 This->DriverBindingHandle,\r
187 Private->Controller\r
188 );\r
189\r
190 NetLibDestroyServiceChild (\r
191 Private->Controller,\r
192 This->DriverBindingHandle,\r
193 &gEfiUdp4ServiceBindingProtocolGuid,\r
194 Private->Udp4ReadChild\r
195 );\r
196 }\r
197\r
198 if (Private->Mtftp4Child != NULL) {\r
199 //\r
200 // Close Mtftp4 for PxeBc->Mtftp4 and destroy the instance.\r
201 //\r
202 gBS->CloseProtocol (\r
203 Private->Mtftp4Child,\r
204 &gEfiMtftp4ProtocolGuid,\r
205 This->DriverBindingHandle,\r
206 Private->Controller\r
207 );\r
208\r
209 NetLibDestroyServiceChild (\r
210 Private->Controller,\r
211 This->DriverBindingHandle,\r
212 &gEfiMtftp4ServiceBindingProtocolGuid,\r
213 Private->Mtftp4Child\r
214 );\r
215 }\r
216\r
217 if (Private->Dhcp4Child != NULL) {\r
218 //\r
219 // Close Dhcp4 for PxeBc->Dhcp4 and destroy the instance.\r
220 //\r
221 gBS->CloseProtocol (\r
222 Private->Dhcp4Child,\r
223 &gEfiDhcp4ProtocolGuid,\r
224 This->DriverBindingHandle,\r
225 Private->Controller\r
226 );\r
227\r
228 NetLibDestroyServiceChild (\r
229 Private->Controller,\r
230 This->DriverBindingHandle,\r
231 &gEfiDhcp4ServiceBindingProtocolGuid,\r
232 Private->Dhcp4Child\r
233 );\r
234 }\r
235\r
236 if (Private->Ip4Nic != NULL) {\r
237 //\r
15f3fc85 238 // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.\r
a3bcde70
HT
239 //\r
240 gBS->CloseProtocol (\r
241 Private->Controller,\r
9bdc6592 242 &gEfiCallerIdGuid,\r
a3bcde70
HT
243 This->DriverBindingHandle,\r
244 Private->Ip4Nic->Controller\r
245 );\r
246\r
247 gBS->UninstallMultipleProtocolInterfaces (\r
248 Private->Ip4Nic->Controller,\r
249 &gEfiDevicePathProtocolGuid,\r
250 Private->Ip4Nic->DevicePath,\r
251 &gEfiLoadFileProtocolGuid,\r
252 &Private->Ip4Nic->LoadFile,\r
15f3fc85 253 &gEfiPxeBaseCodeProtocolGuid,\r
254 &Private->PxeBc,\r
a3bcde70
HT
255 NULL\r
256 );\r
15f3fc85 257\r
258 if (Private->Snp != NULL) { \r
259 //\r
260 // Close SNP from the child virtual handle\r
261 //\r
262 gBS->CloseProtocol (\r
263 Private->Ip4Nic->Controller,\r
264 &gEfiSimpleNetworkProtocolGuid,\r
265 This->DriverBindingHandle,\r
266 Private->Ip4Nic->Controller\r
267 );\r
268 \r
269 gBS->UninstallProtocolInterface (\r
270 Private->Ip4Nic->Controller,\r
271 &gEfiSimpleNetworkProtocolGuid,\r
272 Private->Snp\r
273 );\r
274 }\r
a3bcde70
HT
275 FreePool (Private->Ip4Nic);\r
276 }\r
277\r
278 Private->ArpChild = NULL;\r
279 Private->Ip4Child = NULL;\r
280 Private->Udp4WriteChild = NULL;\r
281 Private->Udp4ReadChild = NULL;\r
282 Private->Mtftp4Child = NULL;\r
283 Private->Dhcp4Child = NULL;\r
284 Private->Ip4Nic = NULL;\r
285}\r
286\r
287\r
288/**\r
289 Destroy the opened instances based on IPv6.\r
290\r
291 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.\r
292 @param[in] Private Pointer to PXEBC_PRIVATE_DATA.\r
293\r
294**/\r
295VOID\r
296PxeBcDestroyIp6Children (\r
297 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
298 IN PXEBC_PRIVATE_DATA *Private\r
299 )\r
300{\r
301 ASSERT(Private != NULL);\r
302\r
303 if (Private->Ip6Child != NULL) {\r
304 //\r
305 // Close Ip6 for Ip6->Ip6Config and destroy the instance.\r
306 //\r
307 gBS->CloseProtocol (\r
308 Private->Ip6Child,\r
309 &gEfiIp6ProtocolGuid,\r
310 This->DriverBindingHandle,\r
311 Private->Controller\r
312 );\r
313\r
314 NetLibDestroyServiceChild (\r
315 Private->Controller,\r
316 This->DriverBindingHandle,\r
317 &gEfiIp6ServiceBindingProtocolGuid,\r
318 Private->Ip6Child\r
319 );\r
320 }\r
321\r
322 if (Private->Udp6WriteChild != NULL) {\r
323 //\r
324 // Close Udp6 for PxeBc->UdpWrite and destroy the instance.\r
325 //\r
326 gBS->CloseProtocol (\r
327 Private->Udp6WriteChild,\r
328 &gEfiUdp6ProtocolGuid,\r
329 This->DriverBindingHandle,\r
330 Private->Controller\r
331 );\r
332 NetLibDestroyServiceChild (\r
333 Private->Controller,\r
334 This->DriverBindingHandle,\r
335 &gEfiUdp6ServiceBindingProtocolGuid,\r
336 Private->Udp6WriteChild\r
337 );\r
338 }\r
339\r
340 if (Private->Udp6ReadChild != NULL) {\r
341 //\r
342 // Close Udp6 for PxeBc->UdpRead and destroy the instance.\r
343 //\r
344 gBS->CloseProtocol (\r
345 Private->Udp6ReadChild,\r
346 &gEfiUdp6ProtocolGuid,\r
347 This->DriverBindingHandle,\r
348 Private->Controller\r
349 );\r
350 NetLibDestroyServiceChild (\r
351 Private->Controller,\r
352 This->DriverBindingHandle,\r
353 &gEfiUdp6ServiceBindingProtocolGuid,\r
354 Private->Udp6ReadChild\r
355 );\r
356 }\r
357\r
358 if (Private->Mtftp6Child != NULL) {\r
359 //\r
360 // Close Mtftp6 for PxeBc->Mtftp and destroy the instance.\r
361 //\r
362 gBS->CloseProtocol (\r
363 Private->Mtftp6Child,\r
364 &gEfiMtftp6ProtocolGuid,\r
365 This->DriverBindingHandle,\r
366 Private->Controller\r
367 );\r
368\r
369 NetLibDestroyServiceChild (\r
370 Private->Controller,\r
371 This->DriverBindingHandle,\r
372 &gEfiMtftp6ServiceBindingProtocolGuid,\r
373 Private->Mtftp6Child\r
374 );\r
375 }\r
376\r
377 if (Private->Dhcp6Child != NULL) {\r
378 //\r
379 // Close Dhcp6 for PxeBc->Dhcp and destroy the instance.\r
380 //\r
381 gBS->CloseProtocol (\r
382 Private->Dhcp6Child,\r
383 &gEfiDhcp6ProtocolGuid,\r
384 This->DriverBindingHandle,\r
385 Private->Controller\r
386 );\r
387\r
388 NetLibDestroyServiceChild (\r
389 Private->Controller,\r
390 This->DriverBindingHandle,\r
391 &gEfiDhcp6ServiceBindingProtocolGuid,\r
392 Private->Dhcp6Child\r
393 );\r
394 }\r
395\r
396 if (Private->Ip6Nic != NULL) {\r
397 //\r
15f3fc85 398 // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.\r
a3bcde70
HT
399 //\r
400 gBS->CloseProtocol (\r
401 Private->Controller,\r
9bdc6592 402 &gEfiCallerIdGuid,\r
a3bcde70
HT
403 This->DriverBindingHandle,\r
404 Private->Ip6Nic->Controller\r
405 );\r
15f3fc85 406\r
a3bcde70
HT
407 gBS->UninstallMultipleProtocolInterfaces (\r
408 Private->Ip6Nic->Controller,\r
409 &gEfiDevicePathProtocolGuid,\r
410 Private->Ip6Nic->DevicePath,\r
411 &gEfiLoadFileProtocolGuid,\r
412 &Private->Ip6Nic->LoadFile,\r
15f3fc85 413 &gEfiPxeBaseCodeProtocolGuid,\r
414 &Private->PxeBc,\r
a3bcde70
HT
415 NULL\r
416 );\r
15f3fc85 417 if (Private->Snp != NULL) {\r
418 //\r
419 // Close SNP from the child virtual handle\r
420 //\r
421 gBS->CloseProtocol (\r
422 Private->Ip6Nic->Controller,\r
423 &gEfiSimpleNetworkProtocolGuid,\r
424 This->DriverBindingHandle,\r
425 Private->Ip6Nic->Controller\r
426 );\r
427 gBS->UninstallProtocolInterface (\r
428 Private->Ip6Nic->Controller,\r
429 &gEfiSimpleNetworkProtocolGuid,\r
430 Private->Snp\r
431 );\r
432 }\r
a3bcde70
HT
433 FreePool (Private->Ip6Nic);\r
434 }\r
435\r
436 Private->Ip6Child = NULL;\r
437 Private->Udp6WriteChild = NULL;\r
438 Private->Udp6ReadChild = NULL;\r
439 Private->Mtftp6Child = NULL;\r
440 Private->Dhcp6Child = NULL;\r
441 Private->Ip6Nic = NULL;\r
442 Private->Mode.Ipv6Available = FALSE;\r
443}\r
444\r
445\r
446/**\r
447 Create the opened instances based on IPv4.\r
448\r
449 @param[in] This Pointer to EFI_DRIVER_BINDING_PROTOCOL.\r
450 @param[in] ControllerHandle Handle of the child to destroy.\r
451 @param[in] Private Handle Pointer to PXEBC_PRIVATE_DATA.\r
452\r
453 @retval EFI_SUCCESS The instances based on IPv4 were all created successfully.\r
454 @retval Others An unexpected error occurred.\r
455\r
456**/\r
457EFI_STATUS\r
458PxeBcCreateIp4Children (\r
459 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
460 IN EFI_HANDLE ControllerHandle,\r
461 IN PXEBC_PRIVATE_DATA *Private\r
462 )\r
463{\r
464 EFI_STATUS Status;\r
465 IPv4_DEVICE_PATH Ip4Node;\r
a3bcde70
HT
466 EFI_PXE_BASE_CODE_MODE *Mode;\r
467 EFI_UDP4_CONFIG_DATA *Udp4CfgData;\r
468 EFI_IP4_CONFIG_DATA *Ip4CfgData;\r
469 EFI_IP4_MODE_DATA Ip4ModeData;\r
15f3fc85 470 PXEBC_PRIVATE_PROTOCOL *Id;\r
471 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
a3bcde70
HT
472\r
473 if (Private->Ip4Nic != NULL) {\r
474 //\r
475 // Already created before.\r
476 //\r
477 return EFI_SUCCESS;\r
478 }\r
479\r
480 //\r
481 // Create Dhcp4 child and open Dhcp4 protocol for PxeBc->Dhcp.\r
482 //\r
483 Status = NetLibCreateServiceChild (\r
484 ControllerHandle,\r
485 This->DriverBindingHandle,\r
486 &gEfiDhcp4ServiceBindingProtocolGuid,\r
487 &Private->Dhcp4Child\r
488 );\r
489 if (EFI_ERROR (Status)) {\r
490 goto ON_ERROR;\r
491 }\r
492\r
493 Status = gBS->OpenProtocol (\r
494 Private->Dhcp4Child,\r
495 &gEfiDhcp4ProtocolGuid,\r
496 (VOID **) &Private->Dhcp4,\r
497 This->DriverBindingHandle,\r
498 ControllerHandle,\r
499 EFI_OPEN_PROTOCOL_BY_DRIVER\r
500 );\r
501 if (EFI_ERROR (Status)) {\r
502 goto ON_ERROR;\r
503 }\r
504\r
505 //\r
506 // Create Mtftp4 child and open Mtftp4 protocol for PxeBc->Mtftp.\r
507 //\r
508 Status = NetLibCreateServiceChild (\r
509 ControllerHandle,\r
510 This->DriverBindingHandle,\r
511 &gEfiMtftp4ServiceBindingProtocolGuid,\r
512 &Private->Mtftp4Child\r
513 );\r
514 if (EFI_ERROR (Status)) {\r
515 goto ON_ERROR;\r
516 }\r
517\r
518 Status = gBS->OpenProtocol (\r
519 Private->Mtftp4Child,\r
520 &gEfiMtftp4ProtocolGuid,\r
521 (VOID **) &Private->Mtftp4,\r
522 This->DriverBindingHandle,\r
523 ControllerHandle,\r
524 EFI_OPEN_PROTOCOL_BY_DRIVER\r
525 );\r
526 if (EFI_ERROR (Status)) {\r
527 goto ON_ERROR;\r
528 }\r
529\r
530 //\r
531 // Create Udp4 child and open Udp4 protocol for PxeBc->UdpRead.\r
532 //\r
533 Status = NetLibCreateServiceChild (\r
534 ControllerHandle,\r
535 This->DriverBindingHandle,\r
536 &gEfiUdp4ServiceBindingProtocolGuid,\r
537 &Private->Udp4ReadChild\r
538 );\r
539 if (EFI_ERROR (Status)) {\r
540 goto ON_ERROR;\r
541 }\r
542\r
543 Status = gBS->OpenProtocol (\r
544 Private->Udp4ReadChild,\r
545 &gEfiUdp4ProtocolGuid,\r
546 (VOID **) &Private->Udp4Read,\r
547 This->DriverBindingHandle,\r
548 ControllerHandle,\r
549 EFI_OPEN_PROTOCOL_BY_DRIVER\r
550 );\r
551 if (EFI_ERROR (Status)) {\r
552 goto ON_ERROR;\r
553 }\r
554\r
555 //\r
556 // Create Udp4 child and open Udp4 protocol for PxeBc->UdpWrite.\r
557 //\r
558 Status = NetLibCreateServiceChild (\r
559 ControllerHandle,\r
560 This->DriverBindingHandle,\r
561 &gEfiUdp4ServiceBindingProtocolGuid,\r
562 &Private->Udp4WriteChild\r
563 );\r
564 if (EFI_ERROR (Status)) {\r
565 goto ON_ERROR;\r
566 }\r
567\r
568 Status = gBS->OpenProtocol (\r
569 Private->Udp4WriteChild,\r
570 &gEfiUdp4ProtocolGuid,\r
571 (VOID **) &Private->Udp4Write,\r
572 This->DriverBindingHandle,\r
573 ControllerHandle,\r
574 EFI_OPEN_PROTOCOL_BY_DRIVER\r
575 );\r
576 if (EFI_ERROR (Status)) {\r
577 goto ON_ERROR;\r
578 }\r
579\r
580 //\r
581 // Create Arp child and open Arp protocol for PxeBc->Arp.\r
582 //\r
583 Status = NetLibCreateServiceChild (\r
584 ControllerHandle,\r
585 This->DriverBindingHandle,\r
586 &gEfiArpServiceBindingProtocolGuid,\r
587 &Private->ArpChild\r
588 );\r
589 if (EFI_ERROR (Status)) {\r
590 goto ON_ERROR;\r
591 }\r
592\r
593 Status = gBS->OpenProtocol (\r
594 Private->ArpChild,\r
595 &gEfiArpProtocolGuid,\r
596 (VOID **) &Private->Arp,\r
597 This->DriverBindingHandle,\r
598 ControllerHandle,\r
599 EFI_OPEN_PROTOCOL_BY_DRIVER\r
600 );\r
601 if (EFI_ERROR (Status)) {\r
602 goto ON_ERROR;\r
603 }\r
604\r
605 //\r
606 // Create Ip4 child and open Ip4 protocol for background ICMP packets.\r
607 //\r
608 Status = NetLibCreateServiceChild (\r
609 ControllerHandle,\r
610 This->DriverBindingHandle,\r
611 &gEfiIp4ServiceBindingProtocolGuid,\r
612 &Private->Ip4Child\r
613 );\r
614 if (EFI_ERROR (Status)) {\r
615 goto ON_ERROR;\r
616 }\r
617\r
618 Status = gBS->OpenProtocol (\r
619 Private->Ip4Child,\r
620 &gEfiIp4ProtocolGuid,\r
621 (VOID **) &Private->Ip4,\r
622 This->DriverBindingHandle,\r
623 ControllerHandle,\r
624 EFI_OPEN_PROTOCOL_BY_DRIVER\r
625 );\r
626 if (EFI_ERROR (Status)) {\r
627 goto ON_ERROR;\r
628 }\r
629\r
630 //\r
631 // Get max packet size from Ip4 to calculate block size for Tftp later.\r
632 //\r
633 Status = Private->Ip4->GetModeData (Private->Ip4, &Ip4ModeData, NULL, NULL);\r
634 if (EFI_ERROR (Status)) {\r
635 goto ON_ERROR;\r
636 }\r
637\r
638 Private->Ip4MaxPacketSize = Ip4ModeData.MaxPacketSize;\r
639\r
640 Private->Ip4Nic = AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC));\r
641 if (Private->Ip4Nic == NULL) {\r
642 return EFI_OUT_OF_RESOURCES;\r
643 }\r
644\r
645 Private->Ip4Nic->Private = Private;\r
646 Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;\r
647\r
648 //\r
649 // Create a device path node for Ipv4 virtual nic, and append it.\r
650 //\r
651 ZeroMem (&Ip4Node, sizeof (IPv4_DEVICE_PATH));\r
652 Ip4Node.Header.Type = MESSAGING_DEVICE_PATH;\r
653 Ip4Node.Header.SubType = MSG_IPv4_DP;\r
654 Ip4Node.StaticIpAddress = FALSE;\r
655\r
656 SetDevicePathNodeLength (&Ip4Node.Header, sizeof (Ip4Node));\r
657\r
658 Private->Ip4Nic->DevicePath = AppendDevicePathNode (Private->DevicePath, &Ip4Node.Header);\r
659\r
660 if (Private->Ip4Nic->DevicePath == NULL) {\r
661 Status = EFI_OUT_OF_RESOURCES;\r
662 goto ON_ERROR;\r
663 }\r
664\r
665 CopyMem (\r
666 &Private->Ip4Nic->LoadFile,\r
667 &gLoadFileProtocolTemplate,\r
668 sizeof (EFI_LOAD_FILE_PROTOCOL)\r
669 );\r
670\r
671 //\r
672 // Create a new handle for IPv4 virtual nic,\r
673 // and install PxeBaseCode, LoadFile and DevicePath protocols.\r
674 //\r
675 Status = gBS->InstallMultipleProtocolInterfaces (\r
676 &Private->Ip4Nic->Controller,\r
677 &gEfiDevicePathProtocolGuid,\r
678 Private->Ip4Nic->DevicePath,\r
679 &gEfiLoadFileProtocolGuid,\r
680 &Private->Ip4Nic->LoadFile,\r
15f3fc85 681 &gEfiPxeBaseCodeProtocolGuid,\r
682 &Private->PxeBc,\r
a3bcde70
HT
683 NULL\r
684 );\r
685 if (EFI_ERROR (Status)) {\r
686 goto ON_ERROR;\r
687 }\r
688\r
15f3fc85 689 if (Private->Snp != NULL) {\r
690 //\r
691 // Install SNP protocol on purpose is for some OS loader backward\r
692 // compatibility consideration.\r
693 //\r
694 Status = gBS->InstallProtocolInterface (\r
695 &Private->Ip4Nic->Controller,\r
696 &gEfiSimpleNetworkProtocolGuid,\r
697 EFI_NATIVE_INTERFACE,\r
698 Private->Snp\r
699 );\r
700 if (EFI_ERROR (Status)) {\r
701 goto ON_ERROR;\r
702 }\r
703\r
704 //\r
705 // Open SNP on the child handle BY_DRIVER. It will prevent any additionally \r
706 // layering to perform the experiment.\r
707 //\r
708 Status = gBS->OpenProtocol (\r
709 Private->Ip4Nic->Controller,\r
710 &gEfiSimpleNetworkProtocolGuid,\r
711 (VOID **) &Snp,\r
712 This->DriverBindingHandle,\r
713 Private->Ip4Nic->Controller,\r
714 EFI_OPEN_PROTOCOL_BY_DRIVER\r
715 );\r
716 if (EFI_ERROR (Status)) {\r
717 goto ON_ERROR;\r
718 }\r
719 }\r
720\r
a3bcde70 721 //\r
15f3fc85 722 // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between\r
a3bcde70
HT
723 // real NIC handle and the virtual IPv4 NIC handle.\r
724 //\r
725 Status = gBS->OpenProtocol (\r
726 ControllerHandle,\r
9bdc6592 727 &gEfiCallerIdGuid,\r
15f3fc85 728 (VOID **) &Id,\r
a3bcde70
HT
729 This->DriverBindingHandle,\r
730 Private->Ip4Nic->Controller,\r
731 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
732 );\r
733 if (EFI_ERROR (Status)) {\r
734 goto ON_ERROR;\r
735 }\r
736\r
737 //\r
738 // Set default configure data for Udp4Read and Ip4 instance.\r
739 //\r
15f3fc85 740 Mode = Private->PxeBc.Mode;\r
a3bcde70
HT
741 Udp4CfgData = &Private->Udp4CfgData;\r
742 Ip4CfgData = &Private->Ip4CfgData;\r
743\r
18127352 744 Udp4CfgData->AcceptBroadcast = FALSE;\r
a3bcde70
HT
745 Udp4CfgData->AcceptAnyPort = TRUE;\r
746 Udp4CfgData->AllowDuplicatePort = TRUE;\r
747 Udp4CfgData->TypeOfService = Mode->ToS;\r
748 Udp4CfgData->TimeToLive = Mode->TTL;\r
749 Udp4CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;\r
750 Udp4CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;\r
751\r
752 Ip4CfgData->AcceptIcmpErrors = TRUE;\r
753 Ip4CfgData->DefaultProtocol = EFI_IP_PROTO_ICMP;\r
754 Ip4CfgData->TypeOfService = Mode->ToS;\r
755 Ip4CfgData->TimeToLive = Mode->TTL;\r
756 Ip4CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;\r
757 Ip4CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;\r
758\r
759 return EFI_SUCCESS;\r
760\r
761ON_ERROR:\r
762 PxeBcDestroyIp4Children (This, Private);\r
763 return Status;\r
764}\r
765\r
766\r
767/**\r
768 Create the opened instances based on IPv6.\r
769\r
770 @param[in] This Pointer to EFI_DRIVER_BINDING_PROTOCOL.\r
771 @param[in] ControllerHandle Handle of the child to destroy.\r
772 @param[in] Private Handle Pointer to PXEBC_PRIVATE_DATA.\r
773\r
774 @retval EFI_SUCCESS The instances based on IPv6 were all created successfully.\r
775 @retval Others An unexpected error occurred.\r
776\r
777**/\r
778EFI_STATUS\r
779PxeBcCreateIp6Children (\r
780 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
781 IN EFI_HANDLE ControllerHandle,\r
782 IN PXEBC_PRIVATE_DATA *Private\r
783 )\r
784{\r
785 EFI_STATUS Status;\r
786 IPv6_DEVICE_PATH Ip6Node;\r
a3bcde70
HT
787 EFI_UDP6_CONFIG_DATA *Udp6CfgData;\r
788 EFI_IP6_CONFIG_DATA *Ip6CfgData;\r
789 EFI_IP6_MODE_DATA Ip6ModeData;\r
15f3fc85 790 PXEBC_PRIVATE_PROTOCOL *Id;\r
791 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
75dce340 792 UINTN Index;\r
a3bcde70
HT
793\r
794 if (Private->Ip6Nic != NULL) {\r
795 //\r
796 // Already created before.\r
797 //\r
798 return EFI_SUCCESS;\r
799 }\r
800\r
801 Private->Ip6Nic = AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC));\r
802\r
803 if (Private->Ip6Nic == NULL) {\r
804 return EFI_OUT_OF_RESOURCES;\r
805 }\r
806\r
807 Private->Ip6Nic->Private = Private;\r
808 Private->Ip6Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;\r
809\r
810 //\r
811 // Create Dhcp6 child and open Dhcp6 protocol for PxeBc->Dhcp.\r
812 //\r
813 Status = NetLibCreateServiceChild (\r
814 ControllerHandle,\r
815 This->DriverBindingHandle,\r
816 &gEfiDhcp6ServiceBindingProtocolGuid,\r
817 &Private->Dhcp6Child\r
818 );\r
819 if (EFI_ERROR (Status)) {\r
820 goto ON_ERROR;\r
821 }\r
822\r
823 Status = gBS->OpenProtocol (\r
824 Private->Dhcp6Child,\r
825 &gEfiDhcp6ProtocolGuid,\r
826 (VOID **) &Private->Dhcp6,\r
827 This->DriverBindingHandle,\r
828 ControllerHandle,\r
829 EFI_OPEN_PROTOCOL_BY_DRIVER\r
830 );\r
831 if (EFI_ERROR (Status)) {\r
832 goto ON_ERROR;\r
833 }\r
834\r
75dce340 835 //\r
836 // Generate a random IAID for the Dhcp6 assigned address.\r
837 //\r
838 Private->IaId = NET_RANDOM (NetRandomInitSeed ());\r
839 if (Private->Snp != NULL) {\r
840 for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) {\r
841 Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31));\r
842 } \r
843 }\r
844\r
a3bcde70
HT
845 //\r
846 // Create Mtftp6 child and open Mtftp6 protocol for PxeBc->Mtftp.\r
847 //\r
848 Status = NetLibCreateServiceChild (\r
849 ControllerHandle,\r
850 This->DriverBindingHandle,\r
851 &gEfiMtftp6ServiceBindingProtocolGuid,\r
852 &Private->Mtftp6Child\r
853 );\r
854 if (EFI_ERROR (Status)) {\r
855 goto ON_ERROR;\r
856 }\r
857\r
858 Status = gBS->OpenProtocol (\r
859 Private->Mtftp6Child,\r
860 &gEfiMtftp6ProtocolGuid,\r
861 (VOID **) &Private->Mtftp6,\r
862 This->DriverBindingHandle,\r
863 ControllerHandle,\r
864 EFI_OPEN_PROTOCOL_BY_DRIVER\r
865 );\r
866 if (EFI_ERROR (Status)) {\r
867 goto ON_ERROR;\r
868 }\r
869\r
870 //\r
871 // Create Udp6 child and open Udp6 protocol for PxeBc->UdpRead.\r
872 //\r
873 Status = NetLibCreateServiceChild (\r
874 ControllerHandle,\r
875 This->DriverBindingHandle,\r
876 &gEfiUdp6ServiceBindingProtocolGuid,\r
877 &Private->Udp6ReadChild\r
878 );\r
879 if (EFI_ERROR (Status)) {\r
880 goto ON_ERROR;\r
881 }\r
882\r
883 Status = gBS->OpenProtocol (\r
884 Private->Udp6ReadChild,\r
885 &gEfiUdp6ProtocolGuid,\r
886 (VOID **) &Private->Udp6Read,\r
887 This->DriverBindingHandle,\r
888 ControllerHandle,\r
889 EFI_OPEN_PROTOCOL_BY_DRIVER\r
890 );\r
891 if (EFI_ERROR (Status)) {\r
892 goto ON_ERROR;\r
893 }\r
894\r
895 //\r
896 // Create Udp6 child and open Udp6 protocol for PxeBc->UdpWrite.\r
897 //\r
898 Status = NetLibCreateServiceChild (\r
899 ControllerHandle,\r
900 This->DriverBindingHandle,\r
901 &gEfiUdp6ServiceBindingProtocolGuid,\r
902 &Private->Udp6WriteChild\r
903 );\r
904 if (EFI_ERROR (Status)) {\r
905 goto ON_ERROR;\r
906 }\r
907\r
908 Status = gBS->OpenProtocol (\r
909 Private->Udp6WriteChild,\r
910 &gEfiUdp6ProtocolGuid,\r
911 (VOID **) &Private->Udp6Write,\r
912 This->DriverBindingHandle,\r
913 ControllerHandle,\r
914 EFI_OPEN_PROTOCOL_BY_DRIVER\r
915 );\r
916 if (EFI_ERROR (Status)) {\r
917 goto ON_ERROR;\r
918 }\r
919\r
920 //\r
921 // Create Ip6 child and open Ip6 protocol for background ICMP6 packets.\r
922 //\r
923 Status = NetLibCreateServiceChild (\r
924 ControllerHandle,\r
925 This->DriverBindingHandle,\r
926 &gEfiIp6ServiceBindingProtocolGuid,\r
927 &Private->Ip6Child\r
928 );\r
929 if (EFI_ERROR (Status)) {\r
930 goto ON_ERROR;\r
931 }\r
932\r
933 Status = gBS->OpenProtocol (\r
934 Private->Ip6Child,\r
935 &gEfiIp6ProtocolGuid,\r
936 (VOID **) &Private->Ip6,\r
937 This->DriverBindingHandle,\r
938 ControllerHandle,\r
939 EFI_OPEN_PROTOCOL_BY_DRIVER\r
940 );\r
941 if (EFI_ERROR (Status)) {\r
942 goto ON_ERROR;\r
943 }\r
944\r
945 //\r
946 // Get max packet size from Ip6 to calculate block size for Tftp later.\r
947 //\r
948 Status = Private->Ip6->GetModeData (Private->Ip6, &Ip6ModeData, NULL, NULL);\r
949 if (EFI_ERROR (Status)) {\r
950 goto ON_ERROR;\r
951 }\r
952\r
953 Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize;\r
954\r
955 //\r
956 // Locate Ip6->Ip6Config and store it for set IPv6 address.\r
957 //\r
958 Status = gBS->HandleProtocol (\r
959 ControllerHandle,\r
960 &gEfiIp6ConfigProtocolGuid,\r
961 (VOID **) &Private->Ip6Cfg\r
962 );\r
963 if (EFI_ERROR (Status)) {\r
964 goto ON_ERROR;\r
965 }\r
966\r
967 //\r
968 // Create a device path node for Ipv6 virtual nic, and append it.\r
969 //\r
970 ZeroMem (&Ip6Node, sizeof (IPv6_DEVICE_PATH));\r
971 Ip6Node.Header.Type = MESSAGING_DEVICE_PATH;\r
972 Ip6Node.Header.SubType = MSG_IPv6_DP;\r
501793fa 973 Ip6Node.PrefixLength = IP6_PREFIX_LENGTH;\r
a3bcde70
HT
974\r
975 SetDevicePathNodeLength (&Ip6Node.Header, sizeof (Ip6Node));\r
976\r
977 Private->Ip6Nic->DevicePath = AppendDevicePathNode (Private->DevicePath, &Ip6Node.Header);\r
978\r
979 if (Private->Ip6Nic->DevicePath == NULL) {\r
980 Status = EFI_OUT_OF_RESOURCES;\r
981 goto ON_ERROR;\r
982 }\r
983\r
984 CopyMem (\r
985 &Private->Ip6Nic->LoadFile,\r
986 &gLoadFileProtocolTemplate,\r
987 sizeof (EFI_LOAD_FILE_PROTOCOL)\r
988 );\r
989\r
990 //\r
991 // Create a new handle for IPv6 virtual nic,\r
992 // and install PxeBaseCode, LoadFile and DevicePath protocols.\r
993 //\r
994 Status = gBS->InstallMultipleProtocolInterfaces (\r
995 &Private->Ip6Nic->Controller,\r
996 &gEfiDevicePathProtocolGuid,\r
997 Private->Ip6Nic->DevicePath,\r
998 &gEfiLoadFileProtocolGuid,\r
999 &Private->Ip6Nic->LoadFile,\r
15f3fc85 1000 &gEfiPxeBaseCodeProtocolGuid,\r
1001 &Private->PxeBc,\r
a3bcde70
HT
1002 NULL\r
1003 );\r
1004 if (EFI_ERROR (Status)) {\r
1005 goto ON_ERROR;\r
1006 }\r
15f3fc85 1007 \r
1008 if (Private->Snp != NULL) {\r
1009 //\r
1010 // Install SNP protocol on purpose is for some OS loader backward\r
1011 // compatibility consideration.\r
1012 //\r
1013 Status = gBS->InstallProtocolInterface (\r
1014 &Private->Ip6Nic->Controller,\r
1015 &gEfiSimpleNetworkProtocolGuid,\r
1016 EFI_NATIVE_INTERFACE,\r
1017 Private->Snp\r
1018 );\r
1019 if (EFI_ERROR (Status)) {\r
1020 goto ON_ERROR;\r
1021 }\r
1022\r
1023 //\r
1024 // Open SNP on the child handle BY_DRIVER. It will prevent any additionally \r
1025 // layering to perform the experiment.\r
1026 //\r
1027 Status = gBS->OpenProtocol (\r
1028 Private->Ip6Nic->Controller,\r
1029 &gEfiSimpleNetworkProtocolGuid,\r
1030 (VOID **) &Snp,\r
1031 This->DriverBindingHandle,\r
1032 Private->Ip6Nic->Controller,\r
1033 EFI_OPEN_PROTOCOL_BY_DRIVER\r
1034 );\r
1035 if (EFI_ERROR (Status)) {\r
1036 goto ON_ERROR;\r
1037 }\r
1038 }\r
a3bcde70
HT
1039\r
1040 //\r
15f3fc85 1041 // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between\r
a3bcde70
HT
1042 // real NIC handle and the virtual IPv6 NIC handle.\r
1043 //\r
1044 Status = gBS->OpenProtocol (\r
1045 ControllerHandle,\r
9bdc6592 1046 &gEfiCallerIdGuid,\r
15f3fc85 1047 (VOID **) &Id,\r
a3bcde70
HT
1048 This->DriverBindingHandle,\r
1049 Private->Ip6Nic->Controller,\r
1050 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1051 );\r
1052 if (EFI_ERROR (Status)) {\r
1053 goto ON_ERROR;\r
1054 }\r
1055\r
1056 //\r
1057 // Set IPv6 avaiable flag and set default configure data for\r
1058 // Udp6Read and Ip6 instance.\r
1059 //\r
1060 Private->Mode.Ipv6Available = TRUE;\r
1061 Udp6CfgData = &Private->Udp6CfgData;\r
1062 Ip6CfgData = &Private->Ip6CfgData;\r
1063\r
1064 Udp6CfgData->AcceptAnyPort = TRUE;\r
1065 Udp6CfgData->AllowDuplicatePort = TRUE;\r
1066 Udp6CfgData->HopLimit = PXEBC_DEFAULT_HOPLIMIT;\r
1067 Udp6CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;\r
1068 Udp6CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;\r
1069\r
1070 Ip6CfgData->AcceptIcmpErrors = TRUE;\r
1071 Ip6CfgData->DefaultProtocol = IP6_ICMP;\r
1072 Ip6CfgData->HopLimit = PXEBC_DEFAULT_HOPLIMIT;\r
1073 Ip6CfgData->ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;\r
1074 Ip6CfgData->TransmitTimeout = PXEBC_DEFAULT_LIFETIME;\r
1075\r
1076 return EFI_SUCCESS;\r
1077\r
1078ON_ERROR:\r
1079 PxeBcDestroyIp6Children (This, Private);\r
1080 return Status;\r
1081}\r
1082\r
1083\r
1084/**\r
1085 The entry point for UefiPxeBc driver that installs the driver\r
1086 binding and component name protocol on its image.\r
1087\r
1088 @param[in] ImageHandle The Image handle of the driver.\r
1089 @param[in] SystemTable The system table.\r
1090\r
1091 @return EFI_SUCCESS\r
1092 @return Others\r
1093\r
1094**/\r
1095EFI_STATUS\r
1096EFIAPI\r
1097PxeBcDriverEntryPoint (\r
1098 IN EFI_HANDLE ImageHandle,\r
1099 IN EFI_SYSTEM_TABLE *SystemTable\r
1100 )\r
1101{\r
6879581d 1102 EFI_STATUS Status;\r
1103\r
1104 Status = EfiLibInstallDriverBindingComponentName2 (\r
1105 ImageHandle,\r
1106 SystemTable,\r
1107 &gPxeBcIp4DriverBinding,\r
1108 ImageHandle,\r
1109 &gPxeBcComponentName,\r
1110 &gPxeBcComponentName2\r
1111 );\r
1112 if (EFI_ERROR (Status)) {\r
1113 return Status;\r
1114 }\r
1115\r
1116 Status = EfiLibInstallDriverBindingComponentName2 (\r
1117 ImageHandle,\r
1118 SystemTable,\r
1119 &gPxeBcIp6DriverBinding,\r
1120 NULL,\r
1121 &gPxeBcComponentName,\r
1122 &gPxeBcComponentName2\r
1123 );\r
1124 if (EFI_ERROR (Status)) {\r
1125 gBS->UninstallMultipleProtocolInterfaces (\r
a3bcde70 1126 ImageHandle,\r
6879581d 1127 &gEfiDriverBindingProtocolGuid,\r
1128 &gPxeBcIp4DriverBinding,\r
1129 &gEfiComponentName2ProtocolGuid,\r
1130 &gPxeBcComponentName2,\r
1131 &gEfiComponentNameProtocolGuid,\r
a3bcde70 1132 &gPxeBcComponentName,\r
6879581d 1133 NULL\r
a3bcde70 1134 );\r
6879581d 1135 }\r
a3bcde70 1136\r
6879581d 1137 return Status;\r
1138}\r
a3bcde70
HT
1139\r
1140/**\r
6879581d 1141 Test to see if this driver supports ControllerHandle. This is the worker function for\r
1142 PxeBcIp4(6)DriverBindingSupported.\r
a3bcde70
HT
1143\r
1144 @param[in] This The pointer to the driver binding protocol.\r
1145 @param[in] ControllerHandle The handle of device to be tested.\r
1146 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1147 device to be started.\r
6879581d 1148 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
1149 \r
a3bcde70
HT
1150 @retval EFI_SUCCESS This driver supports this device.\r
1151 @retval EFI_UNSUPPORTED This driver does not support this device.\r
1152\r
1153**/\r
1154EFI_STATUS\r
1155EFIAPI\r
6879581d 1156PxeBcSupported (\r
a3bcde70
HT
1157 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1158 IN EFI_HANDLE ControllerHandle,\r
6879581d 1159 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
1160 IN UINT8 IpVersion\r
a3bcde70
HT
1161 )\r
1162{\r
6879581d 1163 EFI_STATUS Status;\r
1164 EFI_GUID *DhcpServiceBindingGuid;\r
1165 EFI_GUID *MtftpServiceBindingGuid;\r
1166 \r
1167 if (IpVersion == IP_VERSION_4) {\r
1168 DhcpServiceBindingGuid = &gEfiDhcp4ServiceBindingProtocolGuid;\r
1169 MtftpServiceBindingGuid = &gEfiMtftp4ServiceBindingProtocolGuid;\r
1170 } else {\r
1171 DhcpServiceBindingGuid = &gEfiDhcp6ServiceBindingProtocolGuid;\r
1172 MtftpServiceBindingGuid = &gEfiMtftp6ServiceBindingProtocolGuid;\r
a3bcde70
HT
1173 }\r
1174\r
1175 //\r
6879581d 1176 // Try to open the Mtftp and Dhcp protocol to test whether IP stack is ready.\r
a3bcde70 1177 //\r
6879581d 1178 Status = gBS->OpenProtocol (\r
a3bcde70 1179 ControllerHandle,\r
6879581d 1180 DhcpServiceBindingGuid,\r
a3bcde70
HT
1181 NULL,\r
1182 This->DriverBindingHandle,\r
1183 ControllerHandle,\r
1184 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
1185 );\r
6879581d 1186 if (!EFI_ERROR (Status)) {\r
1187 Status = gBS->OpenProtocol (\r
a3bcde70 1188 ControllerHandle,\r
6879581d 1189 MtftpServiceBindingGuid,\r
a3bcde70
HT
1190 NULL,\r
1191 This->DriverBindingHandle,\r
1192 ControllerHandle,\r
1193 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
1194 );\r
1195 }\r
1196\r
1197 //\r
6879581d 1198 // It's unsupported case if IP stack are not ready.\r
a3bcde70 1199 //\r
6879581d 1200 if (EFI_ERROR (Status)) {\r
a3bcde70
HT
1201 return EFI_UNSUPPORTED;\r
1202 }\r
1203\r
1204 return EFI_SUCCESS;\r
1205}\r
1206\r
a3bcde70 1207/**\r
6879581d 1208 Start this driver on ControllerHandle. This is the worker function for\r
1209 PxeBcIp4(6)DriverBindingStart.\r
a3bcde70
HT
1210\r
1211 @param[in] This The pointer to the driver binding protocol.\r
1212 @param[in] ControllerHandle The handle of device to be started.\r
1213 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1214 device to be started.\r
6879581d 1215 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
1216\r
a3bcde70
HT
1217\r
1218 @retval EFI_SUCCESS This driver is installed to ControllerHandle.\r
1219 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
1220 @retval other This driver does not support this device.\r
1221\r
1222**/\r
1223EFI_STATUS\r
1224EFIAPI\r
6879581d 1225PxeBcStart (\r
a3bcde70
HT
1226 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1227 IN EFI_HANDLE ControllerHandle,\r
6879581d 1228 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
1229 IN UINT8 IpVersion\r
a3bcde70
HT
1230 )\r
1231{\r
1232 PXEBC_PRIVATE_DATA *Private;\r
a3bcde70 1233 EFI_STATUS Status;\r
15f3fc85 1234 PXEBC_PRIVATE_PROTOCOL *Id;\r
6879581d 1235 BOOLEAN FirstStart;\r
a3bcde70 1236\r
6879581d 1237 FirstStart = FALSE;\r
a3bcde70
HT
1238 Status = gBS->OpenProtocol (\r
1239 ControllerHandle,\r
9bdc6592 1240 &gEfiCallerIdGuid,\r
15f3fc85 1241 (VOID **) &Id,\r
a3bcde70
HT
1242 This->DriverBindingHandle,\r
1243 ControllerHandle,\r
1244 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1245 );\r
1246 if (!EFI_ERROR (Status)) {\r
1247 //\r
1248 // Skip the initialization if the driver has been started already.\r
1249 //\r
15f3fc85 1250 Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);\r
a3bcde70 1251 } else {\r
6879581d 1252 FirstStart = TRUE;\r
a3bcde70
HT
1253 //\r
1254 // If the driver has not been started yet, it should do initialization.\r
1255 //\r
1256 Private = AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));\r
1257 if (Private == NULL) {\r
1258 return EFI_OUT_OF_RESOURCES;\r
1259 }\r
1260\r
1261 CopyMem (\r
1262 &Private->PxeBc,\r
1263 &gPxeBcProtocolTemplate,\r
1264 sizeof (EFI_PXE_BASE_CODE_PROTOCOL)\r
1265 );\r
1266\r
1267 Private->Signature = PXEBC_PRIVATE_DATA_SIGNATURE;\r
1268 Private->Controller = ControllerHandle;\r
1269 Private->Image = This->ImageHandle;\r
1270 Private->PxeBc.Mode = &Private->Mode;\r
1271 Private->Mode.Ipv6Supported = TRUE;\r
1272 Private->Mode.AutoArp = TRUE;\r
1273 Private->Mode.TTL = DEFAULT_TTL;\r
1274 Private->Mode.ToS = DEFAULT_ToS;\r
1275\r
1276 //\r
1277 // Open device path to prepare for appending virtual NIC node.\r
1278 //\r
1279 Status = gBS->OpenProtocol (\r
1280 ControllerHandle,\r
1281 &gEfiDevicePathProtocolGuid,\r
1282 (VOID **) &Private->DevicePath,\r
1283 This->DriverBindingHandle,\r
1284 ControllerHandle,\r
1285 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1286 );\r
1287\r
1288 if (EFI_ERROR (Status)) {\r
1289 goto ON_ERROR;\r
1290 }\r
1291\r
1292 //\r
1293 // Get the NII interface if it exists, it's not required.\r
1294 //\r
1295 Status = gBS->OpenProtocol (\r
1296 ControllerHandle,\r
1297 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
1298 (VOID **) &Private->Nii,\r
1299 This->DriverBindingHandle,\r
1300 ControllerHandle,\r
1301 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1302 );\r
1303 if (EFI_ERROR (Status)) {\r
1304 Private->Nii = NULL;\r
1305 }\r
1306\r
1307 //\r
15f3fc85 1308 // Install PxeBaseCodePrivate protocol onto the real NIC handler.\r
9bdc6592
LG
1309 // PxeBaseCodePrivate protocol is only used to keep the relationship between \r
1310 // NIC handle and virtual child handles.\r
1311 // gEfiCallerIdGuid will be used as its protocol guid.\r
a3bcde70
HT
1312 //\r
1313 Status = gBS->InstallProtocolInterface (\r
1314 &ControllerHandle,\r
9bdc6592 1315 &gEfiCallerIdGuid,\r
a3bcde70 1316 EFI_NATIVE_INTERFACE,\r
15f3fc85 1317 &Private->Id\r
a3bcde70
HT
1318 );\r
1319 if (EFI_ERROR (Status)) {\r
1320 goto ON_ERROR;\r
1321 }\r
15f3fc85 1322\r
1323 //\r
1324 // Try to locate SNP protocol.\r
1325 //\r
1326 NetLibGetSnpHandle(ControllerHandle, &Private->Snp); \r
a3bcde70
HT
1327 }\r
1328\r
6879581d 1329 if (IpVersion == IP_VERSION_4) {\r
1330 //\r
1331 // Try to create virtual NIC handle for IPv4.\r
1332 //\r
1333 Status = PxeBcCreateIp4Children (This, ControllerHandle, Private);\r
1334 } else {\r
1335 //\r
1336 // Try to create virtual NIC handle for IPv6.\r
1337 //\r
1338 Status = PxeBcCreateIp6Children (This, ControllerHandle, Private);\r
1339 }\r
1340 if (EFI_ERROR (Status)) {\r
a3bcde70
HT
1341 //\r
1342 // Failed to start PXE driver if IPv4 and IPv6 stack are both not available.\r
1343 //\r
1344 Status = EFI_DEVICE_ERROR;\r
1345 goto ON_ERROR;\r
1346 }\r
1347\r
1348 return EFI_SUCCESS;\r
1349\r
1350ON_ERROR:\r
6879581d 1351 if (FirstStart) {\r
1352 gBS->UninstallProtocolInterface (\r
1353 ControllerHandle,\r
1354 &gEfiCallerIdGuid,\r
1355 &Private->Id\r
1356 );\r
6879581d 1357 }\r
1358\r
1359 if (IpVersion == IP_VERSION_4) {\r
1360 PxeBcDestroyIp4Children (This, Private);\r
1361 } else {\r
1362 PxeBcDestroyIp6Children (This, Private);\r
1363 }\r
a3bcde70 1364\r
3d2367a2 1365 if (FirstStart && Private != NULL) {\r
1366 FreePool (Private);\r
1367 }\r
1368\r
a3bcde70
HT
1369 return Status;\r
1370}\r
1371\r
1372\r
1373/**\r
6879581d 1374 Stop this driver on ControllerHandle. This is the worker function for\r
1375 PxeBcIp4(6)DriverBindingStop.\r
a3bcde70
HT
1376\r
1377 @param[in] This Protocol instance pointer.\r
1378 @param[in] ControllerHandle Handle of device to stop driver on.\r
1379 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
1380 children is zero stop the entire bus driver.\r
1381 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
6879581d 1382 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
a3bcde70
HT
1383\r
1384 @retval EFI_SUCCESS This driver was removed ControllerHandle.\r
1385 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1386 @retval Others This driver was not removed from this device\r
1387\r
1388**/\r
1389EFI_STATUS\r
1390EFIAPI\r
6879581d 1391PxeBcStop (\r
a3bcde70
HT
1392 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1393 IN EFI_HANDLE ControllerHandle,\r
1394 IN UINTN NumberOfChildren,\r
6879581d 1395 IN EFI_HANDLE *ChildHandleBuffer,\r
1396 IN UINT8 IpVersion\r
a3bcde70
HT
1397 )\r
1398{\r
1399 PXEBC_PRIVATE_DATA *Private;\r
1400 PXEBC_VIRTUAL_NIC *VirtualNic;\r
a3bcde70
HT
1401 EFI_LOAD_FILE_PROTOCOL *LoadFile;\r
1402 EFI_STATUS Status;\r
1403 EFI_HANDLE NicHandle;\r
15f3fc85 1404 PXEBC_PRIVATE_PROTOCOL *Id;\r
a3bcde70
HT
1405\r
1406 Private = NULL;\r
1407 NicHandle = NULL;\r
1408 VirtualNic = NULL;\r
1409 LoadFile = NULL;\r
15f3fc85 1410 Id = NULL;\r
a3bcde70
HT
1411\r
1412 Status = gBS->OpenProtocol (\r
1413 ControllerHandle,\r
1414 &gEfiLoadFileProtocolGuid,\r
1415 (VOID **) &LoadFile,\r
1416 This->DriverBindingHandle,\r
1417 ControllerHandle,\r
1418 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1419 );\r
1420 if (EFI_ERROR (Status)) {\r
1421 //\r
1422 // Get the Nic handle by any pass-over service child handle.\r
1423 //\r
6879581d 1424 if (IpVersion == IP_VERSION_4) {\r
1425 NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);\r
1426 } else {\r
a3bcde70 1427 NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);\r
6879581d 1428 }\r
1429 if (NicHandle == NULL) {\r
1430 return EFI_SUCCESS;\r
a3bcde70
HT
1431 }\r
1432\r
1433 //\r
15f3fc85 1434 // Try to retrieve the private data by PxeBcPrivate protocol.\r
a3bcde70
HT
1435 //\r
1436 Status = gBS->OpenProtocol (\r
1437 NicHandle,\r
9bdc6592 1438 &gEfiCallerIdGuid,\r
15f3fc85 1439 (VOID **) &Id,\r
a3bcde70
HT
1440 This->DriverBindingHandle,\r
1441 ControllerHandle,\r
1442 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1443 );\r
1444 if (EFI_ERROR (Status)) {\r
1445 return Status;\r
1446 }\r
15f3fc85 1447 Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);\r
a3bcde70
HT
1448\r
1449 } else {\r
1450 //\r
1451 // It's a virtual handle with LoadFileProtocol.\r
1452 //\r
1453 Status = gBS->OpenProtocol (\r
1454 ControllerHandle,\r
1455 &gEfiLoadFileProtocolGuid,\r
1456 (VOID **) &LoadFile,\r
1457 This->DriverBindingHandle,\r
1458 ControllerHandle,\r
1459 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1460 );\r
1461 if (EFI_ERROR (Status)) {\r
1462 return Status;\r
1463 }\r
1464\r
1465 VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile);\r
1466 Private = VirtualNic->Private;\r
1467 NicHandle = Private->Controller;\r
a3bcde70
HT
1468 }\r
1469\r
d6d78ac1 1470 //\r
1471 // Stop functionality of PXE Base Code protocol\r
1472 //\r
1473 Status = Private->PxeBc.Stop (&Private->PxeBc);\r
1474 if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {\r
1475 return Status;\r
1476 }\r
1477\r
1478\r
6879581d 1479 if (Private->Ip4Nic != NULL && IpVersion == IP_VERSION_4) {\r
a3bcde70
HT
1480 PxeBcDestroyIp4Children (This, Private);\r
1481 }\r
1482\r
6879581d 1483 if (Private->Ip6Nic != NULL && IpVersion == IP_VERSION_6) {\r
a3bcde70
HT
1484 PxeBcDestroyIp6Children (This, Private);\r
1485 }\r
1486\r
1487 if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {\r
1488 gBS->UninstallProtocolInterface (\r
1489 NicHandle,\r
9bdc6592 1490 &gEfiCallerIdGuid,\r
15f3fc85 1491 &Private->Id\r
a3bcde70
HT
1492 );\r
1493 FreePool (Private);\r
1494 }\r
1495\r
1496 return EFI_SUCCESS;\r
1497}\r
6879581d 1498\r
1499/**\r
1500 Test to see if this driver supports ControllerHandle. This service\r
1501 is called by the EFI boot service ConnectController(). In\r
1502 order to make drivers as small as possible, there are a few calling\r
1503 restrictions for this service. ConnectController() must\r
1504 follow these calling restrictions. If any other agent wishes to call\r
1505 Supported() it must also follow these calling restrictions.\r
1506\r
1507 @param[in] This The pointer to the driver binding protocol.\r
1508 @param[in] ControllerHandle The handle of device to be tested.\r
1509 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1510 device to be started.\r
1511\r
1512 @retval EFI_SUCCESS This driver supports this device.\r
1513 @retval EFI_UNSUPPORTED This driver does not support this device.\r
1514\r
1515**/\r
1516EFI_STATUS\r
1517EFIAPI\r
1518PxeBcIp4DriverBindingSupported (\r
1519 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1520 IN EFI_HANDLE ControllerHandle,\r
1521 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1522 )\r
1523{\r
1524 return PxeBcSupported (\r
1525 This,\r
1526 ControllerHandle,\r
1527 RemainingDevicePath,\r
1528 IP_VERSION_4\r
1529 );\r
1530}\r
1531\r
1532/**\r
1533 Start this driver on ControllerHandle. This service is called by the\r
1534 EFI boot service ConnectController(). In order to make\r
1535 drivers as small as possible, there are a few calling restrictions for\r
1536 this service. ConnectController() must follow these\r
1537 calling restrictions. If any other agent wishes to call Start() it\r
1538 must also follow these calling restrictions.\r
1539\r
1540 @param[in] This The pointer to the driver binding protocol.\r
1541 @param[in] ControllerHandle The handle of device to be started.\r
1542 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1543 device to be started.\r
1544\r
1545 @retval EFI_SUCCESS This driver is installed to ControllerHandle.\r
1546 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
1547 @retval other This driver does not support this device.\r
1548\r
1549**/\r
1550EFI_STATUS\r
1551EFIAPI\r
1552PxeBcIp4DriverBindingStart (\r
1553 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1554 IN EFI_HANDLE ControllerHandle,\r
1555 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1556 )\r
1557{\r
1558 return PxeBcStart (\r
1559 This,\r
1560 ControllerHandle,\r
1561 RemainingDevicePath,\r
1562 IP_VERSION_4\r
1563 );\r
1564}\r
1565\r
1566/**\r
1567 Stop this driver on ControllerHandle. This service is called by the\r
1568 EFI boot service DisconnectController(). In order to\r
1569 make drivers as small as possible, there are a few calling\r
1570 restrictions for this service. DisconnectController()\r
1571 must follow these calling restrictions. If any other agent wishes\r
1572 to call Stop() it must also follow these calling restrictions.\r
1573\r
1574 @param[in] This Protocol instance pointer.\r
1575 @param[in] ControllerHandle Handle of device to stop driver on\r
1576 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
1577 children is zero stop the entire bus driver.\r
1578 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
1579\r
1580 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
1581 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1582 @retval Others This driver was not removed from this device.\r
1583\r
1584**/\r
1585EFI_STATUS\r
1586EFIAPI\r
1587PxeBcIp4DriverBindingStop (\r
1588 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1589 IN EFI_HANDLE ControllerHandle,\r
1590 IN UINTN NumberOfChildren,\r
1591 IN EFI_HANDLE *ChildHandleBuffer\r
1592 )\r
1593{\r
1594 return PxeBcStop (\r
1595 This,\r
1596 ControllerHandle,\r
1597 NumberOfChildren,\r
1598 ChildHandleBuffer,\r
1599 IP_VERSION_4\r
1600 );\r
1601}\r
1602\r
1603/**\r
1604 Test to see if this driver supports ControllerHandle. This service\r
1605 is called by the EFI boot service ConnectController(). In\r
1606 order to make drivers as small as possible, there are a few calling\r
1607 restrictions for this service. ConnectController() must\r
1608 follow these calling restrictions. If any other agent wishes to call\r
1609 Supported() it must also follow these calling restrictions.\r
1610\r
1611 @param[in] This The pointer to the driver binding protocol.\r
1612 @param[in] ControllerHandle The handle of device to be tested.\r
1613 @param[in] RemainingDevicePath Optional parameter use to pick a specific child\r
1614 device to be started.\r
1615\r
1616 @retval EFI_SUCCESS This driver supports this device.\r
1617 @retval EFI_UNSUPPORTED This driver does not support this device.\r
1618\r
1619**/\r
1620EFI_STATUS\r
1621EFIAPI\r
1622PxeBcIp6DriverBindingSupported (\r
1623 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1624 IN EFI_HANDLE ControllerHandle,\r
1625 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1626 )\r
1627{\r
1628 return PxeBcSupported (\r
1629 This,\r
1630 ControllerHandle,\r
1631 RemainingDevicePath,\r
1632 IP_VERSION_6\r
1633 );\r
1634}\r
1635\r
1636/**\r
1637 Start this driver on ControllerHandle. This service is called by the\r
1638 EFI boot service ConnectController(). In order to make\r
1639 drivers as small as possible, there are a few calling restrictions for\r
1640 this service. ConnectController() must follow these\r
1641 calling restrictions. If any other agent wishes to call Start() it\r
1642 must also follow these calling restrictions.\r
1643\r
1644 @param[in] This The pointer to the driver binding protocol.\r
1645 @param[in] ControllerHandle The handle of device to be started.\r
1646 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1647 device to be started.\r
1648\r
1649 @retval EFI_SUCCESS This driver is installed to ControllerHandle.\r
1650 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
1651 @retval other This driver does not support this device.\r
1652\r
1653**/\r
1654EFI_STATUS\r
1655EFIAPI\r
1656PxeBcIp6DriverBindingStart (\r
1657 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1658 IN EFI_HANDLE ControllerHandle,\r
1659 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1660 )\r
1661{\r
1662 return PxeBcStart (\r
1663 This,\r
1664 ControllerHandle,\r
1665 RemainingDevicePath,\r
1666 IP_VERSION_6\r
1667 );\r
1668}\r
1669\r
1670/**\r
1671 Stop this driver on ControllerHandle. This service is called by the\r
1672 EFI boot service DisconnectController(). In order to\r
1673 make drivers as small as possible, there are a few calling\r
1674 restrictions for this service. DisconnectController()\r
1675 must follow these calling restrictions. If any other agent wishes\r
1676 to call Stop() it must also follow these calling restrictions.\r
1677\r
1678 @param[in] This Protocol instance pointer.\r
1679 @param[in] ControllerHandle Handle of device to stop driver on\r
1680 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
1681 children is zero stop the entire bus driver.\r
1682 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
1683\r
1684 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
1685 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1686 @retval Others This driver was not removed from this device.\r
1687\r
1688**/\r
1689EFI_STATUS\r
1690EFIAPI\r
1691PxeBcIp6DriverBindingStop (\r
1692 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1693 IN EFI_HANDLE ControllerHandle,\r
1694 IN UINTN NumberOfChildren,\r
1695 IN EFI_HANDLE *ChildHandleBuffer\r
1696 )\r
1697{\r
1698 return PxeBcStop (\r
1699 This,\r
1700 ControllerHandle,\r
1701 NumberOfChildren,\r
1702 ChildHandleBuffer,\r
1703 IP_VERSION_6\r
1704 );\r
1705}\r