]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
67a60a9120be53f60deaa56aeb30d00749bf5404
[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 &gEfiMtftp4ServiceBindingProtocolGuid,
227 &Private->Mtftp4Child
228 );
229
230 if (EFI_ERROR (Status)) {
231 goto ON_ERROR;
232 }
233
234 Status = gBS->OpenProtocol (
235 Private->Mtftp4Child,
236 &gEfiMtftp4ProtocolGuid,
237 (VOID **) &Private->Mtftp4,
238 This->DriverBindingHandle,
239 ControllerHandle,
240 EFI_OPEN_PROTOCOL_BY_DRIVER
241 );
242
243 if (EFI_ERROR (Status)) {
244 goto ON_ERROR;
245 }
246
247 Status = NetLibCreateServiceChild (
248 ControllerHandle,
249 This->DriverBindingHandle,
250 &gEfiUdp4ServiceBindingProtocolGuid,
251 &Private->Udp4Child
252 );
253
254 if (EFI_ERROR (Status)) {
255 goto ON_ERROR;
256 }
257
258 Status = gBS->OpenProtocol (
259 Private->Udp4Child,
260 &gEfiUdp4ProtocolGuid,
261 (VOID **) &Private->Udp4,
262 This->DriverBindingHandle,
263 ControllerHandle,
264 EFI_OPEN_PROTOCOL_BY_DRIVER
265 );
266
267 if (EFI_ERROR (Status)) {
268 goto ON_ERROR;
269 }
270
271 ZeroMem (&Private->Udp4CfgData, sizeof (EFI_UDP4_CONFIG_DATA));
272 Private->Udp4CfgData.AcceptBroadcast = FALSE;
273 Private->Udp4CfgData.AcceptPromiscuous = FALSE;
274 Private->Udp4CfgData.AcceptAnyPort = FALSE;
275 Private->Udp4CfgData.AllowDuplicatePort = TRUE;
276 Private->Udp4CfgData.TypeOfService = DEFAULT_ToS;
277 Private->Udp4CfgData.TimeToLive = DEFAULT_TTL;
278 Private->Udp4CfgData.DoNotFragment = FALSE;
279 Private->Udp4CfgData.ReceiveTimeout = 10000; // 10 milliseconds
280 Private->Udp4CfgData.UseDefaultAddress = FALSE;
281
282 PxeBcInitSeedPacket (&Private->SeedPacket, Private->Udp4);
283
284 Status = gBS->InstallMultipleProtocolInterfaces (
285 &ControllerHandle,
286 &gEfiPxeBaseCodeProtocolGuid,
287 &Private->PxeBc,
288 &gEfiLoadFileProtocolGuid,
289 &Private->LoadFile,
290 NULL
291 );
292 if (EFI_ERROR (Status)) {
293 goto ON_ERROR;
294 }
295
296 return EFI_SUCCESS;
297
298 ON_ERROR:
299
300 if (Private->Udp4Child != NULL) {
301 gBS->CloseProtocol (
302 Private->Udp4Child,
303 &gEfiUdp4ProtocolGuid,
304 This->DriverBindingHandle,
305 ControllerHandle
306 );
307 NetLibDestroyServiceChild (
308 ControllerHandle,
309 This->DriverBindingHandle,
310 &gEfiUdp4ServiceBindingProtocolGuid,
311 Private->Udp4Child
312 );
313 }
314
315 if (Private->Mtftp4Child != NULL) {
316 gBS->CloseProtocol (
317 Private->Mtftp4Child,
318 &gEfiMtftp4ProtocolGuid,
319 This->DriverBindingHandle,
320 ControllerHandle
321 );
322
323 NetLibDestroyServiceChild (
324 ControllerHandle,
325 This->DriverBindingHandle,
326 &gEfiMtftp4ServiceBindingProtocolGuid,
327 Private->Mtftp4Child
328 );
329 }
330
331 if (Private->Dhcp4Child != NULL) {
332 gBS->CloseProtocol (
333 Private->Dhcp4Child,
334 &gEfiDhcp4ProtocolGuid,
335 This->DriverBindingHandle,
336 ControllerHandle
337 );
338
339 NetLibDestroyServiceChild (
340 ControllerHandle,
341 This->DriverBindingHandle,
342 &gEfiDhcp4ServiceBindingProtocolGuid,
343 Private->Dhcp4Child
344 );
345 }
346
347 if (Private->ArpChild != NULL) {
348 gBS->CloseProtocol (
349 Private->ArpChild,
350 &gEfiArpProtocolGuid,
351 This->DriverBindingHandle,
352 ControllerHandle
353 );
354
355 NetLibDestroyServiceChild (
356 ControllerHandle,
357 This->DriverBindingHandle,
358 &gEfiArpServiceBindingProtocolGuid,
359 Private->ArpChild
360 );
361 }
362
363 gBS->FreePool (Private);
364
365 return Status;
366 }
367
368
369 /**
370 Stop this driver on ControllerHandle.
371
372 @param This Protocol instance pointer.
373 @param ControllerHandle Handle of device to stop driver on
374 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
375 children is zero stop the entire bus driver.
376 @param ChildHandleBuffer List of Child Handles to Stop.
377
378 @return EFI_SUCCESS
379 @return EFI_DEVICE_ERROR
380 @return Others
381
382 **/
383 EFI_STATUS
384 EFIAPI
385 PxeBcDriverBindingStop (
386 IN EFI_DRIVER_BINDING_PROTOCOL *This,
387 IN EFI_HANDLE ControllerHandle,
388 IN UINTN NumberOfChildren,
389 IN EFI_HANDLE *ChildHandleBuffer
390 )
391 {
392 PXEBC_PRIVATE_DATA *Private;
393 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
394 EFI_HANDLE NicHandle;
395 EFI_STATUS Status;
396
397 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
398
399 if (NicHandle == NULL) {
400
401 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
402
403 if (NicHandle == NULL) {
404
405 return EFI_DEVICE_ERROR;
406 }
407 }
408
409 Status = gBS->OpenProtocol (
410 NicHandle,
411 &gEfiPxeBaseCodeProtocolGuid,
412 (VOID **) &PxeBc,
413 This->DriverBindingHandle,
414 ControllerHandle,
415 EFI_OPEN_PROTOCOL_GET_PROTOCOL
416 );
417
418 if (EFI_ERROR (Status)) {
419 return Status;
420 }
421
422 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);
423
424 Status = gBS->UninstallMultipleProtocolInterfaces (
425 NicHandle,
426 &gEfiPxeBaseCodeProtocolGuid,
427 &Private->PxeBc,
428 &gEfiLoadFileProtocolGuid,
429 &Private->LoadFile,
430 NULL
431 );
432
433 if (!EFI_ERROR (Status)) {
434
435 gBS->CloseProtocol (
436 Private->Udp4Child,
437 &gEfiUdp4ProtocolGuid,
438 This->DriverBindingHandle,
439 NicHandle
440 );
441 NetLibDestroyServiceChild (
442 NicHandle,
443 This->DriverBindingHandle,
444 &gEfiUdp4ServiceBindingProtocolGuid,
445 Private->Udp4Child
446 );
447
448 gBS->CloseProtocol (
449 Private->Dhcp4Child,
450 &gEfiDhcp4ProtocolGuid,
451 This->DriverBindingHandle,
452 NicHandle
453 );
454 NetLibDestroyServiceChild (
455 NicHandle,
456 This->DriverBindingHandle,
457 &gEfiDhcp4ServiceBindingProtocolGuid,
458 Private->Dhcp4Child
459 );
460
461 gBS->CloseProtocol (
462 Private->Mtftp4Child,
463 &gEfiMtftp4ProtocolGuid,
464 This->DriverBindingHandle,
465 NicHandle
466 );
467 NetLibDestroyServiceChild (
468 NicHandle,
469 This->DriverBindingHandle,
470 &gEfiMtftp4ServiceBindingProtocolGuid,
471 Private->Mtftp4Child
472 );
473
474 gBS->CloseProtocol (
475 Private->ArpChild,
476 &gEfiArpProtocolGuid,
477 This->DriverBindingHandle,
478 NicHandle
479 );
480 NetLibDestroyServiceChild (
481 NicHandle,
482 This->DriverBindingHandle,
483 &gEfiArpServiceBindingProtocolGuid,
484 Private->ArpChild
485 );
486
487 gBS->FreePool (Private);
488 }
489
490 return Status;
491 }
492
493 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {
494 PxeBcDriverBindingSupported,
495 PxeBcDriverBindingStart,
496 PxeBcDriverBindingStop,
497 0xa,
498 NULL,
499 NULL
500 };
501
502