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