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