]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDriver.c
Update the copyright notice format
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4ConfigDriver.c
1 /** @file
2 The driver binding for IP4 CONFIG protocol.
3
4 Copyright (c) 2006 - 2010, 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
9
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.
12
13 **/
14
15
16 #include "Ip4Config.h"
17 #include "Ip4ConfigNv.h"
18
19 EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding = {
20 Ip4ConfigDriverBindingSupported,
21 Ip4ConfigDriverBindingStart,
22 Ip4ConfigDriverBindingStop,
23 0xa,
24 NULL,
25 NULL
26 };
27
28 /**
29 Stop all the auto configuration when the IP4 configure driver is
30 being unloaded.
31
32 @param ImageHandle The driver that is being unloaded
33
34 @retval EFI_SUCCESS The driver has been ready for unload.
35
36 **/
37 EFI_STATUS
38 EFIAPI
39 EfiIp4ConfigUnload (
40 IN EFI_HANDLE ImageHandle
41 )
42 {
43 UINT32 Index;
44
45 //
46 // Stop all the IP4_CONFIG instances
47 //
48 for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {
49 if (mIp4ConfigNicList[Index] == NULL) {
50 continue;
51 }
52
53 gIp4ConfigDriverBinding.Stop (
54 &gIp4ConfigDriverBinding,
55 mIp4ConfigNicList[Index]->MnpHandle,
56 0,
57 NULL
58 );
59 }
60
61 return NetLibDefaultUnload (ImageHandle);
62 }
63
64 /**
65 The entry point for IP4 config driver which install the driver
66 binding and component name protocol on its image.
67
68 @param ImageHandle The image handle of the driver.
69 @param SystemTable The system table.
70
71 @retval EFI_SUCCES All the related protocols are installed on the driver.
72 @retval Others Failed to install protocols.
73
74 **/
75 EFI_STATUS
76 EFIAPI
77 Ip4ConfigDriverEntryPoint (
78 IN EFI_HANDLE ImageHandle,
79 IN EFI_SYSTEM_TABLE *SystemTable
80 )
81 {
82 return EfiLibInstallDriverBindingComponentName2 (
83 ImageHandle,
84 SystemTable,
85 &gIp4ConfigDriverBinding,
86 ImageHandle,
87 &gIp4ConfigComponentName,
88 &gIp4ConfigComponentName2
89 );
90 }
91
92
93 /**
94 Test to see if this driver supports ControllerHandle.
95
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
99 device to start.
100
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
104
105 **/
106 EFI_STATUS
107 EFIAPI
108 Ip4ConfigDriverBindingSupported (
109 IN EFI_DRIVER_BINDING_PROTOCOL *This,
110 IN EFI_HANDLE ControllerHandle,
111 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
112 )
113 {
114 EFI_STATUS Status;
115
116 Status = gBS->OpenProtocol (
117 ControllerHandle,
118 &gEfiManagedNetworkServiceBindingProtocolGuid,
119 NULL,
120 This->DriverBindingHandle,
121 ControllerHandle,
122 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
123 );
124
125 return Status;
126 }
127
128
129 /**
130 Start this driver on ControllerHandle.
131
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
135 device to start.
136
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
140
141 **/
142 EFI_STATUS
143 EFIAPI
144 Ip4ConfigDriverBindingStart (
145 IN EFI_DRIVER_BINDING_PROTOCOL *This,
146 IN EFI_HANDLE ControllerHandle,
147 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
148 )
149 {
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;
158 EFI_STATUS Status;
159 UINT32 Index;
160 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
161
162 Status = gBS->HandleProtocol (
163 ControllerHandle,
164 &gEfiDevicePathProtocolGuid,
165 (VOID **) &ParentDevicePath
166 );
167 if (EFI_ERROR (Status)) {
168 return Status;
169 }
170
171 //
172 // Check for multiple start.
173 //
174 Status = gBS->OpenProtocol (
175 ControllerHandle,
176 &gEfiIp4ConfigProtocolGuid,
177 (VOID **) &Ip4Config,
178 This->DriverBindingHandle,
179 ControllerHandle,
180 EFI_OPEN_PROTOCOL_GET_PROTOCOL
181 );
182
183 if (!EFI_ERROR (Status)) {
184 return EFI_ALREADY_STARTED;
185 }
186
187 //
188 // Create a MNP child
189 //
190 Mnp = NULL;
191 MnpHandle = NULL;
192 Instance = NULL;
193
194 Status = NetLibCreateServiceChild (
195 ControllerHandle,
196 This->DriverBindingHandle,
197 &gEfiManagedNetworkServiceBindingProtocolGuid,
198 &MnpHandle
199 );
200
201 if (EFI_ERROR (Status)) {
202 return Status;
203 }
204
205 Status = gBS->OpenProtocol (
206 MnpHandle,
207 &gEfiManagedNetworkProtocolGuid,
208 (VOID **) &Mnp,
209 This->DriverBindingHandle,
210 ControllerHandle,
211 EFI_OPEN_PROTOCOL_BY_DRIVER
212 );
213
214 if (EFI_ERROR (Status)) {
215 goto ON_ERROR;
216 }
217
218 //
219 // Allocate an instance then initialize it
220 //
221 Instance = AllocatePool (sizeof (IP4_CONFIG_INSTANCE));
222
223 if (Instance == NULL) {
224 Status = EFI_OUT_OF_RESOURCES;
225 goto ON_ERROR;
226 }
227
228 Instance->Signature = IP4_CONFIG_INSTANCE_SIGNATURE;
229 Instance->Controller = ControllerHandle;
230 Instance->Image = This->DriverBindingHandle;
231 Instance->ParentDevicePath = ParentDevicePath;
232
233 CopyMem (&Instance->Ip4ConfigProtocol, &mIp4ConfigProtocolTemplate, sizeof (mIp4ConfigProtocolTemplate));
234
235 Instance->State = IP4_CONFIG_STATE_IDLE;
236 Instance->Mnp = Mnp;
237 Instance->MnpHandle = MnpHandle;
238
239 Instance->DoneEvent = NULL;
240 Instance->ReconfigEvent = NULL;
241 Instance->Result = EFI_NOT_READY;
242 Instance->NicConfig = NULL;
243
244 Instance->Dhcp4 = NULL;
245 Instance->Dhcp4Handle = NULL;
246 Instance->Dhcp4Event = NULL;
247
248 Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
249
250 if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
251 goto ON_ERROR;
252 }
253
254 Instance->NicAddr.Type = (UINT16) SnpMode.IfType;
255 Instance->NicAddr.Len = (UINT8) SnpMode.HwAddressSize;
256 CopyMem (&Instance->NicAddr.MacAddr, &SnpMode.CurrentAddress, Instance->NicAddr.Len);
257
258 //
259 // Add it to the global list, and compose the name
260 //
261 for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {
262 if (mIp4ConfigNicList[Index] == NULL) {
263 mIp4ConfigNicList[Index] = Instance;
264 Instance->NicIndex = Index;
265
266 if (Instance->NicAddr.Type == NET_IFTYPE_ETHERNET) {
267 UnicodeSPrint (Instance->NicName, (UINTN) IP4_NIC_NAME_LENGTH, L"eth%d", Index);
268 } else {
269 UnicodeSPrint (Instance->NicName, (UINTN) IP4_NIC_NAME_LENGTH, L"unk%d", Index);
270 }
271
272 break;
273 }
274 }
275
276 if (Index == MAX_IP4_CONFIG_IN_VARIABLE) {
277 Status = EFI_OUT_OF_RESOURCES;
278 goto ON_ERROR;
279 }
280
281 Status = Ip4ConfigDeviceInit (Instance);
282
283 //
284 // Install the IP4_CONFIG and NIC_IP4CONFIG protocols
285 //
286 Status = gBS->InstallMultipleProtocolInterfaces (
287 &ControllerHandle,
288 &gEfiIp4ConfigProtocolGuid,
289 &Instance->Ip4ConfigProtocol,
290 NULL
291 );
292
293 if (EFI_ERROR (Status)) {
294 mIp4ConfigNicList[Index] = NULL;
295 goto ON_ERROR;
296 }
297
298 //
299 // Get the previous configure parameters. If an error happend here,
300 // just ignore it because the driver should be able to operate.
301 //
302 Variable = Ip4ConfigReadVariable ();
303
304 if (Variable == NULL) {
305 return EFI_SUCCESS;
306 }
307
308 NicConfig = Ip4ConfigFindNicVariable (Variable, &Instance->NicAddr);
309
310 if (NicConfig == NULL) {
311 goto ON_EXIT;
312 }
313
314 //
315 // Don't modify the permant static configuration
316 //
317 if (NicConfig->Perment && (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC)) {
318 goto ON_EXIT;
319 }
320
321 //
322 // Delete the non-permant configuration and remove the previous
323 // acquired DHCP parameters. Only doing DHCP itself is permant
324 //
325 NewVariable = NULL;
326
327 if (!NicConfig->Perment) {
328 NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NULL);
329
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);
333
334 }
335
336 Ip4ConfigWriteVariable (NewVariable);
337
338 if (NewVariable != NULL) {
339 FreePool (NewVariable);
340 }
341
342 ON_EXIT:
343 FreePool (Variable);
344
345 if (NicConfig != NULL) {
346 FreePool (NicConfig);
347 }
348
349 return EFI_SUCCESS;
350
351 ON_ERROR:
352 if (Instance != NULL) {
353 FreePool (Instance);
354 }
355
356 if (Mnp != NULL) {
357 gBS->CloseProtocol (
358 MnpHandle,
359 &gEfiManagedNetworkProtocolGuid,
360 This->DriverBindingHandle,
361 ControllerHandle
362 );
363 }
364
365 NetLibDestroyServiceChild (
366 ControllerHandle,
367 This->DriverBindingHandle,
368 &gEfiManagedNetworkProtocolGuid,
369 MnpHandle
370 );
371
372 return Status;
373 }
374
375
376 /**
377 Stop this driver on ControllerHandle.
378
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.
384
385 @retval EFI_SUCCES This driver is removed ControllerHandle
386 @retval other This driver was not removed from this device
387
388 **/
389 EFI_STATUS
390 EFIAPI
391 Ip4ConfigDriverBindingStop (
392 IN EFI_DRIVER_BINDING_PROTOCOL *This,
393 IN EFI_HANDLE ControllerHandle,
394 IN UINTN NumberOfChildren,
395 IN EFI_HANDLE *ChildHandleBuffer
396 )
397 {
398 IP4_CONFIG_INSTANCE *Instance;
399 EFI_IP4_CONFIG_PROTOCOL *Ip4Config;
400 EFI_HANDLE NicHandle;
401 EFI_STATUS Status;
402
403 //
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.
407 //
408 //
409 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
410
411 if (NicHandle != NULL) {
412 //
413 // Get our context back then clean the DHCP up. Notify the user if necessary.
414 //
415 Status = gBS->OpenProtocol (
416 NicHandle,
417 &gEfiIp4ConfigProtocolGuid,
418 (VOID **) &Ip4Config,
419 This->DriverBindingHandle,
420 ControllerHandle,
421 EFI_OPEN_PROTOCOL_GET_PROTOCOL
422 );
423
424 if (EFI_ERROR (Status)) {
425 return Status;
426 }
427
428 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);
429 ASSERT (ControllerHandle == Instance->Dhcp4Handle);
430
431 Ip4ConfigCleanDhcp4 (Instance);
432
433 Instance->State = IP4_CONFIG_STATE_CONFIGURED;
434 Instance->Result = EFI_DEVICE_ERROR;
435
436 if (Instance->DoneEvent != NULL) {
437 gBS->SignalEvent (Instance->DoneEvent);
438 }
439
440 return EFI_SUCCESS;
441 }
442
443 //
444 // This is a MNP handle, stop the whole driver
445 //
446 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
447
448 if (NicHandle == NULL) {
449 return EFI_SUCCESS;
450 }
451
452 //
453 // Get our context back.
454 //
455 Status = gBS->OpenProtocol (
456 NicHandle,
457 &gEfiIp4ConfigProtocolGuid,
458 (VOID **) &Ip4Config,
459 This->DriverBindingHandle,
460 ControllerHandle,
461 EFI_OPEN_PROTOCOL_GET_PROTOCOL
462 );
463
464 if (EFI_ERROR (Status)) {
465 return Status;
466 }
467
468 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);
469
470 Ip4ConfigDeviceUnload (Instance);
471
472 //
473 // Unload the protocols first to inform the top drivers
474 //
475 Status = gBS->UninstallMultipleProtocolInterfaces (
476 NicHandle,
477 &gEfiIp4ConfigProtocolGuid,
478 &Instance->Ip4ConfigProtocol,
479 NULL
480 );
481
482 if (EFI_ERROR (Status)) {
483 return Status;
484 }
485
486 //
487 // Release all the resources
488 //
489 if (Instance->MnpHandle != NULL) {
490 gBS->CloseProtocol (
491 Instance->MnpHandle,
492 &gEfiManagedNetworkProtocolGuid,
493 This->DriverBindingHandle,
494 NicHandle
495 );
496
497 NetLibDestroyServiceChild (
498 NicHandle,
499 Instance->Image,
500 &gEfiManagedNetworkServiceBindingProtocolGuid,
501 Instance->MnpHandle
502 );
503
504 Instance->Mnp = NULL;
505 Instance->MnpHandle = NULL;
506 }
507
508 Ip4ConfigCleanConfig (Instance);
509 mIp4ConfigNicList[Instance->NicIndex] = NULL;
510 FreePool (Instance);
511
512 return EFI_SUCCESS;
513 }
514