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