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