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
,
94 The entry point for IP4 config driver which install the driver
95 binding and component name protocol on its image.
97 @param ImageHandle The image handle of the driver.
98 @param SystemTable The system table.
100 @retval EFI_SUCCES All the related protocols are installed on the driver.
101 @retval Others Failed to install protocols.
106 Ip4ConfigDriverEntryPoint (
107 IN EFI_HANDLE ImageHandle
,
108 IN EFI_SYSTEM_TABLE
*SystemTable
111 return EfiLibInstallDriverBindingComponentName2 (
114 &gIp4ConfigDriverBinding
,
116 &gIp4ConfigComponentName
,
117 &gIp4ConfigComponentName2
123 Test to see if this driver supports ControllerHandle.
125 @param This Protocol instance pointer.
126 @param ControllerHandle Handle of device to test
127 @param RemainingDevicePath Optional parameter use to pick a specific child
130 @retval EFI_SUCCES This driver supports this device
131 @retval EFI_ALREADY_STARTED This driver is already running on this device
132 @retval other This driver does not support this device
137 Ip4ConfigDriverBindingSupported (
138 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
139 IN EFI_HANDLE ControllerHandle
,
140 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
145 Status
= gBS
->OpenProtocol (
147 &gEfiManagedNetworkServiceBindingProtocolGuid
,
149 This
->DriverBindingHandle
,
151 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
159 Start this driver on ControllerHandle.
161 @param This Protocol instance pointer.
162 @param ControllerHandle Handle of device to bind driver to
163 @param RemainingDevicePath Optional parameter use to pick a specific child
166 @retval EFI_SUCCES This driver is added to ControllerHandle
167 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
168 @retval other This driver does not support this device
173 Ip4ConfigDriverBindingStart (
174 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
175 IN EFI_HANDLE ControllerHandle
,
176 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
179 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
180 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
181 EFI_HANDLE MnpHandle
;
182 IP4_CONFIG_INSTANCE
*Instance
;
183 EFI_SIMPLE_NETWORK_MODE SnpMode
;
184 NIC_IP4_CONFIG_INFO
*NicConfig
;
186 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
188 Status
= gBS
->HandleProtocol (
190 &gEfiDevicePathProtocolGuid
,
191 (VOID
**) &ParentDevicePath
193 if (EFI_ERROR (Status
)) {
198 // Check for multiple start.
200 Status
= gBS
->OpenProtocol (
202 &gEfiIp4ConfigProtocolGuid
,
203 (VOID
**) &Ip4Config
,
204 This
->DriverBindingHandle
,
206 EFI_OPEN_PROTOCOL_GET_PROTOCOL
209 if (!EFI_ERROR (Status
)) {
210 return EFI_ALREADY_STARTED
;
214 // Create a MNP child
220 Status
= NetLibCreateServiceChild (
222 This
->DriverBindingHandle
,
223 &gEfiManagedNetworkServiceBindingProtocolGuid
,
227 if (EFI_ERROR (Status
)) {
231 Status
= gBS
->OpenProtocol (
233 &gEfiManagedNetworkProtocolGuid
,
235 This
->DriverBindingHandle
,
237 EFI_OPEN_PROTOCOL_BY_DRIVER
240 if (EFI_ERROR (Status
)) {
245 // Allocate an instance then initialize it
247 Instance
= AllocateCopyPool (sizeof (IP4_CONFIG_INSTANCE
), &mIp4ConfigTemplate
);
249 if (Instance
== NULL
) {
250 Status
= EFI_OUT_OF_RESOURCES
;
254 Instance
->Controller
= ControllerHandle
;
255 Instance
->Image
= This
->DriverBindingHandle
;
256 Instance
->ParentDevicePath
= ParentDevicePath
;
258 CopyMem (&Instance
->Ip4ConfigProtocol
, &mIp4ConfigProtocolTemplate
, sizeof (mIp4ConfigProtocolTemplate
));
260 Instance
->State
= IP4_CONFIG_STATE_IDLE
;
262 Instance
->MnpHandle
= MnpHandle
;
264 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
266 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
270 Instance
->NicAddr
.Type
= (UINT16
) SnpMode
.IfType
;
271 Instance
->NicAddr
.Len
= (UINT8
) SnpMode
.HwAddressSize
;
272 CopyMem (&Instance
->NicAddr
.MacAddr
, &SnpMode
.CurrentAddress
, Instance
->NicAddr
.Len
);
275 // Add it to the global list, and compose the name
277 Status
= NetLibGetMacString (Instance
->Controller
, Instance
->Image
, &Instance
->MacString
);
278 if (EFI_ERROR (Status
)) {
282 Status
= Ip4ConfigDeviceInit (Instance
);
285 // Install the IP4_CONFIG protocols
287 Status
= gBS
->InstallMultipleProtocolInterfaces (
289 &gEfiIp4ConfigProtocolGuid
,
290 &Instance
->Ip4ConfigProtocol
,
294 if (EFI_ERROR (Status
)) {
299 // A dedicated timer is used to poll underlying media status.
301 Status
= gBS
->CreateEvent (
302 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
309 if (EFI_ERROR (Status
)) {
314 // Get the previous configure parameters. If an error happend here,
315 // just ignore it because the driver should be able to operate.
317 NicConfig
= Ip4ConfigReadVariable (Instance
);
318 if (NicConfig
!= NULL
) {
319 if (!NicConfig
->Perment
) {
321 // Delete the non-permanent configuration.
323 Ip4ConfigWriteVariable (Instance
, NULL
);
326 FreePool (NicConfig
);
332 if (Instance
!= NULL
) {
339 &gEfiManagedNetworkProtocolGuid
,
340 This
->DriverBindingHandle
,
345 NetLibDestroyServiceChild (
347 This
->DriverBindingHandle
,
348 &gEfiManagedNetworkServiceBindingProtocolGuid
,
357 Stop this driver on ControllerHandle.
359 @param This Protocol instance pointer.
360 @param ControllerHandle Handle of device to stop driver on
361 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
362 children is zero stop the entire bus driver.
363 @param ChildHandleBuffer List of Child Handles to Stop.
365 @retval EFI_SUCCES This driver is removed ControllerHandle
366 @retval other This driver was not removed from this device
371 Ip4ConfigDriverBindingStop (
372 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
373 IN EFI_HANDLE ControllerHandle
,
374 IN UINTN NumberOfChildren
,
375 IN EFI_HANDLE
*ChildHandleBuffer
378 IP4_CONFIG_INSTANCE
*Instance
;
379 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
380 EFI_HANDLE NicHandle
;
384 // IP4_CONFIG instance opens an MNP child. It may also create and open
385 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
386 // it is the MNP child, stop the whole driver.
389 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
391 if (NicHandle
!= NULL
) {
393 // Get our context back then clean the DHCP up. Notify the user if necessary.
395 Status
= gBS
->OpenProtocol (
397 &gEfiIp4ConfigProtocolGuid
,
398 (VOID
**) &Ip4Config
,
399 This
->DriverBindingHandle
,
401 EFI_OPEN_PROTOCOL_GET_PROTOCOL
404 if (EFI_ERROR (Status
)) {
408 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
409 ASSERT (ControllerHandle
== Instance
->Dhcp4Handle
);
411 Ip4ConfigCleanDhcp4 (Instance
);
413 Instance
->State
= IP4_CONFIG_STATE_CONFIGURED
;
414 Instance
->Result
= EFI_DEVICE_ERROR
;
416 if (Instance
->DoneEvent
!= NULL
) {
417 gBS
->SignalEvent (Instance
->DoneEvent
);
424 // This is a MNP handle, stop the whole driver
426 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
428 if (NicHandle
== NULL
) {
433 // Get our context back.
435 Status
= gBS
->OpenProtocol (
437 &gEfiIp4ConfigProtocolGuid
,
438 (VOID
**) &Ip4Config
,
439 This
->DriverBindingHandle
,
441 EFI_OPEN_PROTOCOL_GET_PROTOCOL
444 if (EFI_ERROR (Status
)) {
448 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
450 Ip4ConfigDeviceUnload (Instance
);
453 // Unload the protocols first to inform the top drivers
455 Status
= gBS
->UninstallMultipleProtocolInterfaces (
457 &gEfiIp4ConfigProtocolGuid
,
458 &Instance
->Ip4ConfigProtocol
,
462 if (EFI_ERROR (Status
)) {
467 // Release all the resources
469 if (Instance
->MnpHandle
!= NULL
) {
472 &gEfiManagedNetworkProtocolGuid
,
473 This
->DriverBindingHandle
,
477 NetLibDestroyServiceChild (
480 &gEfiManagedNetworkServiceBindingProtocolGuid
,
484 Instance
->Mnp
= NULL
;
485 Instance
->MnpHandle
= NULL
;
488 if (Instance
->MacString
!= NULL
) {
489 FreePool (Instance
->MacString
);
492 if (Instance
->Timer
!= NULL
) {
493 gBS
->SetTimer (Instance
->Timer
, TimerCancel
, 0);
494 gBS
->CloseEvent (Instance
->Timer
);
495 Instance
->Timer
= NULL
;
498 Ip4ConfigCleanConfig (Instance
);