]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDriver.c
Fix various 'EFIAPI' inconsistencies found while building MdeModulePkg.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4ConfigDriver.c
1 /** @file
2 The driver binding for IP4 CONFIG protocol.
3
4 Copyright (c) 2006 - 2009, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at<BR>
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15
16 #include "Ip4Config.h"
17
18 EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding = {
19 Ip4ConfigDriverBindingSupported,
20 Ip4ConfigDriverBindingStart,
21 Ip4ConfigDriverBindingStop,
22 0xa,
23 NULL,
24 NULL
25 };
26
27 /**
28 Stop all the auto configuration when the IP4 configure driver is
29 being unloaded.
30
31 @param ImageHandle The driver that is being unloaded
32
33 @retval EFI_SUCCESS The driver has been ready for unload.
34
35 **/
36 EFI_STATUS
37 EFIAPI
38 EfiIp4ConfigUnload (
39 IN EFI_HANDLE ImageHandle
40 )
41 {
42 UINT32 Index;
43
44 //
45 // Stop all the IP4_CONFIG instances
46 //
47 for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {
48 if (mIp4ConfigNicList[Index] == NULL) {
49 continue;
50 }
51
52 gIp4ConfigDriverBinding.Stop (
53 &gIp4ConfigDriverBinding,
54 mIp4ConfigNicList[Index]->MnpHandle,
55 0,
56 NULL
57 );
58 }
59
60 return NetLibDefaultUnload (ImageHandle);
61 }
62
63 /**
64 The entry point for IP4 config driver which install the driver
65 binding and component name protocol on its image.
66
67 @param ImageHandle The image handle of the driver.
68 @param SystemTable The system table.
69
70 @retval EFI_SUCCES All the related protocols are installed on the driver.
71 @retval Others Failed to install protocols.
72
73 **/
74 EFI_STATUS
75 EFIAPI
76 Ip4ConfigDriverEntryPoint (
77 IN EFI_HANDLE ImageHandle,
78 IN EFI_SYSTEM_TABLE *SystemTable
79 )
80 {
81 return EfiLibInstallDriverBindingComponentName2 (
82 ImageHandle,
83 SystemTable,
84 &gIp4ConfigDriverBinding,
85 ImageHandle,
86 &gIp4ConfigComponentName,
87 &gIp4ConfigComponentName2
88 );
89 }
90
91
92 /**
93 Test to see if this driver supports ControllerHandle.
94
95 @param This Protocol instance pointer.
96 @param ControllerHandle Handle of device to test
97 @param RemainingDevicePath Optional parameter use to pick a specific child
98 device to start.
99
100 @retval EFI_SUCCES This driver supports this device
101 @retval EFI_ALREADY_STARTED This driver is already running on this device
102 @retval other This driver does not support this device
103
104 **/
105 EFI_STATUS
106 EFIAPI
107 Ip4ConfigDriverBindingSupported (
108 IN EFI_DRIVER_BINDING_PROTOCOL *This,
109 IN EFI_HANDLE ControllerHandle,
110 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
111 )
112 {
113 EFI_STATUS Status;
114
115 Status = gBS->OpenProtocol (
116 ControllerHandle,
117 &gEfiManagedNetworkServiceBindingProtocolGuid,
118 NULL,
119 This->DriverBindingHandle,
120 ControllerHandle,
121 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
122 );
123
124 return Status;
125 }
126
127
128 /**
129 Start this driver on ControllerHandle.
130
131 @param This Protocol instance pointer.
132 @param ControllerHandle Handle of device to bind driver to
133 @param RemainingDevicePath Optional parameter use to pick a specific child
134 device to start.
135
136 @retval EFI_SUCCES This driver is added to ControllerHandle
137 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
138 @retval other This driver does not support this device
139
140 **/
141 EFI_STATUS
142 EFIAPI
143 Ip4ConfigDriverBindingStart (
144 IN EFI_DRIVER_BINDING_PROTOCOL *This,
145 IN EFI_HANDLE ControllerHandle,
146 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
147 )
148 {
149 EFI_IP4_CONFIG_PROTOCOL *Ip4Config;
150 EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
151 EFI_HANDLE MnpHandle;
152 IP4_CONFIG_INSTANCE *Instance;
153 EFI_SIMPLE_NETWORK_MODE SnpMode;
154 IP4_CONFIG_VARIABLE *Variable;
155 NIC_IP4_CONFIG_INFO *NicConfig;
156 IP4_CONFIG_VARIABLE *NewVariable;
157 EFI_STATUS Status;
158 UINT32 Index;
159
160 //
161 // Check for multiple start.
162 //
163 Status = gBS->OpenProtocol (
164 ControllerHandle,
165 &gEfiIp4ConfigProtocolGuid,
166 (VOID **) &Ip4Config,
167 This->DriverBindingHandle,
168 ControllerHandle,
169 EFI_OPEN_PROTOCOL_GET_PROTOCOL
170 );
171
172 if (!EFI_ERROR (Status)) {
173 return EFI_ALREADY_STARTED;
174 }
175
176 //
177 // Create a MNP child
178 //
179 Mnp = NULL;
180 MnpHandle = NULL;
181 Instance = NULL;
182
183 Status = NetLibCreateServiceChild (
184 ControllerHandle,
185 This->DriverBindingHandle,
186 &gEfiManagedNetworkServiceBindingProtocolGuid,
187 &MnpHandle
188 );
189
190 if (EFI_ERROR (Status)) {
191 return Status;
192 }
193
194 Status = gBS->OpenProtocol (
195 MnpHandle,
196 &gEfiManagedNetworkProtocolGuid,
197 (VOID **) &Mnp,
198 This->DriverBindingHandle,
199 ControllerHandle,
200 EFI_OPEN_PROTOCOL_BY_DRIVER
201 );
202
203 if (EFI_ERROR (Status)) {
204 goto ON_ERROR;
205 }
206
207 //
208 // Allocate an instance then initialize it
209 //
210 Instance = AllocatePool (sizeof (IP4_CONFIG_INSTANCE));
211
212 if (Instance == NULL) {
213 Status = EFI_OUT_OF_RESOURCES;
214 goto ON_ERROR;
215 }
216
217 Instance->Signature = IP4_CONFIG_INSTANCE_SIGNATURE;
218 Instance->Controller = ControllerHandle;
219 Instance->Image = This->DriverBindingHandle;
220
221 CopyMem (&Instance->Ip4ConfigProtocol, &mIp4ConfigProtocolTemplate, sizeof (mIp4ConfigProtocolTemplate));
222 CopyMem (&Instance->NicIp4Protocol, &mNicIp4ConfigProtocolTemplate, sizeof (mNicIp4ConfigProtocolTemplate));
223
224 Instance->State = IP4_CONFIG_STATE_IDLE;
225 Instance->Mnp = Mnp;
226 Instance->MnpHandle = MnpHandle;
227
228 Instance->DoneEvent = NULL;
229 Instance->ReconfigEvent = NULL;
230 Instance->Result = EFI_NOT_READY;
231 Instance->NicConfig = NULL;
232
233 Instance->Dhcp4 = NULL;
234 Instance->Dhcp4Handle = NULL;
235 Instance->Dhcp4Event = NULL;
236
237 Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
238
239 if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
240 goto ON_ERROR;
241 }
242
243 Instance->NicAddr.Type = (UINT16) SnpMode.IfType;
244 Instance->NicAddr.Len = (UINT8) SnpMode.HwAddressSize;
245 CopyMem (&Instance->NicAddr.MacAddr, &SnpMode.CurrentAddress, sizeof (Instance->NicAddr.MacAddr));
246
247 //
248 // Add it to the global list, and compose the name
249 //
250 for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {
251 if (mIp4ConfigNicList[Index] == NULL) {
252 mIp4ConfigNicList[Index] = Instance;
253 Instance->NicIndex = Index;
254
255 if (Instance->NicAddr.Type == NET_IFTYPE_ETHERNET) {
256 Instance->NicName[0] = 'e';
257 Instance->NicName[1] = 't';
258 Instance->NicName[2] = 'h';
259 Instance->NicName[3] = (UINT16) ('0' + Index);
260 Instance->NicName[4] = 0;
261 } else {
262 Instance->NicName[0] = 'u';
263 Instance->NicName[1] = 'n';
264 Instance->NicName[2] = 'k';
265 Instance->NicName[3] = (UINT16) ('0' + Index);
266 Instance->NicName[4] = 0;
267 }
268
269 break;
270 }
271 }
272
273 if (Index == MAX_IP4_CONFIG_IN_VARIABLE) {
274 Status = EFI_OUT_OF_RESOURCES;
275 goto ON_ERROR;
276 }
277
278 //
279 // Install the IP4_CONFIG and NIC_IP4CONFIG protocols
280 //
281 Status = gBS->InstallMultipleProtocolInterfaces (
282 &ControllerHandle,
283 &gEfiIp4ConfigProtocolGuid,
284 &Instance->Ip4ConfigProtocol,
285 &gEfiNicIp4ConfigProtocolGuid,
286 &Instance->NicIp4Protocol,
287 NULL
288 );
289
290 if (EFI_ERROR (Status)) {
291 mIp4ConfigNicList[Index] = NULL;
292 goto ON_ERROR;
293 }
294
295 //
296 // Get the previous configure parameters. If an error happend here,
297 // just ignore it because the driver should be able to operate.
298 //
299 Variable = Ip4ConfigReadVariable ();
300
301 if (Variable == NULL) {
302 return EFI_SUCCESS;
303 }
304
305 NicConfig = Ip4ConfigFindNicVariable (Variable, &Instance->NicAddr);
306
307 if (NicConfig == NULL) {
308 goto ON_EXIT;
309 }
310
311 //
312 // Don't modify the permant static configuration
313 //
314 if (NicConfig->Perment && (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC)) {
315 goto ON_EXIT;
316 }
317
318 //
319 // Delete the non-permant configuration and remove the previous
320 // acquired DHCP parameters. Only doing DHCP itself is permant
321 //
322 NewVariable = NULL;
323
324 if (!NicConfig->Perment) {
325 NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NULL);
326
327 } else if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {
328 ZeroMem (&NicConfig->Ip4Info, sizeof (EFI_IP4_IPCONFIG_DATA));
329 NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NicConfig);
330
331 }
332
333 Ip4ConfigWriteVariable (NewVariable);
334
335 if (NewVariable != NULL) {
336 gBS->FreePool (NewVariable);
337 }
338
339 ON_EXIT:
340 gBS->FreePool (Variable);
341
342 if (NicConfig != NULL) {
343 gBS->FreePool (NicConfig);
344 }
345
346 return EFI_SUCCESS;
347
348 ON_ERROR:
349 if (Instance != NULL) {
350 gBS->FreePool (Instance);
351 }
352
353 if (Mnp != NULL) {
354 gBS->CloseProtocol (
355 MnpHandle,
356 &gEfiManagedNetworkProtocolGuid,
357 This->DriverBindingHandle,
358 ControllerHandle
359 );
360 }
361
362 NetLibDestroyServiceChild (
363 ControllerHandle,
364 This->DriverBindingHandle,
365 &gEfiManagedNetworkProtocolGuid,
366 MnpHandle
367 );
368
369 return Status;
370 }
371
372
373 /**
374 Stop this driver on ControllerHandle.
375
376 @param This Protocol instance pointer.
377 @param ControllerHandle Handle of device to stop driver on
378 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
379 children is zero stop the entire bus driver.
380 @param ChildHandleBuffer List of Child Handles to Stop.
381
382 @retval EFI_SUCCES This driver is removed ControllerHandle
383 @retval other This driver was not removed from this device
384
385 **/
386 EFI_STATUS
387 EFIAPI
388 Ip4ConfigDriverBindingStop (
389 IN EFI_DRIVER_BINDING_PROTOCOL *This,
390 IN EFI_HANDLE ControllerHandle,
391 IN UINTN NumberOfChildren,
392 IN EFI_HANDLE *ChildHandleBuffer
393 )
394 {
395 IP4_CONFIG_INSTANCE *Instance;
396 EFI_IP4_CONFIG_PROTOCOL *Ip4Config;
397 EFI_HANDLE NicHandle;
398 EFI_STATUS Status;
399
400 //
401 // IP4_CONFIG instance opens an MNP child. It may also create and open
402 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
403 // it is the MNP child, stop the whole driver.
404 //
405 //
406 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
407
408 if (NicHandle != NULL) {
409 //
410 // Get our context back then clean the DHCP up. Notify the user if necessary.
411 //
412 Status = gBS->OpenProtocol (
413 NicHandle,
414 &gEfiIp4ConfigProtocolGuid,
415 (VOID **) &Ip4Config,
416 This->DriverBindingHandle,
417 ControllerHandle,
418 EFI_OPEN_PROTOCOL_GET_PROTOCOL
419 );
420
421 if (EFI_ERROR (Status)) {
422 return Status;
423 }
424
425 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);
426 ASSERT (ControllerHandle == Instance->Dhcp4Handle);
427
428 Ip4ConfigCleanDhcp4 (Instance);
429
430 Instance->State = IP4_CONFIG_STATE_CONFIGURED;
431 Instance->Result = EFI_DEVICE_ERROR;
432
433 if (Instance->DoneEvent != NULL) {
434 gBS->SignalEvent (Instance->DoneEvent);
435 }
436
437 return EFI_SUCCESS;
438 }
439
440 //
441 // This is a MNP handle, stop the whole driver
442 //
443 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
444
445 if (NicHandle == NULL) {
446 return EFI_SUCCESS;
447 }
448
449 //
450 // Get our context back.
451 //
452 Status = gBS->OpenProtocol (
453 NicHandle,
454 &gEfiIp4ConfigProtocolGuid,
455 (VOID **) &Ip4Config,
456 This->DriverBindingHandle,
457 ControllerHandle,
458 EFI_OPEN_PROTOCOL_GET_PROTOCOL
459 );
460
461 if (EFI_ERROR (Status)) {
462 return Status;
463 }
464
465 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);
466
467 //
468 // Unload the protocols first to inform the top drivers
469 //
470 Status = gBS->UninstallMultipleProtocolInterfaces (
471 NicHandle,
472 &gEfiIp4ConfigProtocolGuid,
473 &Instance->Ip4ConfigProtocol,
474 &gEfiNicIp4ConfigProtocolGuid,
475 &Instance->NicIp4Protocol,
476 NULL
477 );
478
479 if (EFI_ERROR (Status)) {
480 return Status;
481 }
482
483 //
484 // Release all the resources
485 //
486 if (Instance->MnpHandle != NULL) {
487 gBS->CloseProtocol (
488 Instance->MnpHandle,
489 &gEfiManagedNetworkProtocolGuid,
490 This->DriverBindingHandle,
491 NicHandle
492 );
493
494 NetLibDestroyServiceChild (
495 NicHandle,
496 Instance->Image,
497 &gEfiManagedNetworkServiceBindingProtocolGuid,
498 Instance->MnpHandle
499 );
500
501 Instance->Mnp = NULL;
502 Instance->MnpHandle = NULL;
503 }
504
505 Ip4ConfigCleanConfig (Instance);
506 mIp4ConfigNicList[Instance->NicIndex] = NULL;
507 gBS->FreePool (Instance);
508
509 return EFI_SUCCESS;
510 }
511