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