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