]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
MdePkg: add missing #defines for decoding PCIe 2.1 extended capability structures
[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
6879581d 1356 }\r
1357\r
1358 if (IpVersion == IP_VERSION_4) {\r
1359 PxeBcDestroyIp4Children (This, Private);\r
1360 } else {\r
1361 PxeBcDestroyIp6Children (This, Private);\r
1362 }\r
a3bcde70 1363\r
3d2367a2 1364 if (FirstStart && Private != NULL) {\r
1365 FreePool (Private);\r
1366 }\r
1367\r
a3bcde70
HT
1368 return Status;\r
1369}\r
1370\r
1371\r
1372/**\r
6879581d 1373 Stop this driver on ControllerHandle. This is the worker function for\r
1374 PxeBcIp4(6)DriverBindingStop.\r
a3bcde70
HT
1375\r
1376 @param[in] This Protocol instance pointer.\r
1377 @param[in] ControllerHandle Handle of device to stop driver on.\r
1378 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
1379 children is zero stop the entire bus driver.\r
1380 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
6879581d 1381 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
a3bcde70
HT
1382\r
1383 @retval EFI_SUCCESS This driver was removed ControllerHandle.\r
1384 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1385 @retval Others This driver was not removed from this device\r
1386\r
1387**/\r
1388EFI_STATUS\r
1389EFIAPI\r
6879581d 1390PxeBcStop (\r
a3bcde70
HT
1391 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1392 IN EFI_HANDLE ControllerHandle,\r
1393 IN UINTN NumberOfChildren,\r
6879581d 1394 IN EFI_HANDLE *ChildHandleBuffer,\r
1395 IN UINT8 IpVersion\r
a3bcde70
HT
1396 )\r
1397{\r
1398 PXEBC_PRIVATE_DATA *Private;\r
1399 PXEBC_VIRTUAL_NIC *VirtualNic;\r
a3bcde70
HT
1400 EFI_LOAD_FILE_PROTOCOL *LoadFile;\r
1401 EFI_STATUS Status;\r
1402 EFI_HANDLE NicHandle;\r
1403 BOOLEAN IsIpv6;\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 IsIpv6 = FALSE;\r
1412\r
1413 Status = gBS->OpenProtocol (\r
1414 ControllerHandle,\r
1415 &gEfiLoadFileProtocolGuid,\r
1416 (VOID **) &LoadFile,\r
1417 This->DriverBindingHandle,\r
1418 ControllerHandle,\r
1419 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1420 );\r
1421 if (EFI_ERROR (Status)) {\r
1422 //\r
1423 // Get the Nic handle by any pass-over service child handle.\r
1424 //\r
6879581d 1425 if (IpVersion == IP_VERSION_4) {\r
1426 NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);\r
1427 } else {\r
a3bcde70 1428 NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);\r
6879581d 1429 }\r
1430 if (NicHandle == NULL) {\r
1431 return EFI_SUCCESS;\r
a3bcde70
HT
1432 }\r
1433\r
1434 //\r
15f3fc85 1435 // Try to retrieve the private data by PxeBcPrivate protocol.\r
a3bcde70
HT
1436 //\r
1437 Status = gBS->OpenProtocol (\r
1438 NicHandle,\r
9bdc6592 1439 &gEfiCallerIdGuid,\r
15f3fc85 1440 (VOID **) &Id,\r
a3bcde70
HT
1441 This->DriverBindingHandle,\r
1442 ControllerHandle,\r
1443 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1444 );\r
1445 if (EFI_ERROR (Status)) {\r
1446 return Status;\r
1447 }\r
15f3fc85 1448 Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);\r
a3bcde70
HT
1449\r
1450 } else {\r
1451 //\r
1452 // It's a virtual handle with LoadFileProtocol.\r
1453 //\r
1454 Status = gBS->OpenProtocol (\r
1455 ControllerHandle,\r
1456 &gEfiLoadFileProtocolGuid,\r
1457 (VOID **) &LoadFile,\r
1458 This->DriverBindingHandle,\r
1459 ControllerHandle,\r
1460 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1461 );\r
1462 if (EFI_ERROR (Status)) {\r
1463 return Status;\r
1464 }\r
1465\r
1466 VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile);\r
1467 Private = VirtualNic->Private;\r
1468 NicHandle = Private->Controller;\r
a3bcde70
HT
1469 }\r
1470\r
d6d78ac1 1471 //\r
1472 // Stop functionality of PXE Base Code protocol\r
1473 //\r
1474 Status = Private->PxeBc.Stop (&Private->PxeBc);\r
1475 if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {\r
1476 return Status;\r
1477 }\r
1478\r
1479\r
6879581d 1480 if (Private->Ip4Nic != NULL && IpVersion == IP_VERSION_4) {\r
a3bcde70
HT
1481 PxeBcDestroyIp4Children (This, Private);\r
1482 }\r
1483\r
6879581d 1484 if (Private->Ip6Nic != NULL && IpVersion == IP_VERSION_6) {\r
a3bcde70
HT
1485 PxeBcDestroyIp6Children (This, Private);\r
1486 }\r
1487\r
1488 if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {\r
1489 gBS->UninstallProtocolInterface (\r
1490 NicHandle,\r
9bdc6592 1491 &gEfiCallerIdGuid,\r
15f3fc85 1492 &Private->Id\r
a3bcde70
HT
1493 );\r
1494 FreePool (Private);\r
1495 }\r
1496\r
1497 return EFI_SUCCESS;\r
1498}\r
6879581d 1499\r
1500/**\r
1501 Test to see if this driver supports ControllerHandle. This service\r
1502 is called by the EFI boot service ConnectController(). In\r
1503 order to make drivers as small as possible, there are a few calling\r
1504 restrictions for this service. ConnectController() must\r
1505 follow these calling restrictions. If any other agent wishes to call\r
1506 Supported() it must also follow these calling restrictions.\r
1507\r
1508 @param[in] This The pointer to the driver binding protocol.\r
1509 @param[in] ControllerHandle The handle of device to be tested.\r
1510 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1511 device to be started.\r
1512\r
1513 @retval EFI_SUCCESS This driver supports this device.\r
1514 @retval EFI_UNSUPPORTED This driver does not support this device.\r
1515\r
1516**/\r
1517EFI_STATUS\r
1518EFIAPI\r
1519PxeBcIp4DriverBindingSupported (\r
1520 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1521 IN EFI_HANDLE ControllerHandle,\r
1522 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1523 )\r
1524{\r
1525 return PxeBcSupported (\r
1526 This,\r
1527 ControllerHandle,\r
1528 RemainingDevicePath,\r
1529 IP_VERSION_4\r
1530 );\r
1531}\r
1532\r
1533/**\r
1534 Start this driver on ControllerHandle. This service is called by the\r
1535 EFI boot service ConnectController(). In order to make\r
1536 drivers as small as possible, there are a few calling restrictions for\r
1537 this service. ConnectController() must follow these\r
1538 calling restrictions. If any other agent wishes to call Start() it\r
1539 must also follow these calling restrictions.\r
1540\r
1541 @param[in] This The pointer to the driver binding protocol.\r
1542 @param[in] ControllerHandle The handle of device to be started.\r
1543 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1544 device to be started.\r
1545\r
1546 @retval EFI_SUCCESS This driver is installed to ControllerHandle.\r
1547 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
1548 @retval other This driver does not support this device.\r
1549\r
1550**/\r
1551EFI_STATUS\r
1552EFIAPI\r
1553PxeBcIp4DriverBindingStart (\r
1554 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1555 IN EFI_HANDLE ControllerHandle,\r
1556 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1557 )\r
1558{\r
1559 return PxeBcStart (\r
1560 This,\r
1561 ControllerHandle,\r
1562 RemainingDevicePath,\r
1563 IP_VERSION_4\r
1564 );\r
1565}\r
1566\r
1567/**\r
1568 Stop this driver on ControllerHandle. This service is called by the\r
1569 EFI boot service DisconnectController(). In order to\r
1570 make drivers as small as possible, there are a few calling\r
1571 restrictions for this service. DisconnectController()\r
1572 must follow these calling restrictions. If any other agent wishes\r
1573 to call Stop() it must also follow these calling restrictions.\r
1574\r
1575 @param[in] This Protocol instance pointer.\r
1576 @param[in] ControllerHandle Handle of device to stop driver on\r
1577 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
1578 children is zero stop the entire bus driver.\r
1579 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
1580\r
1581 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
1582 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1583 @retval Others This driver was not removed from this device.\r
1584\r
1585**/\r
1586EFI_STATUS\r
1587EFIAPI\r
1588PxeBcIp4DriverBindingStop (\r
1589 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1590 IN EFI_HANDLE ControllerHandle,\r
1591 IN UINTN NumberOfChildren,\r
1592 IN EFI_HANDLE *ChildHandleBuffer\r
1593 )\r
1594{\r
1595 return PxeBcStop (\r
1596 This,\r
1597 ControllerHandle,\r
1598 NumberOfChildren,\r
1599 ChildHandleBuffer,\r
1600 IP_VERSION_4\r
1601 );\r
1602}\r
1603\r
1604/**\r
1605 Test to see if this driver supports ControllerHandle. This service\r
1606 is called by the EFI boot service ConnectController(). In\r
1607 order to make drivers as small as possible, there are a few calling\r
1608 restrictions for this service. ConnectController() must\r
1609 follow these calling restrictions. If any other agent wishes to call\r
1610 Supported() it must also follow these calling restrictions.\r
1611\r
1612 @param[in] This The pointer to the driver binding protocol.\r
1613 @param[in] ControllerHandle The handle of device to be tested.\r
1614 @param[in] RemainingDevicePath Optional parameter use to pick a specific child\r
1615 device to be started.\r
1616\r
1617 @retval EFI_SUCCESS This driver supports this device.\r
1618 @retval EFI_UNSUPPORTED This driver does not support this device.\r
1619\r
1620**/\r
1621EFI_STATUS\r
1622EFIAPI\r
1623PxeBcIp6DriverBindingSupported (\r
1624 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1625 IN EFI_HANDLE ControllerHandle,\r
1626 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1627 )\r
1628{\r
1629 return PxeBcSupported (\r
1630 This,\r
1631 ControllerHandle,\r
1632 RemainingDevicePath,\r
1633 IP_VERSION_6\r
1634 );\r
1635}\r
1636\r
1637/**\r
1638 Start this driver on ControllerHandle. This service is called by the\r
1639 EFI boot service ConnectController(). In order to make\r
1640 drivers as small as possible, there are a few calling restrictions for\r
1641 this service. ConnectController() must follow these\r
1642 calling restrictions. If any other agent wishes to call Start() it\r
1643 must also follow these calling restrictions.\r
1644\r
1645 @param[in] This The pointer to the driver binding protocol.\r
1646 @param[in] ControllerHandle The handle of device to be started.\r
1647 @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
1648 device to be started.\r
1649\r
1650 @retval EFI_SUCCESS This driver is installed to ControllerHandle.\r
1651 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
1652 @retval other This driver does not support this device.\r
1653\r
1654**/\r
1655EFI_STATUS\r
1656EFIAPI\r
1657PxeBcIp6DriverBindingStart (\r
1658 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1659 IN EFI_HANDLE ControllerHandle,\r
1660 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
1661 )\r
1662{\r
1663 return PxeBcStart (\r
1664 This,\r
1665 ControllerHandle,\r
1666 RemainingDevicePath,\r
1667 IP_VERSION_6\r
1668 );\r
1669}\r
1670\r
1671/**\r
1672 Stop this driver on ControllerHandle. This service is called by the\r
1673 EFI boot service DisconnectController(). In order to\r
1674 make drivers as small as possible, there are a few calling\r
1675 restrictions for this service. DisconnectController()\r
1676 must follow these calling restrictions. If any other agent wishes\r
1677 to call Stop() it must also follow these calling restrictions.\r
1678\r
1679 @param[in] This Protocol instance pointer.\r
1680 @param[in] ControllerHandle Handle of device to stop driver on\r
1681 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
1682 children is zero stop the entire bus driver.\r
1683 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
1684\r
1685 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
1686 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1687 @retval Others This driver was not removed from this device.\r
1688\r
1689**/\r
1690EFI_STATUS\r
1691EFIAPI\r
1692PxeBcIp6DriverBindingStop (\r
1693 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1694 IN EFI_HANDLE ControllerHandle,\r
1695 IN UINTN NumberOfChildren,\r
1696 IN EFI_HANDLE *ChildHandleBuffer\r
1697 )\r
1698{\r
1699 return PxeBcStop (\r
1700 This,\r
1701 ControllerHandle,\r
1702 NumberOfChildren,\r
1703 ChildHandleBuffer,\r
1704 IP_VERSION_6\r
1705 );\r
1706}\r