]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - 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
1/** @file\r
2 The driver binding for IP4 CONFIG protocol.\r
3\r
4Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at<BR>\r
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
13**/\r
14\r
15\r
16#include "Ip4Config.h"\r
17#include "Ip4ConfigNv.h"\r
18#include "NicIp4Variable.h"\r
19\r
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
28\r
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
80 NULL,\r
81 NULL,\r
82 TRUE\r
83};\r
84\r
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
91\r
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
96EFI_STATUS\r
97EFIAPI\r
98Ip4ConfigDriverEntryPoint (\r
99 IN EFI_HANDLE ImageHandle,\r
100 IN EFI_SYSTEM_TABLE *SystemTable\r
101 )\r
102{\r
103 return EfiLibInstallDriverBindingComponentName2 (\r
104 ImageHandle,\r
105 SystemTable,\r
106 &gIp4ConfigDriverBinding,\r
107 ImageHandle,\r
108 &gIp4ConfigComponentName,\r
109 &gIp4ConfigComponentName2\r
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
176 NIC_IP4_CONFIG_INFO *NicConfig;\r
177 EFI_STATUS Status;\r
178 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
179\r
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
188\r
189 //\r
190 // Check for multiple start.\r
191 //\r
192 Status = gBS->OpenProtocol (\r
193 ControllerHandle,\r
194 &gEfiIp4ConfigProtocolGuid,\r
195 (VOID **) &Ip4Config,\r
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
239 Instance = AllocateCopyPool (sizeof (IP4_CONFIG_INSTANCE), &mIp4ConfigTemplate);\r
240\r
241 if (Instance == NULL) {\r
242 Status = EFI_OUT_OF_RESOURCES;\r
243 goto ON_ERROR;\r
244 }\r
245\r
246 Instance->Controller = ControllerHandle;\r
247 Instance->Image = This->DriverBindingHandle;\r
248 Instance->ParentDevicePath = ParentDevicePath;\r
249\r
250 CopyMem (&Instance->Ip4ConfigProtocol, &mIp4ConfigProtocolTemplate, sizeof (mIp4ConfigProtocolTemplate));\r
251\r
252 Instance->State = IP4_CONFIG_STATE_IDLE;\r
253 Instance->Mnp = Mnp;\r
254 Instance->MnpHandle = MnpHandle;\r
255\r
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
264 CopyMem (&Instance->NicAddr.MacAddr, &SnpMode.CurrentAddress, Instance->NicAddr.Len);\r
265\r
266 //\r
267 // Add it to the global list, and compose the name\r
268 //\r
269 Status = NetLibGetMacString (Instance->Controller, Instance->Image, &Instance->MacString);\r
270 if (EFI_ERROR (Status)) {\r
271 goto ON_ERROR;\r
272 }\r
273\r
274 Status = Ip4ConfigDeviceInit (Instance);\r
275\r
276 //\r
277 // Install the IP4_CONFIG protocols\r
278 //\r
279 Status = gBS->InstallMultipleProtocolInterfaces (\r
280 &ControllerHandle,\r
281 &gEfiIp4ConfigProtocolGuid,\r
282 &Instance->Ip4ConfigProtocol,\r
283 NULL\r
284 );\r
285\r
286 if (EFI_ERROR (Status)) {\r
287 goto ON_ERROR;\r
288 }\r
289\r
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
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 NicConfig = Ip4ConfigReadVariable (Instance);\r
310 if (NicConfig != NULL) {\r
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
330 FreePool (NicConfig);\r
331 }\r
332\r
333 return EFI_SUCCESS;\r
334\r
335ON_ERROR:\r
336 if (Instance != NULL) {\r
337 FreePool (Instance);\r
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
352 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
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
454 Ip4ConfigDeviceUnload (Instance);\r
455\r
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
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
492 if (Instance->MacString != NULL) {\r
493 FreePool (Instance->MacString);\r
494 }\r
495\r
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
502 Ip4ConfigCleanConfig (Instance);\r
503 FreePool (Instance);\r
504\r
505 return EFI_SUCCESS;\r
506}\r