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"
18 EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding
= {
19 Ip4ConfigDriverBindingSupported
,
20 Ip4ConfigDriverBindingStart
,
21 Ip4ConfigDriverBindingStop
,
28 Stop all the auto configuration when the IP4 configure driver is
31 @param ImageHandle The driver that is being unloaded
33 @retval EFI_SUCCESS The driver has been ready for unload.
39 IN EFI_HANDLE ImageHandle
45 // Stop all the IP4_CONFIG instances
47 for (Index
= 0; Index
< MAX_IP4_CONFIG_IN_VARIABLE
; Index
++) {
48 if (mIp4ConfigNicList
[Index
] == NULL
) {
52 gIp4ConfigDriverBinding
.Stop (
53 &gIp4ConfigDriverBinding
,
54 mIp4ConfigNicList
[Index
]->MnpHandle
,
60 return NetLibDefaultUnload (ImageHandle
);
64 The entry point for IP4 config driver which install the driver
65 binding and component name protocol on its image.
67 @param ImageHandle The image handle of the driver.
68 @param SystemTable The system table.
70 @retval EFI_SUCCES All the related protocols are installed on the driver.
71 @retval Others Failed to install protocols.
76 Ip4ConfigDriverEntryPoint (
77 IN EFI_HANDLE ImageHandle
,
78 IN EFI_SYSTEM_TABLE
*SystemTable
81 return EfiLibInstallDriverBindingComponentName2 (
84 &gIp4ConfigDriverBinding
,
86 &gIp4ConfigComponentName
,
87 &gIp4ConfigComponentName2
93 Test to see if this driver supports ControllerHandle.
95 @param This Protocol instance pointer.
96 @param ControllerHandle Handle of device to test
97 @param RemainingDevicePath Optional parameter use to pick a specific child
100 @retval EFI_SUCCES This driver supports this device
101 @retval EFI_ALREADY_STARTED This driver is already running on this device
102 @retval other This driver does not support this device
107 Ip4ConfigDriverBindingSupported (
108 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
109 IN EFI_HANDLE ControllerHandle
,
110 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
115 Status
= gBS
->OpenProtocol (
117 &gEfiManagedNetworkServiceBindingProtocolGuid
,
119 This
->DriverBindingHandle
,
121 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
129 Start this driver on ControllerHandle.
131 @param This Protocol instance pointer.
132 @param ControllerHandle Handle of device to bind driver to
133 @param RemainingDevicePath Optional parameter use to pick a specific child
136 @retval EFI_SUCCES This driver is added to ControllerHandle
137 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
138 @retval other This driver does not support this device
143 Ip4ConfigDriverBindingStart (
144 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
145 IN EFI_HANDLE ControllerHandle
,
146 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
149 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
150 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
151 EFI_HANDLE MnpHandle
;
152 IP4_CONFIG_INSTANCE
*Instance
;
153 EFI_SIMPLE_NETWORK_MODE SnpMode
;
154 IP4_CONFIG_VARIABLE
*Variable
;
155 NIC_IP4_CONFIG_INFO
*NicConfig
;
156 IP4_CONFIG_VARIABLE
*NewVariable
;
161 // Check for multiple start.
163 Status
= gBS
->OpenProtocol (
165 &gEfiIp4ConfigProtocolGuid
,
166 (VOID
**) &Ip4Config
,
167 This
->DriverBindingHandle
,
169 EFI_OPEN_PROTOCOL_GET_PROTOCOL
172 if (!EFI_ERROR (Status
)) {
173 return EFI_ALREADY_STARTED
;
177 // Create a MNP child
183 Status
= NetLibCreateServiceChild (
185 This
->DriverBindingHandle
,
186 &gEfiManagedNetworkServiceBindingProtocolGuid
,
190 if (EFI_ERROR (Status
)) {
194 Status
= gBS
->OpenProtocol (
196 &gEfiManagedNetworkProtocolGuid
,
198 This
->DriverBindingHandle
,
200 EFI_OPEN_PROTOCOL_BY_DRIVER
203 if (EFI_ERROR (Status
)) {
208 // Allocate an instance then initialize it
210 Instance
= AllocatePool (sizeof (IP4_CONFIG_INSTANCE
));
212 if (Instance
== NULL
) {
213 Status
= EFI_OUT_OF_RESOURCES
;
217 Instance
->Signature
= IP4_CONFIG_INSTANCE_SIGNATURE
;
218 Instance
->Controller
= ControllerHandle
;
219 Instance
->Image
= This
->DriverBindingHandle
;
221 CopyMem (&Instance
->Ip4ConfigProtocol
, &mIp4ConfigProtocolTemplate
, sizeof (mIp4ConfigProtocolTemplate
));
222 CopyMem (&Instance
->NicIp4Protocol
, &mNicIp4ConfigProtocolTemplate
, sizeof (mNicIp4ConfigProtocolTemplate
));
224 Instance
->State
= IP4_CONFIG_STATE_IDLE
;
226 Instance
->MnpHandle
= MnpHandle
;
228 Instance
->DoneEvent
= NULL
;
229 Instance
->ReconfigEvent
= NULL
;
230 Instance
->Result
= EFI_NOT_READY
;
231 Instance
->NicConfig
= NULL
;
233 Instance
->Dhcp4
= NULL
;
234 Instance
->Dhcp4Handle
= NULL
;
235 Instance
->Dhcp4Event
= NULL
;
237 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
239 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
243 Instance
->NicAddr
.Type
= (UINT16
) SnpMode
.IfType
;
244 Instance
->NicAddr
.Len
= (UINT8
) SnpMode
.HwAddressSize
;
245 CopyMem (&Instance
->NicAddr
.MacAddr
, &SnpMode
.CurrentAddress
, sizeof (Instance
->NicAddr
.MacAddr
));
248 // Add it to the global list, and compose the name
250 for (Index
= 0; Index
< MAX_IP4_CONFIG_IN_VARIABLE
; Index
++) {
251 if (mIp4ConfigNicList
[Index
] == NULL
) {
252 mIp4ConfigNicList
[Index
] = Instance
;
253 Instance
->NicIndex
= Index
;
255 if (Instance
->NicAddr
.Type
== NET_IFTYPE_ETHERNET
) {
256 Instance
->NicName
[0] = 'e';
257 Instance
->NicName
[1] = 't';
258 Instance
->NicName
[2] = 'h';
259 Instance
->NicName
[3] = (UINT16
) ('0' + Index
);
260 Instance
->NicName
[4] = 0;
262 Instance
->NicName
[0] = 'u';
263 Instance
->NicName
[1] = 'n';
264 Instance
->NicName
[2] = 'k';
265 Instance
->NicName
[3] = (UINT16
) ('0' + Index
);
266 Instance
->NicName
[4] = 0;
273 if (Index
== MAX_IP4_CONFIG_IN_VARIABLE
) {
274 Status
= EFI_OUT_OF_RESOURCES
;
279 // Install the IP4_CONFIG and NIC_IP4CONFIG protocols
281 Status
= gBS
->InstallMultipleProtocolInterfaces (
283 &gEfiIp4ConfigProtocolGuid
,
284 &Instance
->Ip4ConfigProtocol
,
285 &gEfiNicIp4ConfigProtocolGuid
,
286 &Instance
->NicIp4Protocol
,
290 if (EFI_ERROR (Status
)) {
291 mIp4ConfigNicList
[Index
] = NULL
;
296 // Get the previous configure parameters. If an error happend here,
297 // just ignore it because the driver should be able to operate.
299 Variable
= Ip4ConfigReadVariable ();
301 if (Variable
== NULL
) {
305 NicConfig
= Ip4ConfigFindNicVariable (Variable
, &Instance
->NicAddr
);
307 if (NicConfig
== NULL
) {
312 // Don't modify the permant static configuration
314 if (NicConfig
->Perment
&& (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
)) {
319 // Delete the non-permant configuration and remove the previous
320 // acquired DHCP parameters. Only doing DHCP itself is permant
324 if (!NicConfig
->Perment
) {
325 NewVariable
= Ip4ConfigModifyVariable (Variable
, &Instance
->NicAddr
, NULL
);
327 } else if (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
) {
328 ZeroMem (&NicConfig
->Ip4Info
, sizeof (EFI_IP4_IPCONFIG_DATA
));
329 NewVariable
= Ip4ConfigModifyVariable (Variable
, &Instance
->NicAddr
, NicConfig
);
333 Ip4ConfigWriteVariable (NewVariable
);
335 if (NewVariable
!= NULL
) {
336 gBS
->FreePool (NewVariable
);
340 gBS
->FreePool (Variable
);
342 if (NicConfig
!= NULL
) {
343 gBS
->FreePool (NicConfig
);
349 if (Instance
!= NULL
) {
350 gBS
->FreePool (Instance
);
356 &gEfiManagedNetworkProtocolGuid
,
357 This
->DriverBindingHandle
,
362 NetLibDestroyServiceChild (
364 This
->DriverBindingHandle
,
365 &gEfiManagedNetworkProtocolGuid
,
374 Stop this driver on ControllerHandle.
376 @param This Protocol instance pointer.
377 @param ControllerHandle Handle of device to stop driver on
378 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
379 children is zero stop the entire bus driver.
380 @param ChildHandleBuffer List of Child Handles to Stop.
382 @retval EFI_SUCCES This driver is removed ControllerHandle
383 @retval other This driver was not removed from this device
388 Ip4ConfigDriverBindingStop (
389 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
390 IN EFI_HANDLE ControllerHandle
,
391 IN UINTN NumberOfChildren
,
392 IN EFI_HANDLE
*ChildHandleBuffer
395 IP4_CONFIG_INSTANCE
*Instance
;
396 EFI_IP4_CONFIG_PROTOCOL
*Ip4Config
;
397 EFI_HANDLE NicHandle
;
401 // IP4_CONFIG instance opens an MNP child. It may also create and open
402 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If
403 // it is the MNP child, stop the whole driver.
406 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiDhcp4ProtocolGuid
);
408 if (NicHandle
!= NULL
) {
410 // Get our context back then clean the DHCP up. Notify the user if necessary.
412 Status
= gBS
->OpenProtocol (
414 &gEfiIp4ConfigProtocolGuid
,
415 (VOID
**) &Ip4Config
,
416 This
->DriverBindingHandle
,
418 EFI_OPEN_PROTOCOL_GET_PROTOCOL
421 if (EFI_ERROR (Status
)) {
425 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
426 ASSERT (ControllerHandle
== Instance
->Dhcp4Handle
);
428 Ip4ConfigCleanDhcp4 (Instance
);
430 Instance
->State
= IP4_CONFIG_STATE_CONFIGURED
;
431 Instance
->Result
= EFI_DEVICE_ERROR
;
433 if (Instance
->DoneEvent
!= NULL
) {
434 gBS
->SignalEvent (Instance
->DoneEvent
);
441 // This is a MNP handle, stop the whole driver
443 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
445 if (NicHandle
== NULL
) {
450 // Get our context back.
452 Status
= gBS
->OpenProtocol (
454 &gEfiIp4ConfigProtocolGuid
,
455 (VOID
**) &Ip4Config
,
456 This
->DriverBindingHandle
,
458 EFI_OPEN_PROTOCOL_GET_PROTOCOL
461 if (EFI_ERROR (Status
)) {
465 Instance
= IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config
);
468 // Unload the protocols first to inform the top drivers
470 Status
= gBS
->UninstallMultipleProtocolInterfaces (
472 &gEfiIp4ConfigProtocolGuid
,
473 &Instance
->Ip4ConfigProtocol
,
474 &gEfiNicIp4ConfigProtocolGuid
,
475 &Instance
->NicIp4Protocol
,
479 if (EFI_ERROR (Status
)) {
484 // Release all the resources
486 if (Instance
->MnpHandle
!= NULL
) {
489 &gEfiManagedNetworkProtocolGuid
,
490 This
->DriverBindingHandle
,
494 NetLibDestroyServiceChild (
497 &gEfiManagedNetworkServiceBindingProtocolGuid
,
501 Instance
->Mnp
= NULL
;
502 Instance
->MnpHandle
= NULL
;
505 Ip4ConfigCleanConfig (Instance
);
506 mIp4ConfigNicList
[Instance
->NicIndex
] = NULL
;
507 gBS
->FreePool (Instance
);