2 Implementation of driver entry point and driver binding protocol.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding
= {
14 MnpDriverBindingSupported
,
15 MnpDriverBindingStart
,
23 Callback function which provided by user to remove one node in NetDestroyLinkList process.
25 @param[in] Entry The entry to be removed.
26 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
28 @retval EFI_SUCCESS The entry has been removed successfully.
29 @retval Others Fail to remove the entry.
34 MnpDestroyServiceDataEntry (
39 MNP_SERVICE_DATA
*MnpServiceData
;
41 MnpServiceData
= MNP_SERVICE_DATA_FROM_LINK (Entry
);
42 return MnpDestroyServiceData (MnpServiceData
);
46 Callback function which provided by user to remove one node in NetDestroyLinkList process.
48 @param[in] Entry The entry to be removed.
49 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
51 @retval EFI_SUCCESS The entry has been removed successfully.
52 @retval Others Fail to remove the entry.
57 MnpDestroyServiceChildEntry (
62 MNP_SERVICE_DATA
*MnpServiceData
;
64 MnpServiceData
= MNP_SERVICE_DATA_FROM_LINK (Entry
);
65 return MnpDestroyServiceChild (MnpServiceData
);
69 Test to see if this driver supports ControllerHandle. This service
70 is called by the EFI boot service ConnectController(). In
71 order to make drivers as small as possible, there are a few calling
72 restrictions for this service. ConnectController() must
73 follow these calling restrictions. If any other agent wishes to call
74 Supported() it must also follow these calling restrictions.
76 @param[in] This Protocol instance pointer.
77 @param[in] ControllerHandle Handle of device to test.
78 @param[in] RemainingDevicePath Optional parameter use to pick a specific
79 child device to start.
81 @retval EFI_SUCCESS This driver supports this device.
82 @retval EFI_ALREADY_STARTED This driver is already running on this device.
83 @retval Others This driver does not support this device.
88 MnpDriverBindingSupported (
89 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
90 IN EFI_HANDLE ControllerHandle
,
91 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
95 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
98 // Test to open the Simple Network protocol BY_DRIVER.
100 Status
= gBS
->OpenProtocol (
102 &gEfiSimpleNetworkProtocolGuid
,
104 This
->DriverBindingHandle
,
106 EFI_OPEN_PROTOCOL_BY_DRIVER
108 if (EFI_ERROR (Status
)) {
113 // Close the openned SNP protocol.
117 &gEfiSimpleNetworkProtocolGuid
,
118 This
->DriverBindingHandle
,
127 Start this driver on ControllerHandle. This service is called by the
128 EFI boot service ConnectController(). In order to make drivers as small
129 as possible, there are a few calling restrictions for this service.
130 ConnectController() must follow these calling restrictions. If any other
131 agent wishes to call Start() it must also follow these calling restrictions.
133 @param[in] This Protocol instance pointer.
134 @param[in] ControllerHandle Handle of device to bind driver to.
135 @param[in] RemainingDevicePath Optional parameter use to pick a specific
136 child device to start.
138 @retval EFI_SUCCESS This driver is added to ControllerHandle.
139 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
140 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Mnp Service Data.
141 @retval Others This driver does not support this device.
146 MnpDriverBindingStart (
147 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
148 IN EFI_HANDLE ControllerHandle
,
149 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
153 MNP_SERVICE_DATA
*MnpServiceData
;
154 MNP_DEVICE_DATA
*MnpDeviceData
;
156 VLAN_TCI
*VlanVariable
;
163 // Initialize the Mnp Device Data
165 MnpDeviceData
= AllocateZeroPool (sizeof (MNP_DEVICE_DATA
));
166 if (MnpDeviceData
== NULL
) {
167 DEBUG ((EFI_D_ERROR
, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));
169 return EFI_OUT_OF_RESOURCES
;
172 Status
= MnpInitializeDeviceData (MnpDeviceData
, This
->DriverBindingHandle
, ControllerHandle
);
173 if (EFI_ERROR (Status
)) {
174 DEBUG ((EFI_D_ERROR
, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status
));
176 FreePool (MnpDeviceData
);
181 // Check whether NIC driver has already produced VlanConfig protocol
183 Status
= gBS
->OpenProtocol (
185 &gEfiVlanConfigProtocolGuid
,
187 This
->DriverBindingHandle
,
189 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
191 if (!EFI_ERROR (Status
)) {
193 // NIC hardware already implement VLAN,
194 // no need to provide software VLAN implementation in MNP driver
196 MnpDeviceData
->NumberOfVlan
= 0;
197 ZeroMem (&MnpDeviceData
->VlanConfig
, sizeof (EFI_VLAN_CONFIG_PROTOCOL
));
198 MnpServiceData
= MnpCreateServiceData (MnpDeviceData
, 0, 0);
199 Status
= (MnpServiceData
!= NULL
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
204 // Install VLAN Config Protocol
206 Status
= gBS
->InstallMultipleProtocolInterfaces (
208 &gEfiVlanConfigProtocolGuid
,
209 &MnpDeviceData
->VlanConfig
,
212 if (EFI_ERROR (Status
)) {
217 // Get current VLAN configuration from EFI Variable
220 Status
= MnpGetVlanVariable (MnpDeviceData
, &NumberOfVlan
, &VlanVariable
);
221 if (EFI_ERROR (Status
)) {
223 // No VLAN is set, create a default MNP service data for untagged frame
225 MnpDeviceData
->NumberOfVlan
= 0;
226 MnpServiceData
= MnpCreateServiceData (MnpDeviceData
, 0, 0);
227 Status
= (MnpServiceData
!= NULL
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
232 // Create MNP service data for each VLAN
234 MnpDeviceData
->NumberOfVlan
= NumberOfVlan
;
235 for (Index
= 0; Index
< NumberOfVlan
; Index
++) {
236 MnpServiceData
= MnpCreateServiceData (
238 VlanVariable
[Index
].Bits
.Vid
,
239 (UINT8
) VlanVariable
[Index
].Bits
.Priority
242 if (MnpServiceData
== NULL
) {
243 Status
= EFI_OUT_OF_RESOURCES
;
250 if (VlanVariable
!= NULL
) {
251 FreePool (VlanVariable
);
254 if (EFI_ERROR (Status
)) {
256 // Destroy all MNP service data
258 while (!IsListEmpty (&MnpDeviceData
->ServiceList
)) {
259 Entry
= GetFirstNode (&MnpDeviceData
->ServiceList
);
260 MnpServiceData
= MNP_SERVICE_DATA_FROM_LINK (Entry
);
261 MnpDestroyServiceData (MnpServiceData
);
265 // Uninstall the VLAN Config Protocol if any
267 if (MnpDeviceData
->VlanConfig
.Set
!= NULL
) {
268 gBS
->UninstallMultipleProtocolInterfaces (
269 MnpDeviceData
->ControllerHandle
,
270 &gEfiVlanConfigProtocolGuid
,
271 &MnpDeviceData
->VlanConfig
,
277 // Destroy Mnp Device Data
279 MnpDestroyDeviceData (MnpDeviceData
, This
->DriverBindingHandle
);
280 FreePool (MnpDeviceData
);
287 Stop this driver on ControllerHandle. This service is called by the
288 EFI boot service DisconnectController(). In order to make drivers as
289 small as possible, there are a few calling restrictions for this service.
290 DisconnectController() must follow these calling restrictions. If any other
291 agent wishes to call Stop() it must also follow these calling restrictions.
293 @param[in] This Protocol instance pointer.
294 @param[in] ControllerHandle Handle of device to stop driver on.
295 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If
296 number of children is zero stop the entire
298 @param[in] ChildHandleBuffer List of Child Handles to Stop.
300 @retval EFI_SUCCESS This driver is removed ControllerHandle.
301 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
306 MnpDriverBindingStop (
307 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
308 IN EFI_HANDLE ControllerHandle
,
309 IN UINTN NumberOfChildren
,
310 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
314 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
315 EFI_VLAN_CONFIG_PROTOCOL
*VlanConfig
;
316 MNP_DEVICE_DATA
*MnpDeviceData
;
317 MNP_SERVICE_DATA
*MnpServiceData
;
322 // Try to retrieve MNP service binding protocol from the ControllerHandle
324 Status
= gBS
->OpenProtocol (
326 &gEfiManagedNetworkServiceBindingProtocolGuid
,
327 (VOID
**) &ServiceBinding
,
328 This
->DriverBindingHandle
,
330 EFI_OPEN_PROTOCOL_GET_PROTOCOL
332 if (EFI_ERROR (Status
)) {
334 // Retrieve VLAN Config Protocol from the ControllerHandle
336 Status
= gBS
->OpenProtocol (
338 &gEfiVlanConfigProtocolGuid
,
339 (VOID
**) &VlanConfig
,
340 This
->DriverBindingHandle
,
342 EFI_OPEN_PROTOCOL_GET_PROTOCOL
344 if (EFI_ERROR (Status
)) {
345 DEBUG ((EFI_D_ERROR
, "MnpDriverBindingStop: try to stop unknown Controller.\n"));
346 return EFI_DEVICE_ERROR
;
349 MnpDeviceData
= MNP_DEVICE_DATA_FROM_THIS (VlanConfig
);
351 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
352 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
355 if (NumberOfChildren
== 0) {
357 // Destroy all MNP service data
359 List
= &MnpDeviceData
->ServiceList
;
360 Status
= NetDestroyLinkList (
362 MnpDestroyServiceDataEntry
,
366 if (EFI_ERROR (Status
) || ListLength
!=0) {
367 return EFI_DEVICE_ERROR
;
371 // Uninstall the VLAN Config Protocol if any
373 if (MnpDeviceData
->VlanConfig
.Set
!= NULL
) {
374 gBS
->UninstallMultipleProtocolInterfaces (
375 MnpDeviceData
->ControllerHandle
,
376 &gEfiVlanConfigProtocolGuid
,
377 &MnpDeviceData
->VlanConfig
,
383 // Destroy Mnp Device Data
385 MnpDestroyDeviceData (MnpDeviceData
, This
->DriverBindingHandle
);
386 FreePool (MnpDeviceData
);
388 if (gMnpControllerNameTable
!= NULL
) {
389 FreeUnicodeStringTable (gMnpControllerNameTable
);
390 gMnpControllerNameTable
= NULL
;
396 // Stop all MNP child
398 List
= &MnpDeviceData
->ServiceList
;
399 Status
= NetDestroyLinkList (
401 MnpDestroyServiceChildEntry
,
405 if (EFI_ERROR (Status
)) {
406 return EFI_DEVICE_ERROR
;
414 Creates a child handle with a set of I/O services.
416 @param[in] This Protocol instance pointer.
417 @param[in, out] ChildHandle Pointer to the handle of the child to create. If
418 it is NULL, then a new handle is created. If
419 it is not NULL, then the I/O services are added
420 to the existing child handle.
422 @retval EFI_SUCCES The protocol was added to ChildHandle.
423 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
424 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
426 @retval Others The child handle was not created.
431 MnpServiceBindingCreateChild (
432 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
433 IN OUT EFI_HANDLE
*ChildHandle
437 MNP_SERVICE_DATA
*MnpServiceData
;
438 MNP_INSTANCE_DATA
*Instance
;
442 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
443 return EFI_INVALID_PARAMETER
;
446 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
449 // Allocate buffer for the new instance.
451 Instance
= AllocateZeroPool (sizeof (MNP_INSTANCE_DATA
));
452 if (Instance
== NULL
) {
453 DEBUG ((EFI_D_ERROR
, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));
455 return EFI_OUT_OF_RESOURCES
;
459 // Init the instance data.
461 MnpInitializeInstanceData (MnpServiceData
, Instance
);
463 Status
= gBS
->InstallMultipleProtocolInterfaces (
465 &gEfiManagedNetworkProtocolGuid
,
466 &Instance
->ManagedNetwork
,
469 if (EFI_ERROR (Status
)) {
472 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
480 // Save the instance's childhandle.
482 Instance
->Handle
= *ChildHandle
;
484 Status
= gBS
->OpenProtocol (
485 MnpServiceData
->ServiceHandle
,
486 &gEfiManagedNetworkServiceBindingProtocolGuid
,
488 gMnpDriverBinding
.DriverBindingHandle
,
490 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
492 if (EFI_ERROR (Status
)) {
497 // Add the child instance into ChildrenList.
499 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
501 InsertTailList (&MnpServiceData
->ChildrenList
, &Instance
->InstEntry
);
502 MnpServiceData
->ChildrenNumber
++;
504 gBS
->RestoreTPL (OldTpl
);
508 if (EFI_ERROR (Status
)) {
510 if (Instance
->Handle
!= NULL
) {
512 gBS
->UninstallMultipleProtocolInterfaces (
514 &gEfiManagedNetworkProtocolGuid
,
515 &Instance
->ManagedNetwork
,
528 Destroys a child handle with a set of I/O services.
530 The DestroyChild() function does the opposite of CreateChild(). It removes a
531 protocol that was installed by CreateChild() from ChildHandle. If the removed
532 protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.
534 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
536 @param[in] ChildHandle Handle of the child to destroy.
538 @retval EFI_SUCCES The protocol was removed from ChildHandle.
539 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that
541 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
542 @retval EFI_ACCESS_DENIED The protocol could not be removed from the
543 ChildHandle because its services are being
545 @retval Others The child handle was not destroyed.
550 MnpServiceBindingDestroyChild (
551 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
552 IN EFI_HANDLE ChildHandle
556 MNP_SERVICE_DATA
*MnpServiceData
;
557 EFI_MANAGED_NETWORK_PROTOCOL
*ManagedNetwork
;
558 MNP_INSTANCE_DATA
*Instance
;
561 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
562 return EFI_INVALID_PARAMETER
;
565 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
568 // Try to retrieve ManagedNetwork Protocol from ChildHandle.
570 Status
= gBS
->OpenProtocol (
572 &gEfiManagedNetworkProtocolGuid
,
573 (VOID
**) &ManagedNetwork
,
574 gMnpDriverBinding
.DriverBindingHandle
,
576 EFI_OPEN_PROTOCOL_GET_PROTOCOL
578 if (EFI_ERROR (Status
)) {
579 return EFI_UNSUPPORTED
;
582 Instance
= MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork
);
585 // MnpServiceBindingDestroyChild may be called twice: first called by
586 // MnpServiceBindingStop, second called by uninstalling the MNP protocol
587 // in this ChildHandle. Use destroyed to make sure the resource clean code
588 // will only excecute once.
590 if (Instance
->Destroyed
) {
594 Instance
->Destroyed
= TRUE
;
597 // Close the Simple Network protocol.
600 MnpServiceData
->ServiceHandle
,
601 &gEfiManagedNetworkServiceBindingProtocolGuid
,
602 MnpServiceData
->MnpDeviceData
->ImageHandle
,
607 // Uninstall the ManagedNetwork protocol.
609 Status
= gBS
->UninstallMultipleProtocolInterfaces (
611 &gEfiManagedNetworkProtocolGuid
,
612 &Instance
->ManagedNetwork
,
615 if (EFI_ERROR (Status
)) {
618 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
622 Instance
->Destroyed
= FALSE
;
626 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
629 // Reset the configuration.
631 ManagedNetwork
->Configure (ManagedNetwork
, NULL
);
634 // Try to flush the RcvdPacketQueue.
636 MnpFlushRcvdDataQueue (Instance
);
639 // Clean the RxTokenMap.
641 NetMapClean (&Instance
->RxTokenMap
);
644 // Remove this instance from the ChildrenList.
646 RemoveEntryList (&Instance
->InstEntry
);
647 MnpServiceData
->ChildrenNumber
--;
649 gBS
->RestoreTPL (OldTpl
);
657 The entry point for Mnp driver which installs the driver binding and component
658 name protocol on its ImageHandle.
660 @param[in] ImageHandle The image handle of the driver.
661 @param[in] SystemTable The system table.
663 @retval EFI_SUCCES The driver binding and component name protocols are
664 successfully installed.
665 @retval Others Other errors as indicated.
670 MnpDriverEntryPoint (
671 IN EFI_HANDLE ImageHandle
,
672 IN EFI_SYSTEM_TABLE
*SystemTable
675 return EfiLibInstallDriverBindingComponentName2 (