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