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