]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
Code refinement.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4Config.c
CommitLineData
b2570da8 1/** @file\r
402fa70f 2 This code implements the IP4Config and NicIp4Config protocols.\r
b2570da8 3\r
74df5026 4Copyright (c) 2006 - 2010, 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#include "Ip4Config.h"\r
74df5026 16#include "NicIp4Variable.h"\r
b2570da8 17\r
b2570da8 18\r
19/**\r
c8d8f1e3 20 Get the NIC's configure information from the IP4 configure variable.\r
b2570da8 21 It will remove the invalid variable.\r
22\r
74df5026 23 @param Instance The IP4 CONFIG instance.\r
b2570da8 24\r
25 @return NULL if no configure for the NIC in the variable, or it is invalid.\r
c8d8f1e3 26 Otherwise the pointer to the NIC's IP configure parameter will be returned.\r
b2570da8 27\r
28**/\r
29NIC_IP4_CONFIG_INFO *\r
74df5026 30EfiNicIp4ConfigGetInfo (\r
31 IN IP4_CONFIG_INSTANCE *Instance\r
b2570da8 32 )\r
33{\r
74df5026 34 NIC_IP4_CONFIG_INFO *NicConfig;\r
b2570da8 35\r
36 //\r
74df5026 37 // Read the configuration parameter for this NIC from\r
b2570da8 38 // the EFI variable\r
39 //\r
74df5026 40 NicConfig = Ip4ConfigReadVariable (Instance);\r
41 if (NicConfig == NULL) {\r
b2570da8 42 return NULL;\r
43 }\r
44\r
45 //\r
46 // Validate the configuration, if the configuration is invalid,\r
47 // remove it from the variable.\r
48 //\r
74df5026 49 if (!Ip4ConfigIsValid (NicConfig)) {\r
50 Ip4ConfigWriteVariable (Instance, NULL);\r
b2570da8 51\r
74df5026 52 FreePool (NicConfig);\r
53 NicConfig = NULL;\r
b2570da8 54 }\r
55\r
74df5026 56 return NicConfig;\r
b2570da8 57}\r
58\r
b2570da8 59/**\r
d80ea739 60 Set the IP configure parameters for this NIC.\r
c8d8f1e3 61\r
d80ea739 62 If Reconfig is TRUE, the IP driver will be informed to discard current\r
63 auto configure parameter and restart the auto configuration process.\r
c8d8f1e3 64 If current there is a pending auto configuration, EFI_ALREADY_STARTED is\r
b2570da8 65 returned. You can only change the configure setting when either\r
66 the configure has finished or not started yet. If NicConfig, the\r
67 NIC's configure parameter is removed from the variable.\r
68\r
63886849 69 @param Instance The IP4 CONFIG instance.\r
d80ea739 70 @param NicConfig The new NIC IP4 configure parameter.\r
b2570da8 71 @param Reconfig Inform the IP4 driver to restart the auto\r
d80ea739 72 configuration.\r
73\r
74 @retval EFI_SUCCESS The configure parameter for this NIC was\r
75 set successfully.\r
b2570da8 76 @retval EFI_INVALID_PARAMETER This is NULL or the configure parameter is\r
77 invalid.\r
78 @retval EFI_ALREADY_STARTED There is a pending auto configuration.\r
d80ea739 79 @retval EFI_NOT_FOUND No auto configure parameter is found.\r
b2570da8 80\r
81**/\r
82EFI_STATUS\r
83EFIAPI\r
84EfiNicIp4ConfigSetInfo (\r
63886849 85 IN IP4_CONFIG_INSTANCE *Instance,\r
3e8c18da 86 IN NIC_IP4_CONFIG_INFO *NicConfig OPTIONAL,\r
b2570da8 87 IN BOOLEAN Reconfig\r
88 )\r
89{\r
74df5026 90 EFI_STATUS Status;\r
b2570da8 91\r
92 //\r
93 // Validate the parameters\r
94 //\r
63886849 95 if (Instance == NULL) {\r
b2570da8 96 return EFI_INVALID_PARAMETER;\r
97 }\r
98\r
b2570da8 99 if ((NicConfig != NULL) && (!Ip4ConfigIsValid (NicConfig) ||\r
100 !NIC_ADDR_EQUAL (&NicConfig->NicAddr, &Instance->NicAddr))) {\r
101 return EFI_INVALID_PARAMETER;\r
102 }\r
103\r
104 if (Instance->State == IP4_CONFIG_STATE_STARTED) {\r
105 return EFI_ALREADY_STARTED;\r
106 }\r
107\r
108 //\r
109 // Update the parameter in the configure variable\r
110 //\r
74df5026 111 Status = Ip4ConfigWriteVariable (Instance, NicConfig);\r
b2570da8 112 if (EFI_ERROR (Status)) {\r
113 return Status;\r
114 }\r
115\r
116 //\r
117 // Signal the IP4 to run the auto configuration again\r
118 //\r
119 if (Reconfig && (Instance->ReconfigEvent != NULL)) {\r
120 Status = gBS->SignalEvent (Instance->ReconfigEvent);\r
d8d26fb2 121 DispatchDpc ();\r
b2570da8 122 }\r
123\r
124 return Status;\r
125}\r
126\r
c8d8f1e3 127/**\r
128 Callback function when DHCP process finished. It will save the\r
129 retrieved IP configure parameter from DHCP to the NVRam.\r
130\r
131 @param Event The callback event\r
132 @param Context Opaque context to the callback\r
133\r
134 @return None\r
135\r
136**/\r
137VOID\r
138EFIAPI\r
139Ip4ConfigOnDhcp4Complete (\r
140 IN EFI_EVENT Event,\r
141 IN VOID *Context\r
142 )\r
143{\r
144 IP4_CONFIG_INSTANCE *Instance;\r
145 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
146 EFI_IP4_IPCONFIG_DATA *Ip4Config;\r
147 EFI_STATUS Status;\r
148 BOOLEAN Perment;\r
149 IP4_ADDR Subnet;\r
150 IP4_ADDR Ip1;\r
151 IP4_ADDR Ip2;\r
152\r
153 Instance = (IP4_CONFIG_INSTANCE *) Context;\r
154 ASSERT (Instance->Dhcp4 != NULL);\r
155\r
156 Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
157 Instance->Result = EFI_TIMEOUT;\r
158\r
159 //\r
160 // Get the DHCP retrieved parameters\r
161 //\r
162 Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);\r
163\r
164 if (EFI_ERROR (Status)) {\r
165 goto ON_EXIT;\r
166 }\r
167\r
168 if (Dhcp4Mode.State == Dhcp4Bound) {\r
169 //\r
170 // Save the new configuration retrieved by DHCP both in\r
171 // the instance and to NVRam. So, both the IP4 driver and\r
172 // other user can get that address.\r
173 //\r
174 Perment = FALSE;\r
175\r
176 if (Instance->NicConfig != NULL) {\r
177 ASSERT (Instance->NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);\r
178 Perment = Instance->NicConfig->Perment;\r
766c7483 179 FreePool (Instance->NicConfig);\r
c8d8f1e3 180 }\r
181\r
182 Instance->NicConfig = AllocatePool (sizeof (NIC_IP4_CONFIG_INFO) + 2* sizeof (EFI_IP4_ROUTE_TABLE));\r
183\r
184 if (Instance->NicConfig == NULL) {\r
185 Instance->Result = EFI_OUT_OF_RESOURCES;\r
186 goto ON_EXIT;\r
187 }\r
188\r
189 Instance->NicConfig->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (Instance->NicConfig + 1);\r
190\r
191 CopyMem (&Instance->NicConfig->NicAddr, &Instance->NicAddr, sizeof (Instance->NicConfig->NicAddr));\r
192 Instance->NicConfig->Source = IP4_CONFIG_SOURCE_DHCP;\r
193 Instance->NicConfig->Perment = Perment;\r
194\r
195 Ip4Config = &Instance->NicConfig->Ip4Info;\r
196 Ip4Config->StationAddress = Dhcp4Mode.ClientAddress;\r
197 Ip4Config->SubnetMask = Dhcp4Mode.SubnetMask;\r
198\r
199 //\r
200 // Create a route for the connected network\r
201 //\r
202 Ip4Config->RouteTableSize = 1;\r
203\r
204 CopyMem (&Ip1, &Dhcp4Mode.ClientAddress, sizeof (IP4_ADDR));\r
205 CopyMem (&Ip2, &Dhcp4Mode.SubnetMask, sizeof (IP4_ADDR));\r
206\r
207 Subnet = Ip1 & Ip2;\r
208\r
209 CopyMem (&Ip4Config->RouteTable[0].SubnetAddress, &Subnet, sizeof (EFI_IPv4_ADDRESS));\r
210 CopyMem (&Ip4Config->RouteTable[0].SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
211 ZeroMem (&Ip4Config->RouteTable[0].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
212\r
213 //\r
214 // Create a route if there is a default router.\r
215 //\r
216 if (!EFI_IP4_EQUAL (&Dhcp4Mode.RouterAddress, &mZeroIp4Addr)) {\r
217 Ip4Config->RouteTableSize = 2;\r
218\r
219 ZeroMem (&Ip4Config->RouteTable[1].SubnetAddress, sizeof (EFI_IPv4_ADDRESS));\r
220 ZeroMem (&Ip4Config->RouteTable[1].SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
221 CopyMem (&Ip4Config->RouteTable[1].GatewayAddress, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
222 }\r
223\r
224 Instance->Result = EFI_SUCCESS;\r
225\r
226 //\r
227 // ignore the return status of EfiNicIp4ConfigSetInfo. Network\r
228 // stack can operate even that failed.\r
229 //\r
63886849 230 EfiNicIp4ConfigSetInfo (Instance, Instance->NicConfig, FALSE);\r
c8d8f1e3 231 }\r
232\r
233ON_EXIT:\r
234 gBS->SignalEvent (Instance->DoneEvent);\r
235 Ip4ConfigCleanDhcp4 (Instance);\r
236\r
d8d26fb2 237 DispatchDpc ();\r
c8d8f1e3 238\r
239 return ;\r
240}\r
b2570da8 241\r
242/**\r
402fa70f 243 Starts running the configuration policy for the EFI IPv4 Protocol driver.\r
d80ea739 244\r
245 The Start() function is called to determine and to begin the platform\r
246 configuration policy by the EFI IPv4 Protocol driver. This determination may\r
247 be as simple as returning EFI_UNSUPPORTED if there is no EFI IPv4 Protocol\r
248 driver configuration policy. It may be as involved as loading some defaults\r
249 from nonvolatile storage, downloading dynamic data from a DHCP server, and\r
402fa70f 250 checking permissions with a site policy server.\r
d80ea739 251 Starting the configuration policy is just the beginning. It may finish almost\r
252 instantly or it may take several minutes before it fails to retrieve configuration\r
253 information from one or more servers. Once the policy is started, drivers\r
254 should use the DoneEvent parameter to determine when the configuration policy\r
255 has completed. EFI_IP4_CONFIG_PROTOCOL.GetData() must then be called to\r
402fa70f 256 determine if the configuration succeeded or failed.\r
d80ea739 257 Until the configuration completes successfully, EFI IPv4 Protocol driver instances\r
402fa70f 258 that are attempting to use default configurations must return EFI_NO_MAPPING.\r
d80ea739 259 Once the configuration is complete, the EFI IPv4 Configuration Protocol driver\r
260 signals DoneEvent. The configuration may need to be updated in the future,\r
261 however; in this case, the EFI IPv4 Configuration Protocol driver must signal\r
262 ReconfigEvent, and all EFI IPv4 Protocol driver instances that are using default\r
263 configurations must return EFI_NO_MAPPING until the configuration policy has\r
402fa70f 264 been rerun.\r
265\r
266 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.\r
d80ea739 267 @param DoneEvent Event that will be signaled when the EFI IPv4\r
268 Protocol driver configuration policy completes\r
402fa70f 269 execution. This event must be of type EVT_NOTIFY_SIGNAL.\r
d80ea739 270 @param ReconfigEvent Event that will be signaled when the EFI IPv4\r
271 Protocol driver configuration needs to be updated.\r
402fa70f 272 This event must be of type EVT_NOTIFY_SIGNAL.\r
d80ea739 273\r
274 @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol\r
402fa70f 275 driver is now running.\r
276 @retval EFI_INVALID_PARAMETER One or more of the following parameters is NULL:\r
277 This\r
278 DoneEvent\r
279 ReconfigEvent\r
280 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
d80ea739 281 @retval EFI_ALREADY_STARTED The configuration policy for the EFI IPv4 Protocol\r
402fa70f 282 driver was already started.\r
283 @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.\r
d80ea739 284 @retval EFI_UNSUPPORTED This interface does not support the EFI IPv4 Protocol\r
402fa70f 285 driver configuration.\r
b2570da8 286\r
287**/\r
288EFI_STATUS\r
289EFIAPI\r
290EfiIp4ConfigStart (\r
291 IN EFI_IP4_CONFIG_PROTOCOL *This,\r
292 IN EFI_EVENT DoneEvent,\r
293 IN EFI_EVENT ReconfigEvent\r
294 )\r
295{\r
296 IP4_CONFIG_INSTANCE *Instance;\r
297 EFI_DHCP4_PROTOCOL *Dhcp4;\r
298 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
299 EFI_DHCP4_PACKET_OPTION *OptionList[1];\r
300 IP4_CONFIG_DHCP4_OPTION ParaList;\r
301 EFI_STATUS Status;\r
302 UINT32 Source;\r
303 EFI_TPL OldTpl;\r
304\r
305 if ((This == NULL) || (DoneEvent == NULL) || (ReconfigEvent == NULL)) {\r
306 return EFI_INVALID_PARAMETER;\r
307 }\r
308\r
309 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
310\r
e48e37fc 311 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
b2570da8 312\r
313 if (Instance->State != IP4_CONFIG_STATE_IDLE) {\r
314 Status = EFI_ALREADY_STARTED;\r
315\r
316 goto ON_EXIT;\r
317 }\r
318\r
319 Instance->DoneEvent = DoneEvent;\r
320 Instance->ReconfigEvent = ReconfigEvent;\r
321\r
74df5026 322 Instance->NicConfig = EfiNicIp4ConfigGetInfo (Instance);\r
b2570da8 323\r
324 if (Instance->NicConfig == NULL) {\r
325 Source = IP4_CONFIG_SOURCE_DHCP;\r
326 } else {\r
327 Source = Instance->NicConfig->Source;\r
328 }\r
329\r
330 //\r
331 // If the source is static, the auto configuration is done.\r
332 // return now.\r
333 //\r
334 if (Source == IP4_CONFIG_SOURCE_STATIC) {\r
335 Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
336 Instance->Result = EFI_SUCCESS;\r
337\r
338 gBS->SignalEvent (Instance->DoneEvent);\r
339 Status = EFI_SUCCESS;\r
340 goto ON_EXIT;\r
341 }\r
342\r
343 //\r
344 // Start the dhcp process\r
345 //\r
346 ASSERT ((Source == IP4_CONFIG_SOURCE_DHCP) && (Instance->Dhcp4 == NULL));\r
347\r
348 Status = NetLibCreateServiceChild (\r
349 Instance->Controller,\r
350 Instance->Image,\r
351 &gEfiDhcp4ServiceBindingProtocolGuid,\r
352 &Instance->Dhcp4Handle\r
353 );\r
354\r
355 if (EFI_ERROR (Status)) {\r
356 goto ON_ERROR;\r
357 }\r
358\r
359 Status = gBS->OpenProtocol (\r
360 Instance->Dhcp4Handle,\r
361 &gEfiDhcp4ProtocolGuid,\r
362 (VOID **) &Instance->Dhcp4,\r
363 Instance->Image,\r
364 Instance->Controller,\r
365 EFI_OPEN_PROTOCOL_BY_DRIVER\r
366 );\r
367\r
368 if (EFI_ERROR (Status)) {\r
369 goto ON_ERROR;\r
370 }\r
371\r
372 //\r
373 // Check the current DHCP status, if the DHCP process has\r
374 // already finished, return now.\r
375 //\r
376 Dhcp4 = Instance->Dhcp4;\r
377 Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
378\r
379 if (EFI_ERROR (Status)) {\r
380 goto ON_ERROR;\r
381 }\r
382\r
383 if (Dhcp4Mode.State == Dhcp4Bound) {\r
384 Ip4ConfigOnDhcp4Complete (NULL, Instance);\r
385\r
386 goto ON_EXIT;\r
387 }\r
388\r
389 //\r
390 // Try to start the DHCP process. Use most of the current\r
391 // DHCP configuration to avoid problems if some DHCP client\r
392 // yields the control of this DHCP service to us.\r
393 //\r
394 ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;\r
395 ParaList.Head.Length = 2;\r
396 ParaList.Head.Data[0] = DHCP_TAG_NETMASK;\r
397 ParaList.Route = DHCP_TAG_ROUTER;\r
398 OptionList[0] = &ParaList.Head;\r
399 Dhcp4Mode.ConfigData.OptionCount = 1;\r
400 Dhcp4Mode.ConfigData.OptionList = OptionList;\r
401\r
402 Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);\r
403\r
404 if (EFI_ERROR (Status)) {\r
405 goto ON_ERROR;\r
406 }\r
407\r
408 //\r
409 // Start the DHCP process\r
410 //\r
411 Status = gBS->CreateEvent (\r
412 EVT_NOTIFY_SIGNAL,\r
e48e37fc 413 TPL_CALLBACK,\r
b2570da8 414 Ip4ConfigOnDhcp4Complete,\r
415 Instance,\r
416 &Instance->Dhcp4Event\r
417 );\r
418\r
419 if (EFI_ERROR (Status)) {\r
420 goto ON_ERROR;\r
421 }\r
422\r
423 Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);\r
424\r
425 if (EFI_ERROR (Status)) {\r
426 goto ON_ERROR;\r
427 }\r
428\r
429 Instance->State = IP4_CONFIG_STATE_STARTED;\r
430 Instance->Result = EFI_NOT_READY;\r
431\r
432ON_ERROR:\r
433 if (EFI_ERROR (Status)) {\r
434 Ip4ConfigCleanConfig (Instance);\r
435 }\r
436\r
437ON_EXIT:\r
e48e37fc 438 gBS->RestoreTPL (OldTpl);\r
b2570da8 439\r
d8d26fb2 440 DispatchDpc ();\r
7659d0c9 441\r
b2570da8 442 return Status;\r
443}\r
444\r
445\r
446/**\r
402fa70f 447 Stops running the configuration policy for the EFI IPv4 Protocol driver.\r
d80ea739 448\r
449 The Stop() function stops the configuration policy for the EFI IPv4 Protocol driver.\r
402fa70f 450 All configuration data will be lost after calling Stop().\r
b2570da8 451\r
402fa70f 452 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.\r
b2570da8 453\r
d80ea739 454 @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol\r
402fa70f 455 driver has been stopped.\r
b2570da8 456 @retval EFI_INVALID_PARAMETER This is NULL.\r
d80ea739 457 @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol\r
402fa70f 458 driver was not started.\r
d80ea739 459\r
b2570da8 460**/\r
461EFI_STATUS\r
462EFIAPI\r
463EfiIp4ConfigStop (\r
464 IN EFI_IP4_CONFIG_PROTOCOL *This\r
465 )\r
466{\r
467 IP4_CONFIG_INSTANCE *Instance;\r
468 EFI_STATUS Status;\r
469 EFI_TPL OldTpl;\r
470\r
471 if (This == NULL) {\r
472 return EFI_INVALID_PARAMETER;\r
473 }\r
474\r
475 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
476\r
477 Status = EFI_SUCCESS;\r
e48e37fc 478 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
b2570da8 479\r
480 if (Instance->State == IP4_CONFIG_STATE_IDLE) {\r
481 Status = EFI_NOT_STARTED;\r
482 goto ON_EXIT;\r
483 }\r
484\r
485 //\r
486 // Release all the configure parameters. Don't signal the user\r
487 // event. The user wants to abort the configuration, this isn't\r
488 // the configuration done or reconfiguration.\r
489 //\r
490 Ip4ConfigCleanConfig (Instance);\r
491\r
492ON_EXIT:\r
e48e37fc 493 gBS->RestoreTPL (OldTpl);\r
b2570da8 494\r
495 return Status;\r
496}\r
497\r
498\r
499/**\r
402fa70f 500 Returns the default configuration data (if any) for the EFI IPv4 Protocol driver.\r
501\r
d80ea739 502 The GetData() function returns the current configuration data for the EFI IPv4\r
402fa70f 503 Protocol driver after the configuration policy has completed.\r
d80ea739 504\r
402fa70f 505 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.\r
d80ea739 506 @param ConfigDataSize On input, the size of the ConfigData buffer.\r
507 On output, the count of bytes that were written\r
402fa70f 508 into the ConfigData buffer.\r
d80ea739 509 @param ConfigData Pointer to the EFI IPv4 Configuration Protocol\r
510 driver configuration data structure.\r
511 Type EFI_IP4_IPCONFIG_DATA is defined in\r
402fa70f 512 "Related Definitions" below.\r
513\r
514 @retval EFI_SUCCESS The EFI IPv4 Protocol driver configuration has been returned.\r
515 @retval EFI_INVALID_PARAMETER This is NULL.\r
d80ea739 516 @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol\r
402fa70f 517 driver is not running.\r
c8d8f1e3 518 @retval EFI_NOT_READY EFI IPv4 Protocol driver configuration is still running.\r
519 @retval EFI_ABORTED EFI IPv4 Protocol driver configuration could not complete.\r
520 Currently not implemented.\r
d80ea739 521 @retval EFI_BUFFER_TOO_SMALL *ConfigDataSize is smaller than the configuration\r
402fa70f 522 data buffer or ConfigData is NULL.\r
b2570da8 523\r
524**/\r
525EFI_STATUS\r
526EFIAPI\r
527EfiIp4ConfigGetData (\r
528 IN EFI_IP4_CONFIG_PROTOCOL *This,\r
529 IN OUT UINTN *ConfigDataSize,\r
530 OUT EFI_IP4_IPCONFIG_DATA *ConfigData OPTIONAL\r
531 )\r
532{\r
533 IP4_CONFIG_INSTANCE *Instance;\r
534 NIC_IP4_CONFIG_INFO *NicConfig;\r
535 EFI_STATUS Status;\r
536 EFI_TPL OldTpl;\r
537 UINTN Len;\r
538\r
539 if ((This == NULL) || (ConfigDataSize == NULL)) {\r
540 return EFI_INVALID_PARAMETER;\r
541 }\r
542\r
543 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
544\r
545 Status = EFI_SUCCESS;\r
e48e37fc 546 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
b2570da8 547\r
548 if (Instance->State == IP4_CONFIG_STATE_IDLE) {\r
549 Status = EFI_NOT_STARTED;\r
550 } else if (Instance->State == IP4_CONFIG_STATE_STARTED) {\r
551 Status = EFI_NOT_READY;\r
552 }\r
553\r
554 if (EFI_ERROR (Status)) {\r
555 goto ON_EXIT;\r
556 }\r
557\r
558 //\r
559 // Copy the configure data if auto configuration succeeds.\r
560 //\r
561 Status = Instance->Result;\r
562\r
563 if (Status == EFI_SUCCESS) {\r
564 ASSERT (Instance->NicConfig != NULL);\r
565\r
566 NicConfig = Instance->NicConfig;\r
567 Len = SIZEOF_IP4_CONFIG_INFO (&NicConfig->Ip4Info);\r
568\r
569 if ((*ConfigDataSize < Len) || (ConfigData == NULL)) {\r
570 Status = EFI_BUFFER_TOO_SMALL;\r
571 } else {\r
e48e37fc 572 CopyMem (ConfigData, &NicConfig->Ip4Info, Len);\r
7659d0c9 573 Ip4ConfigFixRouteTablePointer (ConfigData);\r
b2570da8 574 }\r
575\r
576 *ConfigDataSize = Len;\r
577 }\r
578\r
579ON_EXIT:\r
e48e37fc 580 gBS->RestoreTPL (OldTpl);\r
b2570da8 581\r
582 return Status;\r
583}\r
584\r
b2570da8 585/**\r
586 Release all the DHCP related resources.\r
587\r
588 @param This The IP4 configure instance\r
589\r
590 @return None\r
591\r
592**/\r
593VOID\r
594Ip4ConfigCleanDhcp4 (\r
595 IN IP4_CONFIG_INSTANCE *This\r
596 )\r
597{\r
598 if (This->Dhcp4 != NULL) {\r
599 This->Dhcp4->Stop (This->Dhcp4);\r
600\r
601 gBS->CloseProtocol (\r
602 This->Dhcp4Handle,\r
603 &gEfiDhcp4ProtocolGuid,\r
604 This->Image,\r
605 This->Controller\r
606 );\r
607\r
608 This->Dhcp4 = NULL;\r
609 }\r
610\r
611 if (This->Dhcp4Handle != NULL) {\r
612 NetLibDestroyServiceChild (\r
613 This->Controller,\r
614 This->Image,\r
615 &gEfiDhcp4ServiceBindingProtocolGuid,\r
616 This->Dhcp4Handle\r
617 );\r
618\r
619 This->Dhcp4Handle = NULL;\r
620 }\r
621\r
622 if (This->Dhcp4Event == NULL) {\r
623 gBS->CloseEvent (This->Dhcp4Event);\r
624 This->Dhcp4Event = NULL;\r
625 }\r
626}\r
627\r
628\r
629/**\r
7bce0c5a 630 Clean up all the configuration parameters.\r
b2570da8 631\r
632 @param Instance The IP4 configure instance\r
633\r
634 @return None\r
635\r
636**/\r
637VOID\r
638Ip4ConfigCleanConfig (\r
639 IN IP4_CONFIG_INSTANCE *Instance\r
640 )\r
641{\r
642 if (Instance->NicConfig != NULL) {\r
766c7483 643 FreePool (Instance->NicConfig);\r
b2570da8 644 Instance->NicConfig = NULL;\r
645 }\r
646\r
647 Instance->State = IP4_CONFIG_STATE_IDLE;\r
648 Instance->DoneEvent = NULL;\r
649 Instance->ReconfigEvent = NULL;\r
650\r
651 Ip4ConfigCleanDhcp4 (Instance);\r
652}\r
653\r
654EFI_IP4_CONFIG_PROTOCOL mIp4ConfigProtocolTemplate = {\r
655 EfiIp4ConfigStart,\r
656 EfiIp4ConfigStop,\r
657 EfiIp4ConfigGetData\r
658};\r
659\r