2 The driver binding for IP4 CONFIG protocol.
4 Copyright (c) 2006 - 2009, Intel Corporation.<BR>
5 All rights reserved. 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"
19 EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding
= {
20 Ip4ConfigDriverBindingSupported
,
21 Ip4ConfigDriverBindingStart
,
22 Ip4ConfigDriverBindingStop
,
29 Stop all the auto configuration when the IP4 configure driver is
32 @param ImageHandle The driver that is being unloaded
34 @retval EFI_SUCCESS The driver has been ready for unload.
40 IN EFI_HANDLE ImageHandle
46 // Stop all the IP4_CONFIG instances
48 for (Index
= 0; Index
< MAX_IP4_CONFIG_IN_VARIABLE
; Index
++) {
49 if (mIp4ConfigNicList
[Index
] == NULL
) {
53 gIp4ConfigDriverBinding
.Stop (
54 &gIp4ConfigDriverBinding
,
55 mIp4ConfigNicList
[Index
]->MnpHandle
,
61 return NetLibDefaultUnload (ImageHandle
);
65 The entry point for IP4 config driver which install the driver
66 binding and component name protocol on its image.
68 @param ImageHandle The image handle of the driver.
69 @param SystemTable The system table.
71 @retval EFI_SUCCES All the related protocols are installed on the driver.
72 @retval Others Failed to install protocols.
77 Ip4ConfigDriverEntryPoint (
78 IN EFI_HANDLE ImageHandle
,
79 IN EFI_SYSTEM_TABLE
*SystemTable
82 return EfiLibInstallDriverBindingComponentName2 (
85 &gIp4ConfigDriverBinding
,
87 &gIp4ConfigComponentName
,
88 &gIp4ConfigComponentName2
94 Test to see if this driver supports ControllerHandle.
96 @param This Protocol instance pointer.
97 @param ControllerHandle Handle of device to test
98 @param RemainingDevicePath Optional parameter use to pick a specific child
101 @retval EFI_SUCCES This driver supports this device
102 @retval EFI_ALREADY_STARTED This driver is already running on this device
103 @retval other This driver does not support this device
108 Ip4ConfigDriverBindingSupported (
109 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
110 IN EFI_HANDLE ControllerHandle
,
111 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
116 Status
= gBS
->OpenProtocol (
118 &gEfiManagedNetworkServiceBindingProtocolGuid
,
120 This
->DriverBindingHandle
,
122 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
130 Start this driver on ControllerHandle.
132 @param This Protocol instance pointer.
133 @param ControllerHandle Handle of device to bind driver to
134 @param RemainingDevicePath Optional parameter use to pick a specific child
137 @retval EFI_SUCCES This driver is added to ControllerHandle
138 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
139 @retval other This driver does not support this device
144 Ip4ConfigDriverBindingStart (
145 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
146 IN EFI_HANDLE ControllerHandle
,
147 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
150 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
151 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
152 EFI_HANDLE MnpHandle
;
153 IP4_CONFIG_INSTANCE
*Instance
;
154 EFI_SIMPLE_NETWORK_MODE SnpMode
;
155 IP4_CONFIG_VARIABLE
*Variable
;
156 NIC_IP4_CONFIG_INFO
*NicConfig
;
157 IP4_CONFIG_VARIABLE
*NewVariable
;
160 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
162 Status
= gBS
->HandleProtocol (
164 &gEfiDevicePathProtocolGuid
,
165 (VOID
**) &ParentDevicePath
167 if (EFI_ERROR (Status
)) {
172 // Check for multiple start.
174 Status
= gBS
->OpenProtocol (
176 &gEfiIp4ConfigProtocolGuid
,
177 (VOID
**) &Ip4Config
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_GET_PROTOCOL
183 if (!EFI_ERROR (Status
)) {
184 return EFI_ALREADY_STARTED
;
188 // Create a MNP child
194 Status
= NetLibCreateServiceChild (
196 This
->DriverBindingHandle
,
197 &gEfiManagedNetworkServiceBindingProtocolGuid
,
201 if (EFI_ERROR (Status
)) {
205 Status
= gBS
->OpenProtocol (
207 &gEfiManagedNetworkProtocolGuid
,
209 This
->DriverBindingHandle
,
211 EFI_OPEN_PROTOCOL_BY_DRIVER
214 if (EFI_ERROR (Status
)) {
219 // Allocate an instance then initialize it
221 Instance
= AllocatePool (sizeof (IP4_CONFIG_INSTANCE
));
223 if (Instance
== NULL
) {
224 Status
= EFI_OUT_OF_RESOURCES
;
228 Instance
->Signature
= IP4_CONFIG_INSTANCE_SIGNATURE
;
229 Instance
->Controller
= ControllerHandle
;
230 Instance
->Image
= This
->DriverBindingHandle
;
231 Instance
->ParentDevicePath
= ParentDevicePath
;
233 CopyMem (&Instance
->Ip4ConfigProtocol
, &mIp4ConfigProtocolTemplate
, sizeof (mIp4ConfigProtocolTemplate
));
235 Instance
->State
= IP4_CONFIG_STATE_IDLE
;
237 Instance
->MnpHandle
= MnpHandle
;
239 Instance
->DoneEvent
= NULL
;
240 Instance
->ReconfigEvent
= NULL
;
241 Instance
->Result
= EFI_NOT_READY
;
242 Instance
->NicConfig
= NULL
;
244 Instance
->Dhcp4
= NULL
;
245 Instance
->Dhcp4Handle
= NULL
;
246 Instance
->Dhcp4Event
= NULL
;
248 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
250 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
254 Instance
->NicAddr
.Type
= (UINT16
) SnpMode
.IfType
;
255 Instance
->NicAddr
.Len
= (UINT8
) SnpMode
.HwAddressSize
;
256 CopyMem (&Instance
->NicAddr
.MacAddr
, &SnpMode
.CurrentAddress
, Instance
->NicAddr
.Len
);
259 // Add it to the global list, and compose the name
261 for (Index
= 0; Index
< MAX_IP4_CONFIG_IN_VARIABLE
; Index
++) {
262 if (mIp4ConfigNicList
[Index
] == NULL
) {
263 mIp4ConfigNicList
[Index
] = Instance
;
264 Instance
->NicIndex
= Index
;
266 if (Instance
->NicAddr
.Type
== NET_IFTYPE_ETHERNET
) {
267 UnicodeSPrint (Instance
->NicName
, (UINTN
) IP4_NIC_NAME_LENGTH
, L
"eth%d", Index
);
269 UnicodeSPrint (Instance
->NicName
, (UINTN
) IP4_NIC_NAME_LENGTH
, L
"unk%d", Index
);
276 if (Index
== MAX_IP4_CONFIG_IN_VARIABLE
) {
277 Status
= EFI_OUT_OF_RESOURCES
;
281 Status
= Ip4ConfigDeviceInit (Instance
);
284 // Install the IP4_CONFIG and NIC_IP4CONFIG protocols
286 Status
= gBS
->InstallMultipleProtocolInterfaces (
288 &gEfiIp4ConfigProtocolGuid
,
289 &Instance
->Ip4ConfigProtocol
,
293 if (EFI_ERROR (Status
)) {
294 mIp4ConfigNicList
[Index
] = NULL
;
299 // Get the previous configure parameters. If an error happend here,
300 // just ignore it because the driver should be able to operate.
302 Variable
= Ip4ConfigReadVariable ();
304 if (Variable
== NULL
) {
308 NicConfig
= Ip4ConfigFindNicVariable (Variable
, &Instance
->NicAddr
);
310 if (NicConfig
== NULL
) {
315 // Don't modify the permant static configuration
317 if (NicConfig
->Perment
&& (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
)) {
322 // Delete the non-permant configuration and remove the previous
323 // acquired DHCP parameters. Only doing DHCP itself is permant
327 if (!NicConfig
->Perment
) {
328 NewVariable
= Ip4ConfigModifyVariable (Variable
, &Instance
->NicAddr
, NULL
);
330 } else if (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
) {
331 ZeroMem (&NicConfig
->Ip4Info
, sizeof (EFI_IP4_IPCONFIG_DATA
));
332 NewVariable
= Ip4ConfigModifyVariable (Variable
, &Instance
->NicAddr
, NicConfig
);
336 Ip4ConfigWriteVariable (NewVariable
);
338 if (NewVariable
!= NULL
) {
339 FreePool (NewVariable
);
345 if (NicConfig
!= NULL
) {
346 FreePool (NicConfig
);
352 if (Instance
!= NULL
) {
359 &gEfiManagedNetworkProtocolGuid
,
360 This
->DriverBindingHandle
,
365 NetLibDestroyServiceChild (
367 This
->DriverBindingHandle
,
368 &gEfiManagedNetworkProtocolGuid
,
377 Stop this driver on ControllerHandle.
379 @param This Protocol instance pointer.
380 @param ControllerHandle Handle of device to stop driver on
381 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
382 children is zero stop the entire bus driver.
383 @param ChildHandleBuffer List of Child Handles to Stop.
385 @retval EFI_SUCCES This driver is removed ControllerHandle
386 @retval other This driver was not removed from this device
391 Ip4ConfigDriverBindingStop (
392 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
393 IN EFI_HANDLE ControllerHandle
,
394 IN UINTN NumberOfChildren
,
395 IN EFI_HANDLE
*ChildHandleBuffer
398 IP4_CONFIG_INSTANCE
*Instance
;
399 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
400 EFI_HANDLE NicHandle
;
404 // IP4_CONFIG instance opens an MNP child. It may also create and open
405 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
406 // it is the MNP child, stop the whole driver.
409 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
411 if (NicHandle
!= NULL
) {
413 // Get our context back then clean the DHCP up. Notify the user if necessary.
415 Status
= gBS
->OpenProtocol (
417 &gEfiIp4ConfigProtocolGuid
,
418 (VOID
**) &Ip4Config
,
419 This
->DriverBindingHandle
,
421 EFI_OPEN_PROTOCOL_GET_PROTOCOL
424 if (EFI_ERROR (Status
)) {
428 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
429 ASSERT (ControllerHandle
== Instance
->Dhcp4Handle
);
431 Ip4ConfigCleanDhcp4 (Instance
);
433 Instance
->State
= IP4_CONFIG_STATE_CONFIGURED
;
434 Instance
->Result
= EFI_DEVICE_ERROR
;
436 if (Instance
->DoneEvent
!= NULL
) {
437 gBS
->SignalEvent (Instance
->DoneEvent
);
444 // This is a MNP handle, stop the whole driver
446 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
448 if (NicHandle
== NULL
) {
453 // Get our context back.
455 Status
= gBS
->OpenProtocol (
457 &gEfiIp4ConfigProtocolGuid
,
458 (VOID
**) &Ip4Config
,
459 This
->DriverBindingHandle
,
461 EFI_OPEN_PROTOCOL_GET_PROTOCOL
464 if (EFI_ERROR (Status
)) {
468 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
470 Ip4ConfigDeviceUnload (Instance
);
473 // Unload the protocols first to inform the top drivers
475 Status
= gBS
->UninstallMultipleProtocolInterfaces (
477 &gEfiIp4ConfigProtocolGuid
,
478 &Instance
->Ip4ConfigProtocol
,
482 if (EFI_ERROR (Status
)) {
487 // Release all the resources
489 if (Instance
->MnpHandle
!= NULL
) {
492 &gEfiManagedNetworkProtocolGuid
,
493 This
->DriverBindingHandle
,
497 NetLibDestroyServiceChild (
500 &gEfiManagedNetworkServiceBindingProtocolGuid
,
504 Instance
->Mnp
= NULL
;
505 Instance
->MnpHandle
= NULL
;
508 Ip4ConfigCleanConfig (Instance
);
509 mIp4ConfigNicList
[Instance
->NicIndex
] = NULL
;