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