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