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