]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/MnpDxe/MnpDriver.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / MnpDxe / MnpDriver.c
CommitLineData
8a67d61d 1/** @file\r
6e4bac4d 2 Implementation of driver entry point and driver binding protocol.\r
8a67d61d 3\r
d1102dba 4Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
8a67d61d 6\r
8a67d61d 7**/\r
8\r
9#include "MnpDriver.h"\r
8a67d61d 10#include "MnpImpl.h"\r
779ae357 11#include "MnpVlan.h"\r
8a67d61d 12\r
d1050b9d 13EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {\r
8a67d61d 14 MnpDriverBindingSupported,\r
15 MnpDriverBindingStart,\r
16 MnpDriverBindingStop,\r
17 0xa,\r
18 NULL,\r
19 NULL\r
20};\r
21\r
216f7970 22/**\r
23 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
d1102dba 24\r
216f7970 25 @param[in] Entry The entry to be removed.\r
26 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
27\r
28 @retval EFI_SUCCESS The entry has been removed successfully.\r
29 @retval Others Fail to remove the entry.\r
30\r
31**/\r
32EFI_STATUS\r
1f7eb561 33EFIAPI\r
216f7970 34MnpDestroyServiceDataEntry (\r
d1050b9d
MK
35 IN LIST_ENTRY *Entry,\r
36 IN VOID *Context\r
1f7eb561 37 )\r
216f7970 38{\r
d1050b9d 39 MNP_SERVICE_DATA *MnpServiceData;\r
d1102dba 40\r
216f7970 41 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
42 return MnpDestroyServiceData (MnpServiceData);\r
43}\r
44\r
45/**\r
46 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
d1102dba 47\r
216f7970 48 @param[in] Entry The entry to be removed.\r
49 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
50\r
51 @retval EFI_SUCCESS The entry has been removed successfully.\r
52 @retval Others Fail to remove the entry.\r
53\r
54**/\r
55EFI_STATUS\r
1f7eb561 56EFIAPI\r
216f7970 57MnpDestroyServiceChildEntry (\r
d1050b9d
MK
58 IN LIST_ENTRY *Entry,\r
59 IN VOID *Context\r
1f7eb561 60 )\r
216f7970 61{\r
d1050b9d 62 MNP_SERVICE_DATA *MnpServiceData;\r
216f7970 63\r
64 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
65 return MnpDestroyServiceChild (MnpServiceData);\r
66}\r
67\r
8a67d61d 68/**\r
b6c4ecad 69 Test to see if this driver supports ControllerHandle. This service\r
70 is called by the EFI boot service ConnectController(). In\r
71 order to make drivers as small as possible, there are a few calling\r
72 restrictions for this service. ConnectController() must\r
73 follow these calling restrictions. If any other agent wishes to call\r
74 Supported() it must also follow these calling restrictions.\r
75\r
6e4bac4d 76 @param[in] This Protocol instance pointer.\r
77 @param[in] ControllerHandle Handle of device to test.\r
779ae357 78 @param[in] RemainingDevicePath Optional parameter use to pick a specific\r
6e4bac4d 79 child device to start.\r
b6c4ecad 80\r
6e4bac4d 81 @retval EFI_SUCCESS This driver supports this device.\r
82 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
83 @retval Others This driver does not support this device.\r
8a67d61d 84\r
85**/\r
86EFI_STATUS\r
87EFIAPI\r
88MnpDriverBindingSupported (\r
d1050b9d
MK
89 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
90 IN EFI_HANDLE ControllerHandle,\r
91 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
8a67d61d 92 )\r
93{\r
b58baf6b 94 EFI_STATUS Status;\r
95 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
8a67d61d 96\r
8a67d61d 97 //\r
b58baf6b 98 // Test to open the Simple Network protocol BY_DRIVER.\r
8a67d61d 99 //\r
100 Status = gBS->OpenProtocol (\r
101 ControllerHandle,\r
102 &gEfiSimpleNetworkProtocolGuid,\r
d1050b9d 103 (VOID **)&Snp,\r
8a67d61d 104 This->DriverBindingHandle,\r
105 ControllerHandle,\r
b58baf6b 106 EFI_OPEN_PROTOCOL_BY_DRIVER\r
8a67d61d 107 );\r
b58baf6b 108 if (EFI_ERROR (Status)) {\r
109 return Status;\r
110 }\r
111\r
112 //\r
5feb1fbd 113 // Close the opened SNP protocol.\r
b58baf6b 114 //\r
115 gBS->CloseProtocol (\r
116 ControllerHandle,\r
117 &gEfiSimpleNetworkProtocolGuid,\r
118 This->DriverBindingHandle,\r
119 ControllerHandle\r
120 );\r
121\r
122 return EFI_SUCCESS;\r
8a67d61d 123}\r
124\r
8a67d61d 125/**\r
b6c4ecad 126 Start this driver on ControllerHandle. This service is called by the\r
779ae357 127 EFI boot service ConnectController(). In order to make drivers as small\r
6e4bac4d 128 as possible, there are a few calling restrictions for this service.\r
129 ConnectController() must follow these calling restrictions. If any other\r
130 agent wishes to call Start() it must also follow these calling restrictions.\r
131\r
132 @param[in] This Protocol instance pointer.\r
133 @param[in] ControllerHandle Handle of device to bind driver to.\r
779ae357 134 @param[in] RemainingDevicePath Optional parameter use to pick a specific\r
6e4bac4d 135 child device to start.\r
136\r
137 @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
138 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
139 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Mnp Service Data.\r
140 @retval Others This driver does not support this device.\r
779ae357 141\r
8a67d61d 142**/\r
143EFI_STATUS\r
144EFIAPI\r
145MnpDriverBindingStart (\r
d1050b9d
MK
146 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
147 IN EFI_HANDLE ControllerHandle,\r
148 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
8a67d61d 149 )\r
150{\r
151 EFI_STATUS Status;\r
152 MNP_SERVICE_DATA *MnpServiceData;\r
779ae357 153 MNP_DEVICE_DATA *MnpDeviceData;\r
154 LIST_ENTRY *Entry;\r
155 VLAN_TCI *VlanVariable;\r
156 UINTN NumberOfVlan;\r
157 UINTN Index;\r
8a67d61d 158\r
779ae357 159 VlanVariable = NULL;\r
8a67d61d 160\r
779ae357 161 //\r
162 // Initialize the Mnp Device Data\r
163 //\r
164 MnpDeviceData = AllocateZeroPool (sizeof (MNP_DEVICE_DATA));\r
165 if (MnpDeviceData == NULL) {\r
c49ca4a2 166 DEBUG ((DEBUG_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));\r
8a67d61d 167\r
168 return EFI_OUT_OF_RESOURCES;\r
169 }\r
170\r
779ae357 171 Status = MnpInitializeDeviceData (MnpDeviceData, This->DriverBindingHandle, ControllerHandle);\r
8a67d61d 172 if (EFI_ERROR (Status)) {\r
c49ca4a2 173 DEBUG ((DEBUG_ERROR, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status));\r
8a67d61d 174\r
779ae357 175 FreePool (MnpDeviceData);\r
176 return Status;\r
8a67d61d 177 }\r
178\r
779ae357 179 //\r
180 // Check whether NIC driver has already produced VlanConfig protocol\r
181 //\r
182 Status = gBS->OpenProtocol (\r
183 ControllerHandle,\r
184 &gEfiVlanConfigProtocolGuid,\r
185 NULL,\r
186 This->DriverBindingHandle,\r
187 ControllerHandle,\r
188 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
189 );\r
190 if (!EFI_ERROR (Status)) {\r
191 //\r
192 // NIC hardware already implement VLAN,\r
193 // no need to provide software VLAN implementation in MNP driver\r
194 //\r
195 MnpDeviceData->NumberOfVlan = 0;\r
196 ZeroMem (&MnpDeviceData->VlanConfig, sizeof (EFI_VLAN_CONFIG_PROTOCOL));\r
197 MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);\r
d1050b9d 198 Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
779ae357 199 goto Exit;\r
200 }\r
8a67d61d 201\r
202 //\r
779ae357 203 // Install VLAN Config Protocol\r
8a67d61d 204 //\r
205 Status = gBS->InstallMultipleProtocolInterfaces (\r
206 &ControllerHandle,\r
779ae357 207 &gEfiVlanConfigProtocolGuid,\r
208 &MnpDeviceData->VlanConfig,\r
8a67d61d 209 NULL\r
210 );\r
779ae357 211 if (EFI_ERROR (Status)) {\r
212 goto Exit;\r
213 }\r
8a67d61d 214\r
779ae357 215 //\r
216 // Get current VLAN configuration from EFI Variable\r
217 //\r
218 NumberOfVlan = 0;\r
d1050b9d 219 Status = MnpGetVlanVariable (MnpDeviceData, &NumberOfVlan, &VlanVariable);\r
779ae357 220 if (EFI_ERROR (Status)) {\r
221 //\r
222 // No VLAN is set, create a default MNP service data for untagged frame\r
223 //\r
224 MnpDeviceData->NumberOfVlan = 0;\r
d1050b9d
MK
225 MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);\r
226 Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
779ae357 227 goto Exit;\r
228 }\r
229\r
230 //\r
231 // Create MNP service data for each VLAN\r
232 //\r
233 MnpDeviceData->NumberOfVlan = NumberOfVlan;\r
234 for (Index = 0; Index < NumberOfVlan; Index++) {\r
235 MnpServiceData = MnpCreateServiceData (\r
236 MnpDeviceData,\r
237 VlanVariable[Index].Bits.Vid,\r
d1050b9d 238 (UINT8)VlanVariable[Index].Bits.Priority\r
779ae357 239 );\r
240\r
241 if (MnpServiceData == NULL) {\r
242 Status = EFI_OUT_OF_RESOURCES;\r
243\r
244 goto Exit;\r
245 }\r
246 }\r
247\r
248Exit:\r
249 if (VlanVariable != NULL) {\r
250 FreePool (VlanVariable);\r
251 }\r
8a67d61d 252\r
253 if (EFI_ERROR (Status)) {\r
779ae357 254 //\r
255 // Destroy all MNP service data\r
256 //\r
257 while (!IsListEmpty (&MnpDeviceData->ServiceList)) {\r
d1050b9d 258 Entry = GetFirstNode (&MnpDeviceData->ServiceList);\r
779ae357 259 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
260 MnpDestroyServiceData (MnpServiceData);\r
261 }\r
8a67d61d 262\r
779ae357 263 //\r
264 // Uninstall the VLAN Config Protocol if any\r
265 //\r
266 if (MnpDeviceData->VlanConfig.Set != NULL) {\r
267 gBS->UninstallMultipleProtocolInterfaces (\r
268 MnpDeviceData->ControllerHandle,\r
269 &gEfiVlanConfigProtocolGuid,\r
270 &MnpDeviceData->VlanConfig,\r
271 NULL\r
272 );\r
8a67d61d 273 }\r
274\r
779ae357 275 //\r
276 // Destroy Mnp Device Data\r
277 //\r
278 MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
279 FreePool (MnpDeviceData);\r
8a67d61d 280 }\r
281\r
282 return Status;\r
283}\r
284\r
8a67d61d 285/**\r
b6c4ecad 286 Stop this driver on ControllerHandle. This service is called by the\r
779ae357 287 EFI boot service DisconnectController(). In order to make drivers as\r
288 small as possible, there are a few calling restrictions for this service.\r
289 DisconnectController() must follow these calling restrictions. If any other\r
6e4bac4d 290 agent wishes to call Stop() it must also follow these calling restrictions.\r
779ae357 291\r
6e4bac4d 292 @param[in] This Protocol instance pointer.\r
293 @param[in] ControllerHandle Handle of device to stop driver on.\r
779ae357 294 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If\r
295 number of children is zero stop the entire\r
296 bus driver.\r
6e4bac4d 297 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
b6c4ecad 298\r
6e4bac4d 299 @retval EFI_SUCCESS This driver is removed ControllerHandle.\r
300 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
8a67d61d 301\r
302**/\r
303EFI_STATUS\r
304EFIAPI\r
305MnpDriverBindingStop (\r
d1050b9d
MK
306 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
307 IN EFI_HANDLE ControllerHandle,\r
308 IN UINTN NumberOfChildren,\r
309 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
8a67d61d 310 )\r
311{\r
312 EFI_STATUS Status;\r
313 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
779ae357 314 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;\r
315 MNP_DEVICE_DATA *MnpDeviceData;\r
8a67d61d 316 MNP_SERVICE_DATA *MnpServiceData;\r
216f7970 317 LIST_ENTRY *List;\r
318 UINTN ListLength;\r
8a67d61d 319\r
320 //\r
779ae357 321 // Try to retrieve MNP service binding protocol from the ControllerHandle\r
8a67d61d 322 //\r
323 Status = gBS->OpenProtocol (\r
324 ControllerHandle,\r
325 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
d1050b9d 326 (VOID **)&ServiceBinding,\r
8a67d61d 327 This->DriverBindingHandle,\r
328 ControllerHandle,\r
329 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
330 );\r
331 if (EFI_ERROR (Status)) {\r
779ae357 332 //\r
333 // Retrieve VLAN Config Protocol from the ControllerHandle\r
334 //\r
335 Status = gBS->OpenProtocol (\r
336 ControllerHandle,\r
337 &gEfiVlanConfigProtocolGuid,\r
d1050b9d 338 (VOID **)&VlanConfig,\r
779ae357 339 This->DriverBindingHandle,\r
340 ControllerHandle,\r
341 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
342 );\r
343 if (EFI_ERROR (Status)) {\r
c49ca4a2 344 DEBUG ((DEBUG_ERROR, "MnpDriverBindingStop: try to stop unknown Controller.\n"));\r
779ae357 345 return EFI_DEVICE_ERROR;\r
346 }\r
8a67d61d 347\r
779ae357 348 MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (VlanConfig);\r
349 } else {\r
350 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
d1050b9d 351 MnpDeviceData = MnpServiceData->MnpDeviceData;\r
8a67d61d 352 }\r
353\r
c4a62a12 354 if (NumberOfChildren == 0) {\r
8a67d61d 355 //\r
779ae357 356 // Destroy all MNP service data\r
8a67d61d 357 //\r
d1050b9d 358 List = &MnpDeviceData->ServiceList;\r
216f7970 359 Status = NetDestroyLinkList (\r
360 List,\r
361 MnpDestroyServiceDataEntry,\r
362 NULL,\r
363 &ListLength\r
364 );\r
d1050b9d 365 if (EFI_ERROR (Status) || (ListLength != 0)) {\r
216f7970 366 return EFI_DEVICE_ERROR;\r
779ae357 367 }\r
8a67d61d 368\r
c4a62a12 369 //\r
779ae357 370 // Uninstall the VLAN Config Protocol if any\r
c4a62a12 371 //\r
779ae357 372 if (MnpDeviceData->VlanConfig.Set != NULL) {\r
373 gBS->UninstallMultipleProtocolInterfaces (\r
374 MnpDeviceData->ControllerHandle,\r
375 &gEfiVlanConfigProtocolGuid,\r
376 &MnpDeviceData->VlanConfig,\r
377 NULL\r
378 );\r
379 }\r
8a67d61d 380\r
779ae357 381 //\r
dd29f3ed 382 // Destroy Mnp Device Data\r
779ae357 383 //\r
384 MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
385 FreePool (MnpDeviceData);\r
386\r
216f7970 387 if (gMnpControllerNameTable != NULL) {\r
388 FreeUnicodeStringTable (gMnpControllerNameTable);\r
389 gMnpControllerNameTable = NULL;\r
390 }\r
d1050b9d 391\r
779ae357 392 return EFI_SUCCESS;\r
393 }\r
394\r
395 //\r
396 // Stop all MNP child\r
397 //\r
d1050b9d 398 List = &MnpDeviceData->ServiceList;\r
216f7970 399 Status = NetDestroyLinkList (\r
400 List,\r
401 MnpDestroyServiceChildEntry,\r
402 NULL,\r
403 &ListLength\r
404 );\r
405 if (EFI_ERROR (Status)) {\r
779ae357 406 return EFI_DEVICE_ERROR;\r
407 }\r
408\r
409 return EFI_SUCCESS;\r
8a67d61d 410}\r
411\r
8a67d61d 412/**\r
6e4bac4d 413 Creates a child handle with a set of I/O services.\r
8a67d61d 414\r
6e4bac4d 415 @param[in] This Protocol instance pointer.\r
416 @param[in, out] ChildHandle Pointer to the handle of the child to create. If\r
417 it is NULL, then a new handle is created. If\r
779ae357 418 it is not NULL, then the I/O services are added\r
419 to the existing child handle.\r
8a67d61d 420\r
5feb1fbd 421 @retval EFI_SUCCESS The protocol was added to ChildHandle.\r
779ae357 422 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
2048c585 423 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to\r
6e4bac4d 424 create the child.\r
425 @retval Others The child handle was not created.\r
8a67d61d 426\r
427**/\r
428EFI_STATUS\r
429EFIAPI\r
430MnpServiceBindingCreateChild (\r
d1050b9d
MK
431 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
432 IN OUT EFI_HANDLE *ChildHandle\r
8a67d61d 433 )\r
434{\r
435 EFI_STATUS Status;\r
436 MNP_SERVICE_DATA *MnpServiceData;\r
437 MNP_INSTANCE_DATA *Instance;\r
779ae357 438 VOID *MnpSb;\r
8a67d61d 439 EFI_TPL OldTpl;\r
440\r
441 if ((This == NULL) || (ChildHandle == NULL)) {\r
8a67d61d 442 return EFI_INVALID_PARAMETER;\r
443 }\r
444\r
445 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
446\r
447 //\r
448 // Allocate buffer for the new instance.\r
449 //\r
e48e37fc 450 Instance = AllocateZeroPool (sizeof (MNP_INSTANCE_DATA));\r
8a67d61d 451 if (Instance == NULL) {\r
5feb1fbd 452 DEBUG ((DEBUG_ERROR, "MnpServiceBindingCreateChild: Failed to allocate memory for the new instance.\n"));\r
779ae357 453\r
8a67d61d 454 return EFI_OUT_OF_RESOURCES;\r
455 }\r
456\r
457 //\r
458 // Init the instance data.\r
459 //\r
460 MnpInitializeInstanceData (MnpServiceData, Instance);\r
461\r
462 Status = gBS->InstallMultipleProtocolInterfaces (\r
463 ChildHandle,\r
464 &gEfiManagedNetworkProtocolGuid,\r
465 &Instance->ManagedNetwork,\r
466 NULL\r
467 );\r
468 if (EFI_ERROR (Status)) {\r
e48e37fc 469 DEBUG (\r
c49ca4a2 470 (DEBUG_ERROR,\r
d1050b9d
MK
471 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",\r
472 Status)\r
8a67d61d 473 );\r
779ae357 474\r
8a67d61d 475 goto ErrorExit;\r
476 }\r
477\r
478 //\r
479 // Save the instance's childhandle.\r
480 //\r
481 Instance->Handle = *ChildHandle;\r
482\r
483 Status = gBS->OpenProtocol (\r
779ae357 484 MnpServiceData->ServiceHandle,\r
485 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
d1050b9d 486 (VOID **)&MnpSb,\r
8a67d61d 487 gMnpDriverBinding.DriverBindingHandle,\r
488 Instance->Handle,\r
489 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
490 );\r
491 if (EFI_ERROR (Status)) {\r
492 goto ErrorExit;\r
493 }\r
494\r
495 //\r
496 // Add the child instance into ChildrenList.\r
497 //\r
e48e37fc 498 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 499\r
e48e37fc 500 InsertTailList (&MnpServiceData->ChildrenList, &Instance->InstEntry);\r
8a67d61d 501 MnpServiceData->ChildrenNumber++;\r
502\r
e48e37fc 503 gBS->RestoreTPL (OldTpl);\r
8a67d61d 504\r
505ErrorExit:\r
506\r
507 if (EFI_ERROR (Status)) {\r
8a67d61d 508 if (Instance->Handle != NULL) {\r
8a67d61d 509 gBS->UninstallMultipleProtocolInterfaces (\r
d1050b9d
MK
510 Instance->Handle,\r
511 &gEfiManagedNetworkProtocolGuid,\r
512 &Instance->ManagedNetwork,\r
513 NULL\r
514 );\r
8a67d61d 515 }\r
516\r
766c7483 517 FreePool (Instance);\r
8a67d61d 518 }\r
519\r
520 return Status;\r
521}\r
522\r
8a67d61d 523/**\r
6e4bac4d 524 Destroys a child handle with a set of I/O services.\r
779ae357 525\r
526 The DestroyChild() function does the opposite of CreateChild(). It removes a\r
527 protocol that was installed by CreateChild() from ChildHandle. If the removed\r
528 protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.\r
529\r
530 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL\r
6e4bac4d 531 instance.\r
532 @param[in] ChildHandle Handle of the child to destroy.\r
533\r
5feb1fbd 534 @retval EFI_SUCCESS The protocol was removed from ChildHandle.\r
6e4bac4d 535 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that\r
536 is being removed.\r
284ee2e8 537 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
6e4bac4d 538 @retval EFI_ACCESS_DENIED The protocol could not be removed from the\r
539 ChildHandle because its services are being\r
540 used.\r
541 @retval Others The child handle was not destroyed.\r
8a67d61d 542\r
543**/\r
544EFI_STATUS\r
545EFIAPI\r
546MnpServiceBindingDestroyChild (\r
d1050b9d
MK
547 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
548 IN EFI_HANDLE ChildHandle\r
8a67d61d 549 )\r
550{\r
551 EFI_STATUS Status;\r
552 MNP_SERVICE_DATA *MnpServiceData;\r
553 EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;\r
554 MNP_INSTANCE_DATA *Instance;\r
555 EFI_TPL OldTpl;\r
556\r
557 if ((This == NULL) || (ChildHandle == NULL)) {\r
8a67d61d 558 return EFI_INVALID_PARAMETER;\r
559 }\r
560\r
561 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
562\r
563 //\r
564 // Try to retrieve ManagedNetwork Protocol from ChildHandle.\r
565 //\r
566 Status = gBS->OpenProtocol (\r
567 ChildHandle,\r
568 &gEfiManagedNetworkProtocolGuid,\r
d1050b9d 569 (VOID **)&ManagedNetwork,\r
8a67d61d 570 gMnpDriverBinding.DriverBindingHandle,\r
571 ChildHandle,\r
572 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
573 );\r
574 if (EFI_ERROR (Status)) {\r
8a67d61d 575 return EFI_UNSUPPORTED;\r
576 }\r
577\r
578 Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);\r
579\r
580 //\r
581 // MnpServiceBindingDestroyChild may be called twice: first called by\r
582 // MnpServiceBindingStop, second called by uninstalling the MNP protocol\r
583 // in this ChildHandle. Use destroyed to make sure the resource clean code\r
584 // will only excecute once.\r
585 //\r
586 if (Instance->Destroyed) {\r
8a67d61d 587 return EFI_SUCCESS;\r
588 }\r
589\r
590 Instance->Destroyed = TRUE;\r
591\r
592 //\r
593 // Close the Simple Network protocol.\r
594 //\r
595 gBS->CloseProtocol (\r
779ae357 596 MnpServiceData->ServiceHandle,\r
597 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
598 MnpServiceData->MnpDeviceData->ImageHandle,\r
8a67d61d 599 ChildHandle\r
600 );\r
601\r
602 //\r
603 // Uninstall the ManagedNetwork protocol.\r
604 //\r
605 Status = gBS->UninstallMultipleProtocolInterfaces (\r
606 ChildHandle,\r
607 &gEfiManagedNetworkProtocolGuid,\r
608 &Instance->ManagedNetwork,\r
609 NULL\r
610 );\r
611 if (EFI_ERROR (Status)) {\r
e48e37fc 612 DEBUG (\r
c49ca4a2 613 (DEBUG_ERROR,\r
d1050b9d
MK
614 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",\r
615 Status)\r
8a67d61d 616 );\r
617\r
618 Instance->Destroyed = FALSE;\r
619 return Status;\r
620 }\r
621\r
e48e37fc 622 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 623\r
624 //\r
625 // Reset the configuration.\r
626 //\r
627 ManagedNetwork->Configure (ManagedNetwork, NULL);\r
628\r
629 //\r
630 // Try to flush the RcvdPacketQueue.\r
631 //\r
632 MnpFlushRcvdDataQueue (Instance);\r
633\r
634 //\r
635 // Clean the RxTokenMap.\r
636 //\r
637 NetMapClean (&Instance->RxTokenMap);\r
638\r
639 //\r
640 // Remove this instance from the ChildrenList.\r
641 //\r
e48e37fc 642 RemoveEntryList (&Instance->InstEntry);\r
8a67d61d 643 MnpServiceData->ChildrenNumber--;\r
644\r
e48e37fc 645 gBS->RestoreTPL (OldTpl);\r
8a67d61d 646\r
766c7483 647 FreePool (Instance);\r
8a67d61d 648\r
649 return Status;\r
650}\r
651\r
b6c4ecad 652/**\r
653 The entry point for Mnp driver which installs the driver binding and component\r
654 name protocol on its ImageHandle.\r
655\r
6e4bac4d 656 @param[in] ImageHandle The image handle of the driver.\r
657 @param[in] SystemTable The system table.\r
b6c4ecad 658\r
5feb1fbd 659 @retval EFI_SUCCESS The driver binding and component name protocols are\r
b6c4ecad 660 successfully installed.\r
6e4bac4d 661 @retval Others Other errors as indicated.\r
8a67d61d 662\r
b6c4ecad 663**/\r
8a67d61d 664EFI_STATUS\r
665EFIAPI\r
666MnpDriverEntryPoint (\r
d1050b9d
MK
667 IN EFI_HANDLE ImageHandle,\r
668 IN EFI_SYSTEM_TABLE *SystemTable\r
8a67d61d 669 )\r
8a67d61d 670{\r
83cbd279 671 return EfiLibInstallDriverBindingComponentName2 (\r
da1d0201 672 ImageHandle,\r
673 SystemTable,\r
674 &gMnpDriverBinding,\r
675 ImageHandle,\r
676 &gMnpComponentName,\r
83cbd279 677 &gMnpComponentName2\r
da1d0201 678 );\r
8a67d61d 679}\r