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