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