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