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