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