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