2 The driver binding for IP4 CONFIG protocol.
4 Copyright (c) 2006 - 2013, 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 mIp4ConfigTemplate
.Result
= EFI_NOT_READY
;
114 return EfiLibInstallDriverBindingComponentName2 (
117 &gIp4ConfigDriverBinding
,
119 &gIp4ConfigComponentName
,
120 &gIp4ConfigComponentName2
126 Test to see if this driver supports ControllerHandle.
128 @param This Protocol instance pointer.
129 @param ControllerHandle Handle of device to test
130 @param RemainingDevicePath Optional parameter use to pick a specific child
133 @retval EFI_SUCCES This driver supports this device
134 @retval EFI_ALREADY_STARTED This driver is already running on this device
135 @retval other This driver does not support this device
140 Ip4ConfigDriverBindingSupported (
141 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
142 IN EFI_HANDLE ControllerHandle
,
143 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
148 Status
= gBS
->OpenProtocol (
150 &gEfiManagedNetworkServiceBindingProtocolGuid
,
152 This
->DriverBindingHandle
,
154 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
162 Start this driver on ControllerHandle.
164 @param This Protocol instance pointer.
165 @param ControllerHandle Handle of device to bind driver to
166 @param RemainingDevicePath Optional parameter use to pick a specific child
169 @retval EFI_SUCCES This driver is added to ControllerHandle
170 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
171 @retval other This driver does not support this device
176 Ip4ConfigDriverBindingStart (
177 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
178 IN EFI_HANDLE ControllerHandle
,
179 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
182 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
183 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
184 EFI_HANDLE MnpHandle
;
185 IP4_CONFIG_INSTANCE
*Instance
;
186 EFI_SIMPLE_NETWORK_MODE SnpMode
;
187 NIC_IP4_CONFIG_INFO
*NicConfig
;
189 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
191 Status
= gBS
->HandleProtocol (
193 &gEfiDevicePathProtocolGuid
,
194 (VOID
**) &ParentDevicePath
196 if (EFI_ERROR (Status
)) {
201 // Check for multiple start.
203 Status
= gBS
->OpenProtocol (
205 &gEfiIp4ConfigProtocolGuid
,
206 (VOID
**) &Ip4Config
,
207 This
->DriverBindingHandle
,
209 EFI_OPEN_PROTOCOL_GET_PROTOCOL
212 if (!EFI_ERROR (Status
)) {
213 return EFI_ALREADY_STARTED
;
217 // Create a MNP child
223 Status
= NetLibCreateServiceChild (
225 This
->DriverBindingHandle
,
226 &gEfiManagedNetworkServiceBindingProtocolGuid
,
230 if (EFI_ERROR (Status
)) {
234 Status
= gBS
->OpenProtocol (
236 &gEfiManagedNetworkProtocolGuid
,
238 This
->DriverBindingHandle
,
240 EFI_OPEN_PROTOCOL_BY_DRIVER
243 if (EFI_ERROR (Status
)) {
248 // Allocate an instance then initialize it
250 Instance
= AllocateCopyPool (sizeof (IP4_CONFIG_INSTANCE
), &mIp4ConfigTemplate
);
252 if (Instance
== NULL
) {
253 Status
= EFI_OUT_OF_RESOURCES
;
257 Instance
->Controller
= ControllerHandle
;
258 Instance
->Image
= This
->DriverBindingHandle
;
259 Instance
->ParentDevicePath
= ParentDevicePath
;
261 CopyMem (&Instance
->Ip4ConfigProtocol
, &mIp4ConfigProtocolTemplate
, sizeof (mIp4ConfigProtocolTemplate
));
263 Instance
->State
= IP4_CONFIG_STATE_IDLE
;
265 Instance
->MnpHandle
= MnpHandle
;
267 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
269 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
273 Instance
->NicAddr
.Type
= (UINT16
) SnpMode
.IfType
;
274 Instance
->NicAddr
.Len
= (UINT8
) SnpMode
.HwAddressSize
;
275 CopyMem (&Instance
->NicAddr
.MacAddr
, &SnpMode
.CurrentAddress
, Instance
->NicAddr
.Len
);
278 // Add it to the global list, and compose the name
280 Status
= NetLibGetMacString (Instance
->Controller
, Instance
->Image
, &Instance
->MacString
);
281 if (EFI_ERROR (Status
)) {
285 Status
= Ip4ConfigDeviceInit (Instance
);
288 // Install the IP4_CONFIG protocols
290 Status
= gBS
->InstallMultipleProtocolInterfaces (
292 &gEfiIp4ConfigProtocolGuid
,
293 &Instance
->Ip4ConfigProtocol
,
297 if (EFI_ERROR (Status
)) {
302 // A dedicated timer is used to poll underlying media status.
304 Status
= gBS
->CreateEvent (
305 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
312 if (EFI_ERROR (Status
)) {
317 // Get the previous configure parameters. If an error happend here,
318 // just ignore it because the driver should be able to operate.
320 NicConfig
= Ip4ConfigReadVariable (Instance
);
321 if (NicConfig
!= NULL
) {
322 if (!NicConfig
->Perment
) {
324 // Delete the non-permanent configuration.
326 Ip4ConfigWriteVariable (Instance
, NULL
);
329 FreePool (NicConfig
);
335 if (Instance
!= NULL
) {
342 &gEfiManagedNetworkProtocolGuid
,
343 This
->DriverBindingHandle
,
348 NetLibDestroyServiceChild (
350 This
->DriverBindingHandle
,
351 &gEfiManagedNetworkServiceBindingProtocolGuid
,
360 Stop this driver on ControllerHandle.
362 @param This Protocol instance pointer.
363 @param ControllerHandle Handle of device to stop driver on
364 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
365 children is zero stop the entire bus driver.
366 @param ChildHandleBuffer List of Child Handles to Stop.
368 @retval EFI_SUCCES This driver is removed ControllerHandle
369 @retval other This driver was not removed from this device
374 Ip4ConfigDriverBindingStop (
375 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
376 IN EFI_HANDLE ControllerHandle
,
377 IN UINTN NumberOfChildren
,
378 IN EFI_HANDLE
*ChildHandleBuffer
381 IP4_CONFIG_INSTANCE
*Instance
;
382 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
383 EFI_HANDLE NicHandle
;
387 // IP4_CONFIG instance opens an MNP child. It may also create and open
388 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
389 // it is the MNP child, stop the whole driver.
392 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
394 if (NicHandle
!= NULL
) {
396 // Get our context back then clean the DHCP up. Notify the user if necessary.
398 Status
= gBS
->OpenProtocol (
400 &gEfiIp4ConfigProtocolGuid
,
401 (VOID
**) &Ip4Config
,
402 This
->DriverBindingHandle
,
404 EFI_OPEN_PROTOCOL_GET_PROTOCOL
407 if (EFI_ERROR (Status
)) {
411 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
412 ASSERT (ControllerHandle
== Instance
->Dhcp4Handle
);
414 Ip4ConfigCleanDhcp4 (Instance
);
416 Instance
->State
= IP4_CONFIG_STATE_CONFIGURED
;
417 Instance
->Result
= EFI_DEVICE_ERROR
;
419 if (Instance
->DoneEvent
!= NULL
) {
420 gBS
->SignalEvent (Instance
->DoneEvent
);
427 // This is a MNP handle, stop the whole driver
429 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
431 if (NicHandle
== NULL
) {
436 // Get our context back.
438 Status
= gBS
->OpenProtocol (
440 &gEfiIp4ConfigProtocolGuid
,
441 (VOID
**) &Ip4Config
,
442 This
->DriverBindingHandle
,
444 EFI_OPEN_PROTOCOL_GET_PROTOCOL
447 if (EFI_ERROR (Status
)) {
451 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
453 Ip4ConfigDeviceUnload (Instance
);
456 // Unload the protocols first to inform the top drivers
458 Status
= gBS
->UninstallMultipleProtocolInterfaces (
460 &gEfiIp4ConfigProtocolGuid
,
461 &Instance
->Ip4ConfigProtocol
,
465 if (EFI_ERROR (Status
)) {
470 // Release all the resources
472 if (Instance
->MnpHandle
!= NULL
) {
475 &gEfiManagedNetworkProtocolGuid
,
476 This
->DriverBindingHandle
,
480 NetLibDestroyServiceChild (
483 &gEfiManagedNetworkServiceBindingProtocolGuid
,
487 Instance
->Mnp
= NULL
;
488 Instance
->MnpHandle
= NULL
;
491 if (Instance
->MacString
!= NULL
) {
492 FreePool (Instance
->MacString
);
495 if (Instance
->Timer
!= NULL
) {
496 gBS
->SetTimer (Instance
->Timer
, TimerCancel
, 0);
497 gBS
->CloseEvent (Instance
->Timer
);
498 Instance
->Timer
= NULL
;
501 Ip4ConfigCleanConfig (Instance
);