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