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