2 The driver binding for IP4 CONFIG protocol.
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
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
,
64 (EFI_MANAGED_NETWORK_PROTOCOL
*) NULL
,
77 (NIC_IP4_CONFIG_INFO
*) NULL
,
78 (EFI_DHCP4_PROTOCOL
*) NULL
,
86 The entry point for IP4 config driver which install the driver
87 binding and component name protocol on its image.
89 @param ImageHandle The image handle of the driver.
90 @param SystemTable The system table.
92 @retval EFI_SUCCES All the related protocols are installed on the driver.
93 @retval Others Failed to install protocols.
98 Ip4ConfigDriverEntryPoint (
99 IN EFI_HANDLE ImageHandle
,
100 IN EFI_SYSTEM_TABLE
*SystemTable
103 return EfiLibInstallDriverBindingComponentName2 (
106 &gIp4ConfigDriverBinding
,
108 &gIp4ConfigComponentName
,
109 &gIp4ConfigComponentName2
115 Test to see if this driver supports ControllerHandle.
117 @param This Protocol instance pointer.
118 @param ControllerHandle Handle of device to test
119 @param RemainingDevicePath Optional parameter use to pick a specific child
122 @retval EFI_SUCCES This driver supports this device
123 @retval EFI_ALREADY_STARTED This driver is already running on this device
124 @retval other This driver does not support this device
129 Ip4ConfigDriverBindingSupported (
130 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
131 IN EFI_HANDLE ControllerHandle
,
132 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
137 Status
= gBS
->OpenProtocol (
139 &gEfiManagedNetworkServiceBindingProtocolGuid
,
141 This
->DriverBindingHandle
,
143 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
151 Start this driver on ControllerHandle.
153 @param This Protocol instance pointer.
154 @param ControllerHandle Handle of device to bind driver to
155 @param RemainingDevicePath Optional parameter use to pick a specific child
158 @retval EFI_SUCCES This driver is added to ControllerHandle
159 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
160 @retval other This driver does not support this device
165 Ip4ConfigDriverBindingStart (
166 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
167 IN EFI_HANDLE ControllerHandle
,
168 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
171 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
172 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
173 EFI_HANDLE MnpHandle
;
174 IP4_CONFIG_INSTANCE
*Instance
;
175 EFI_SIMPLE_NETWORK_MODE SnpMode
;
176 NIC_IP4_CONFIG_INFO
*NicConfig
;
178 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
180 Status
= gBS
->HandleProtocol (
182 &gEfiDevicePathProtocolGuid
,
183 (VOID
**) &ParentDevicePath
185 if (EFI_ERROR (Status
)) {
190 // Check for multiple start.
192 Status
= gBS
->OpenProtocol (
194 &gEfiIp4ConfigProtocolGuid
,
195 (VOID
**) &Ip4Config
,
196 This
->DriverBindingHandle
,
198 EFI_OPEN_PROTOCOL_GET_PROTOCOL
201 if (!EFI_ERROR (Status
)) {
202 return EFI_ALREADY_STARTED
;
206 // Create a MNP child
212 Status
= NetLibCreateServiceChild (
214 This
->DriverBindingHandle
,
215 &gEfiManagedNetworkServiceBindingProtocolGuid
,
219 if (EFI_ERROR (Status
)) {
223 Status
= gBS
->OpenProtocol (
225 &gEfiManagedNetworkProtocolGuid
,
227 This
->DriverBindingHandle
,
229 EFI_OPEN_PROTOCOL_BY_DRIVER
232 if (EFI_ERROR (Status
)) {
237 // Allocate an instance then initialize it
239 Instance
= AllocateCopyPool (sizeof (IP4_CONFIG_INSTANCE
), &mIp4ConfigTemplate
);
241 if (Instance
== NULL
) {
242 Status
= EFI_OUT_OF_RESOURCES
;
246 Instance
->Controller
= ControllerHandle
;
247 Instance
->Image
= This
->DriverBindingHandle
;
248 Instance
->ParentDevicePath
= ParentDevicePath
;
250 CopyMem (&Instance
->Ip4ConfigProtocol
, &mIp4ConfigProtocolTemplate
, sizeof (mIp4ConfigProtocolTemplate
));
252 Instance
->State
= IP4_CONFIG_STATE_IDLE
;
254 Instance
->MnpHandle
= MnpHandle
;
256 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
258 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
262 Instance
->NicAddr
.Type
= (UINT16
) SnpMode
.IfType
;
263 Instance
->NicAddr
.Len
= (UINT8
) SnpMode
.HwAddressSize
;
264 CopyMem (&Instance
->NicAddr
.MacAddr
, &SnpMode
.CurrentAddress
, Instance
->NicAddr
.Len
);
267 // Add it to the global list, and compose the name
269 Status
= NetLibGetMacString (Instance
->Controller
, Instance
->Image
, &Instance
->MacString
);
270 if (EFI_ERROR (Status
)) {
274 Status
= Ip4ConfigDeviceInit (Instance
);
277 // Install the IP4_CONFIG protocols
279 Status
= gBS
->InstallMultipleProtocolInterfaces (
281 &gEfiIp4ConfigProtocolGuid
,
282 &Instance
->Ip4ConfigProtocol
,
286 if (EFI_ERROR (Status
)) {
291 // A dedicated timer is used to poll underlying media status.
293 Status
= gBS
->CreateEvent (
294 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
301 if (EFI_ERROR (Status
)) {
306 // Get the previous configure parameters. If an error happend here,
307 // just ignore it because the driver should be able to operate.
309 NicConfig
= Ip4ConfigReadVariable (Instance
);
310 if (NicConfig
!= NULL
) {
311 if (NicConfig
->Perment
) {
312 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
) {
314 // Don't modify the permanent static configuration.
316 } else if (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
) {
318 // Remove the previous acquired DHCP parameters.
320 ZeroMem (&NicConfig
->Ip4Info
, sizeof (EFI_IP4_IPCONFIG_DATA
));
321 Ip4ConfigWriteVariable (Instance
, NicConfig
);
325 // Delete the non-permanent configuration.
327 Ip4ConfigWriteVariable (Instance
, NULL
);
330 FreePool (NicConfig
);
336 if (Instance
!= NULL
) {
343 &gEfiManagedNetworkProtocolGuid
,
344 This
->DriverBindingHandle
,
349 NetLibDestroyServiceChild (
351 This
->DriverBindingHandle
,
352 &gEfiManagedNetworkServiceBindingProtocolGuid
,
361 Stop this driver on ControllerHandle.
363 @param This Protocol instance pointer.
364 @param ControllerHandle Handle of device to stop driver on
365 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
366 children is zero stop the entire bus driver.
367 @param ChildHandleBuffer List of Child Handles to Stop.
369 @retval EFI_SUCCES This driver is removed ControllerHandle
370 @retval other This driver was not removed from this device
375 Ip4ConfigDriverBindingStop (
376 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
377 IN EFI_HANDLE ControllerHandle
,
378 IN UINTN NumberOfChildren
,
379 IN EFI_HANDLE
*ChildHandleBuffer
382 IP4_CONFIG_INSTANCE
*Instance
;
383 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
384 EFI_HANDLE NicHandle
;
388 // IP4_CONFIG instance opens an MNP child. It may also create and open
389 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
390 // it is the MNP child, stop the whole driver.
393 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
395 if (NicHandle
!= NULL
) {
397 // Get our context back then clean the DHCP up. Notify the user if necessary.
399 Status
= gBS
->OpenProtocol (
401 &gEfiIp4ConfigProtocolGuid
,
402 (VOID
**) &Ip4Config
,
403 This
->DriverBindingHandle
,
405 EFI_OPEN_PROTOCOL_GET_PROTOCOL
408 if (EFI_ERROR (Status
)) {
412 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
413 ASSERT (ControllerHandle
== Instance
->Dhcp4Handle
);
415 Ip4ConfigCleanDhcp4 (Instance
);
417 Instance
->State
= IP4_CONFIG_STATE_CONFIGURED
;
418 Instance
->Result
= EFI_DEVICE_ERROR
;
420 if (Instance
->DoneEvent
!= NULL
) {
421 gBS
->SignalEvent (Instance
->DoneEvent
);
428 // This is a MNP handle, stop the whole driver
430 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
432 if (NicHandle
== NULL
) {
437 // Get our context back.
439 Status
= gBS
->OpenProtocol (
441 &gEfiIp4ConfigProtocolGuid
,
442 (VOID
**) &Ip4Config
,
443 This
->DriverBindingHandle
,
445 EFI_OPEN_PROTOCOL_GET_PROTOCOL
448 if (EFI_ERROR (Status
)) {
452 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
454 Ip4ConfigDeviceUnload (Instance
);
457 // Unload the protocols first to inform the top drivers
459 Status
= gBS
->UninstallMultipleProtocolInterfaces (
461 &gEfiIp4ConfigProtocolGuid
,
462 &Instance
->Ip4ConfigProtocol
,
466 if (EFI_ERROR (Status
)) {
471 // Release all the resources
473 if (Instance
->MnpHandle
!= NULL
) {
476 &gEfiManagedNetworkProtocolGuid
,
477 This
->DriverBindingHandle
,
481 NetLibDestroyServiceChild (
484 &gEfiManagedNetworkServiceBindingProtocolGuid
,
488 Instance
->Mnp
= NULL
;
489 Instance
->MnpHandle
= NULL
;
492 if (Instance
->MacString
!= NULL
) {
493 FreePool (Instance
->MacString
);
496 if (Instance
->Timer
!= NULL
) {
497 gBS
->SetTimer (Instance
->Timer
, TimerCancel
, 0);
498 gBS
->CloseEvent (Instance
->Timer
);
499 Instance
->Timer
= NULL
;
502 Ip4ConfigCleanConfig (Instance
);