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