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