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