}\r
\r
\r
+/**\r
+ The event handle for IP4 auto reconfiguration. The original default\r
+ interface and route table will be removed as the default.\r
+\r
+ @param[in] Context The IP4 service binding instance.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4AutoReconfigCallBackDpc (\r
+ IN VOID *Context\r
+ )\r
+{\r
+ IP4_SERVICE *IpSb;\r
+\r
+ IpSb = (IP4_SERVICE *) Context;\r
+ NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
+\r
+ if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
+ IpSb->State = IP4_SERVICE_UNSTARTED;\r
+ }\r
+\r
+ Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
+\r
+ return ;\r
+}\r
+\r
+\r
+/**\r
+ Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The event that is signalled.\r
+ @param Context The IP4 service binding instance.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4AutoReconfigCallBack (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ //\r
+ // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK\r
+ //\r
+ QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);\r
+}\r
+\r
\r
/**\r
Configure the IP4 child. If the child is already configured,\r
// been started, start it.\r
//\r
if (IpSb->State == IP4_SERVICE_UNSTARTED) {\r
+ //\r
+ // Create the ReconfigEvent to start the new configuration.\r
+ //\r
+ if (IpSb->ReconfigEvent == NULL) {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ Ip4AutoReconfigCallBack,\r
+ IpSb,\r
+ &IpSb->ReconfigEvent\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+ }\r
+ \r
Status = Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
\r
if (EFI_ERROR (Status)) {\r
- goto ON_ERROR;\r
+ goto CLOSE_RECONFIG_EVENT;\r
}\r
}\r
\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
if (EFI_ERROR (Status)) {\r
- goto ON_ERROR;\r
+ goto CLOSE_RECONFIG_EVENT;\r
}\r
}\r
InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);\r
\r
return EFI_SUCCESS;\r
\r
+CLOSE_RECONFIG_EVENT:\r
+ if (IpSb->ReconfigEvent != NULL) {\r
+ gBS->CloseEvent (IpSb->ReconfigEvent);\r
+ IpSb->ReconfigEvent = NULL;\r
+ }\r
+\r
ON_ERROR:\r
Ip4FreeRouteTable (IpInstance->RouteTable);\r
IpInstance->RouteTable = NULL;\r
\r
\r
/**\r
- The heart beat timer of IP4 service instance. It times out\r
- all of its IP4 children's received-but-not-delivered and\r
- transmitted-but-not-recycle packets, and provides time input\r
- for its IGMP protocol.\r
+ There are two steps for this the heart beat timer of IP4 service instance. \r
+ First, it times out all of its IP4 children's received-but-not-delivered \r
+ and transmitted-but-not-recycle packets, and provides time input for its \r
+ IGMP protocol.\r
+ Second, a dedicated timer is used to poll underlying media status. In case \r
+ of cable swap, a new round auto configuration will be initiated. The timer \r
+ will signal the IP4 to run DHCP configuration again. IP4 driver will free\r
+ old IP address related resource, such as route table and Interface, then\r
+ initiate a DHCP process to acquire new IP, eventually create route table \r
+ for new IP address.\r
\r
@param[in] Event The IP4 service instance's heart beat timer.\r
@param[in] Context The IP4 service instance.\r
)\r
{\r
IP4_SERVICE *IpSb;\r
+ BOOLEAN OldMediaPresent;\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_NETWORK_MODE SnpModeData;\r
\r
IpSb = (IP4_SERVICE *) Context;\r
NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
+ \r
+ OldMediaPresent = IpSb->MediaPresent;\r
\r
Ip4PacketTimerTicking (IpSb);\r
Ip4IgmpTicking (IpSb);\r
+\r
+ //\r
+ // Get fresh mode data from MNP, since underlying media status may change. \r
+ // Here, it needs to mention that the MediaPresent can also be checked even if \r
+ // EFI_NOT_STARTED returned while this MNP child driver instance isn't configured.\r
+ //\r
+ Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &SnpModeData);\r
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
+ return;\r
+ }\r
+\r
+ IpSb->MediaPresent = SnpModeData.MediaPresent;\r
+ //\r
+ // Media transimit Unpresent to Present means new link movement is detected.\r
+ //\r
+ if (!OldMediaPresent && IpSb->MediaPresent) {\r
+ //\r
+ // Signal the IP4 to run the dhcp configuration again. IP4 driver will free\r
+ // old IP address related resource, such as route table and Interface, then \r
+ // initiate a DHCP round to acquire new IP, eventually \r
+ // create route table for new IP address.\r
+ //\r
+ if (IpSb->ReconfigEvent != NULL) {\r
+ Status = gBS->SignalEvent (IpSb->ReconfigEvent);\r
+ DispatchDpc ();\r
+ }\r
+ }\r
}\r