2 The driver binding for IP4 CONFIG protocol.
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
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.
16 #include "Ip4Config.h"
17 #include "Ip4ConfigNv.h"
18 #include "NicIp4Variable.h"
20 EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding
= {
21 Ip4ConfigDriverBindingSupported
,
22 Ip4ConfigDriverBindingStart
,
23 Ip4ConfigDriverBindingStop
,
30 // The intance of template of IP4 Config private data
32 IP4_CONFIG_INSTANCE mIp4ConfigTemplate
= {
33 IP4_CONFIG_INSTANCE_SIGNATURE
,
36 (EFI_DEVICE_PATH_PROTOCOL
*) NULL
,
48 (EFI_DEVICE_PATH_PROTOCOL
*) NULL
,
70 (EFI_MANAGED_NETWORK_PROTOCOL
*) NULL
,
85 (NIC_IP4_CONFIG_INFO
*) NULL
,
86 (EFI_DHCP4_PROTOCOL
*) NULL
,
95 The entry point for IP4 config driver which install the driver
96 binding and component name protocol on its image.
98 @param ImageHandle The image handle of the driver.
99 @param SystemTable The system table.
101 @retval EFI_SUCCES All the related protocols are installed on the driver.
102 @retval Others Failed to install protocols.
107 Ip4ConfigDriverEntryPoint (
108 IN EFI_HANDLE ImageHandle
,
109 IN EFI_SYSTEM_TABLE
*SystemTable
112 return EfiLibInstallDriverBindingComponentName2 (
115 &gIp4ConfigDriverBinding
,
117 &gIp4ConfigComponentName
,
118 &gIp4ConfigComponentName2
124 Test to see if this driver supports ControllerHandle.
126 @param This Protocol instance pointer.
127 @param ControllerHandle Handle of device to test
128 @param RemainingDevicePath Optional parameter use to pick a specific child
131 @retval EFI_SUCCES This driver supports this device
132 @retval EFI_ALREADY_STARTED This driver is already running on this device
133 @retval other This driver does not support this device
138 Ip4ConfigDriverBindingSupported (
139 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
140 IN EFI_HANDLE ControllerHandle
,
141 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
146 Status
= gBS
->OpenProtocol (
148 &gEfiManagedNetworkServiceBindingProtocolGuid
,
150 This
->DriverBindingHandle
,
152 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
160 Start this driver on ControllerHandle.
162 @param This Protocol instance pointer.
163 @param ControllerHandle Handle of device to bind driver to
164 @param RemainingDevicePath Optional parameter use to pick a specific child
167 @retval EFI_SUCCES This driver is added to ControllerHandle
168 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
169 @retval other This driver does not support this device
174 Ip4ConfigDriverBindingStart (
175 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
176 IN EFI_HANDLE ControllerHandle
,
177 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
180 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
181 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
182 EFI_HANDLE MnpHandle
;
183 IP4_CONFIG_INSTANCE
*Instance
;
184 EFI_SIMPLE_NETWORK_MODE SnpMode
;
185 NIC_IP4_CONFIG_INFO
*NicConfig
;
187 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
189 Status
= gBS
->HandleProtocol (
191 &gEfiDevicePathProtocolGuid
,
192 (VOID
**) &ParentDevicePath
194 if (EFI_ERROR (Status
)) {
199 // Check for multiple start.
201 Status
= gBS
->OpenProtocol (
203 &gEfiIp4ConfigProtocolGuid
,
204 (VOID
**) &Ip4Config
,
205 This
->DriverBindingHandle
,
207 EFI_OPEN_PROTOCOL_GET_PROTOCOL
210 if (!EFI_ERROR (Status
)) {
211 return EFI_ALREADY_STARTED
;
215 // Create a MNP child
221 Status
= NetLibCreateServiceChild (
223 This
->DriverBindingHandle
,
224 &gEfiManagedNetworkServiceBindingProtocolGuid
,
228 if (EFI_ERROR (Status
)) {
232 Status
= gBS
->OpenProtocol (
234 &gEfiManagedNetworkProtocolGuid
,
236 This
->DriverBindingHandle
,
238 EFI_OPEN_PROTOCOL_BY_DRIVER
241 if (EFI_ERROR (Status
)) {
246 // Allocate an instance then initialize it
248 Instance
= AllocateCopyPool (sizeof (IP4_CONFIG_INSTANCE
), &mIp4ConfigTemplate
);
250 if (Instance
== NULL
) {
251 Status
= EFI_OUT_OF_RESOURCES
;
255 Instance
->Controller
= ControllerHandle
;
256 Instance
->Image
= This
->DriverBindingHandle
;
257 Instance
->ParentDevicePath
= ParentDevicePath
;
259 CopyMem (&Instance
->Ip4ConfigProtocol
, &mIp4ConfigProtocolTemplate
, sizeof (mIp4ConfigProtocolTemplate
));
261 Instance
->State
= IP4_CONFIG_STATE_IDLE
;
263 Instance
->MnpHandle
= MnpHandle
;
265 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
267 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
271 Instance
->NicAddr
.Type
= (UINT16
) SnpMode
.IfType
;
272 Instance
->NicAddr
.Len
= (UINT8
) SnpMode
.HwAddressSize
;
273 CopyMem (&Instance
->NicAddr
.MacAddr
, &SnpMode
.CurrentAddress
, Instance
->NicAddr
.Len
);
276 // Add it to the global list, and compose the name
278 Status
= NetLibGetMacString (Instance
->Controller
, Instance
->Image
, &Instance
->MacString
);
279 if (EFI_ERROR (Status
)) {
283 Status
= Ip4ConfigDeviceInit (Instance
);
286 // Install the IP4_CONFIG protocols
288 Status
= gBS
->InstallMultipleProtocolInterfaces (
290 &gEfiIp4ConfigProtocolGuid
,
291 &Instance
->Ip4ConfigProtocol
,
295 if (EFI_ERROR (Status
)) {
300 // A dedicated timer is used to poll underlying media status.
302 Status
= gBS
->CreateEvent (
303 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
310 if (EFI_ERROR (Status
)) {
315 // Get the previous configure parameters. If an error happend here,
316 // just ignore it because the driver should be able to operate.
318 NicConfig
= Ip4ConfigReadVariable (Instance
);
319 if (NicConfig
!= NULL
) {
320 if (!NicConfig
->Perment
) {
322 // Delete the non-permanent configuration.
324 Ip4ConfigWriteVariable (Instance
, NULL
);
327 FreePool (NicConfig
);
333 if (Instance
!= NULL
) {
340 &gEfiManagedNetworkProtocolGuid
,
341 This
->DriverBindingHandle
,
346 NetLibDestroyServiceChild (
348 This
->DriverBindingHandle
,
349 &gEfiManagedNetworkServiceBindingProtocolGuid
,
358 Stop this driver on ControllerHandle.
360 @param This Protocol instance pointer.
361 @param ControllerHandle Handle of device to stop driver on
362 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
363 children is zero stop the entire bus driver.
364 @param ChildHandleBuffer List of Child Handles to Stop.
366 @retval EFI_SUCCES This driver is removed ControllerHandle
367 @retval other This driver was not removed from this device
372 Ip4ConfigDriverBindingStop (
373 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
374 IN EFI_HANDLE ControllerHandle
,
375 IN UINTN NumberOfChildren
,
376 IN EFI_HANDLE
*ChildHandleBuffer
379 IP4_CONFIG_INSTANCE
*Instance
;
380 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
381 EFI_HANDLE NicHandle
;
385 // IP4_CONFIG instance opens an MNP child. It may also create and open
386 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
387 // it is the MNP child, stop the whole driver.
390 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
392 if (NicHandle
!= NULL
) {
394 // Get our context back then clean the DHCP up. Notify the user if necessary.
396 Status
= gBS
->OpenProtocol (
398 &gEfiIp4ConfigProtocolGuid
,
399 (VOID
**) &Ip4Config
,
400 This
->DriverBindingHandle
,
402 EFI_OPEN_PROTOCOL_GET_PROTOCOL
405 if (EFI_ERROR (Status
)) {
409 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
410 ASSERT (ControllerHandle
== Instance
->Dhcp4Handle
);
412 Ip4ConfigCleanDhcp4 (Instance
);
414 Instance
->State
= IP4_CONFIG_STATE_CONFIGURED
;
415 Instance
->Result
= EFI_DEVICE_ERROR
;
417 if (Instance
->DoneEvent
!= NULL
) {
418 gBS
->SignalEvent (Instance
->DoneEvent
);
425 // This is a MNP handle, stop the whole driver
427 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
429 if (NicHandle
== NULL
) {
434 // Get our context back.
436 Status
= gBS
->OpenProtocol (
438 &gEfiIp4ConfigProtocolGuid
,
439 (VOID
**) &Ip4Config
,
440 This
->DriverBindingHandle
,
442 EFI_OPEN_PROTOCOL_GET_PROTOCOL
445 if (EFI_ERROR (Status
)) {
449 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
451 Ip4ConfigDeviceUnload (Instance
);
454 // Unload the protocols first to inform the top drivers
456 Status
= gBS
->UninstallMultipleProtocolInterfaces (
458 &gEfiIp4ConfigProtocolGuid
,
459 &Instance
->Ip4ConfigProtocol
,
463 if (EFI_ERROR (Status
)) {
468 // Release all the resources
470 if (Instance
->MnpHandle
!= NULL
) {
473 &gEfiManagedNetworkProtocolGuid
,
474 This
->DriverBindingHandle
,
478 NetLibDestroyServiceChild (
481 &gEfiManagedNetworkServiceBindingProtocolGuid
,
485 Instance
->Mnp
= NULL
;
486 Instance
->MnpHandle
= NULL
;
489 if (Instance
->MacString
!= NULL
) {
490 FreePool (Instance
->MacString
);
493 if (Instance
->Timer
!= NULL
) {
494 gBS
->SetTimer (Instance
->Timer
, TimerCancel
, 0);
495 gBS
->CloseEvent (Instance
->Timer
);
496 Instance
->Timer
= NULL
;
499 Ip4ConfigCleanConfig (Instance
);