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 opened SNP protocol.
117 &gEfiSimpleNetworkProtocolGuid
,
118 This
->DriverBindingHandle
,
126 Start this driver on ControllerHandle. This service is called by the
127 EFI boot service ConnectController(). In order to make drivers as small
128 as possible, there are a few calling restrictions for this service.
129 ConnectController() must follow these calling restrictions. If any other
130 agent wishes to call Start() it must also follow these calling restrictions.
132 @param[in] This Protocol instance pointer.
133 @param[in] ControllerHandle Handle of device to bind driver to.
134 @param[in] RemainingDevicePath Optional parameter use to pick a specific
135 child device to start.
137 @retval EFI_SUCCESS This driver is added to ControllerHandle.
138 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
139 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Mnp Service Data.
140 @retval Others This driver does not support this device.
145 MnpDriverBindingStart (
146 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
147 IN EFI_HANDLE ControllerHandle
,
148 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
152 MNP_SERVICE_DATA
*MnpServiceData
;
153 MNP_DEVICE_DATA
*MnpDeviceData
;
155 VLAN_TCI
*VlanVariable
;
162 // Initialize the Mnp Device Data
164 MnpDeviceData
= AllocateZeroPool (sizeof (MNP_DEVICE_DATA
));
165 if (MnpDeviceData
== NULL
) {
166 DEBUG ((DEBUG_ERROR
, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));
168 return EFI_OUT_OF_RESOURCES
;
171 Status
= MnpInitializeDeviceData (MnpDeviceData
, This
->DriverBindingHandle
, ControllerHandle
);
172 if (EFI_ERROR (Status
)) {
173 DEBUG ((DEBUG_ERROR
, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status
));
175 FreePool (MnpDeviceData
);
180 // Check whether NIC driver has already produced VlanConfig protocol
182 Status
= gBS
->OpenProtocol (
184 &gEfiVlanConfigProtocolGuid
,
186 This
->DriverBindingHandle
,
188 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
190 if (!EFI_ERROR (Status
)) {
192 // NIC hardware already implement VLAN,
193 // no need to provide software VLAN implementation in MNP driver
195 MnpDeviceData
->NumberOfVlan
= 0;
196 ZeroMem (&MnpDeviceData
->VlanConfig
, sizeof (EFI_VLAN_CONFIG_PROTOCOL
));
197 MnpServiceData
= MnpCreateServiceData (MnpDeviceData
, 0, 0);
198 Status
= (MnpServiceData
!= NULL
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
203 // Install VLAN Config Protocol
205 Status
= gBS
->InstallMultipleProtocolInterfaces (
207 &gEfiVlanConfigProtocolGuid
,
208 &MnpDeviceData
->VlanConfig
,
211 if (EFI_ERROR (Status
)) {
216 // Get current VLAN configuration from EFI Variable
219 Status
= MnpGetVlanVariable (MnpDeviceData
, &NumberOfVlan
, &VlanVariable
);
220 if (EFI_ERROR (Status
)) {
222 // No VLAN is set, create a default MNP service data for untagged frame
224 MnpDeviceData
->NumberOfVlan
= 0;
225 MnpServiceData
= MnpCreateServiceData (MnpDeviceData
, 0, 0);
226 Status
= (MnpServiceData
!= NULL
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
231 // Create MNP service data for each VLAN
233 MnpDeviceData
->NumberOfVlan
= NumberOfVlan
;
234 for (Index
= 0; Index
< NumberOfVlan
; Index
++) {
235 MnpServiceData
= MnpCreateServiceData (
237 VlanVariable
[Index
].Bits
.Vid
,
238 (UINT8
)VlanVariable
[Index
].Bits
.Priority
241 if (MnpServiceData
== NULL
) {
242 Status
= EFI_OUT_OF_RESOURCES
;
249 if (VlanVariable
!= NULL
) {
250 FreePool (VlanVariable
);
253 if (EFI_ERROR (Status
)) {
255 // Destroy all MNP service data
257 while (!IsListEmpty (&MnpDeviceData
->ServiceList
)) {
258 Entry
= GetFirstNode (&MnpDeviceData
->ServiceList
);
259 MnpServiceData
= MNP_SERVICE_DATA_FROM_LINK (Entry
);
260 MnpDestroyServiceData (MnpServiceData
);
264 // Uninstall the VLAN Config Protocol if any
266 if (MnpDeviceData
->VlanConfig
.Set
!= NULL
) {
267 gBS
->UninstallMultipleProtocolInterfaces (
268 MnpDeviceData
->ControllerHandle
,
269 &gEfiVlanConfigProtocolGuid
,
270 &MnpDeviceData
->VlanConfig
,
276 // Destroy Mnp Device Data
278 MnpDestroyDeviceData (MnpDeviceData
, This
->DriverBindingHandle
);
279 FreePool (MnpDeviceData
);
286 Stop this driver on ControllerHandle. This service is called by the
287 EFI boot service DisconnectController(). In order to make drivers as
288 small as possible, there are a few calling restrictions for this service.
289 DisconnectController() must follow these calling restrictions. If any other
290 agent wishes to call Stop() it must also follow these calling restrictions.
292 @param[in] This Protocol instance pointer.
293 @param[in] ControllerHandle Handle of device to stop driver on.
294 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If
295 number of children is zero stop the entire
297 @param[in] ChildHandleBuffer List of Child Handles to Stop.
299 @retval EFI_SUCCESS This driver is removed ControllerHandle.
300 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
305 MnpDriverBindingStop (
306 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
307 IN EFI_HANDLE ControllerHandle
,
308 IN UINTN NumberOfChildren
,
309 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
313 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
314 EFI_VLAN_CONFIG_PROTOCOL
*VlanConfig
;
315 MNP_DEVICE_DATA
*MnpDeviceData
;
316 MNP_SERVICE_DATA
*MnpServiceData
;
321 // Try to retrieve MNP service binding protocol from the ControllerHandle
323 Status
= gBS
->OpenProtocol (
325 &gEfiManagedNetworkServiceBindingProtocolGuid
,
326 (VOID
**)&ServiceBinding
,
327 This
->DriverBindingHandle
,
329 EFI_OPEN_PROTOCOL_GET_PROTOCOL
331 if (EFI_ERROR (Status
)) {
333 // Retrieve VLAN Config Protocol from the ControllerHandle
335 Status
= gBS
->OpenProtocol (
337 &gEfiVlanConfigProtocolGuid
,
338 (VOID
**)&VlanConfig
,
339 This
->DriverBindingHandle
,
341 EFI_OPEN_PROTOCOL_GET_PROTOCOL
343 if (EFI_ERROR (Status
)) {
344 DEBUG ((DEBUG_ERROR
, "MnpDriverBindingStop: try to stop unknown Controller.\n"));
345 return EFI_DEVICE_ERROR
;
348 MnpDeviceData
= MNP_DEVICE_DATA_FROM_THIS (VlanConfig
);
350 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
351 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
354 if (NumberOfChildren
== 0) {
356 // Destroy all MNP service data
358 List
= &MnpDeviceData
->ServiceList
;
359 Status
= NetDestroyLinkList (
361 MnpDestroyServiceDataEntry
,
365 if (EFI_ERROR (Status
) || (ListLength
!= 0)) {
366 return EFI_DEVICE_ERROR
;
370 // Uninstall the VLAN Config Protocol if any
372 if (MnpDeviceData
->VlanConfig
.Set
!= NULL
) {
373 gBS
->UninstallMultipleProtocolInterfaces (
374 MnpDeviceData
->ControllerHandle
,
375 &gEfiVlanConfigProtocolGuid
,
376 &MnpDeviceData
->VlanConfig
,
382 // Destroy Mnp Device Data
384 MnpDestroyDeviceData (MnpDeviceData
, This
->DriverBindingHandle
);
385 FreePool (MnpDeviceData
);
387 if (gMnpControllerNameTable
!= NULL
) {
388 FreeUnicodeStringTable (gMnpControllerNameTable
);
389 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
;
413 Creates a child handle with a set of I/O services.
415 @param[in] This Protocol instance pointer.
416 @param[in, out] ChildHandle Pointer to the handle of the child to create. If
417 it is NULL, then a new handle is created. If
418 it is not NULL, then the I/O services are added
419 to the existing child handle.
421 @retval EFI_SUCCESS The protocol was added to ChildHandle.
422 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
423 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
425 @retval Others The child handle was not created.
430 MnpServiceBindingCreateChild (
431 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
432 IN OUT EFI_HANDLE
*ChildHandle
436 MNP_SERVICE_DATA
*MnpServiceData
;
437 MNP_INSTANCE_DATA
*Instance
;
441 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
442 return EFI_INVALID_PARAMETER
;
445 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
448 // Allocate buffer for the new instance.
450 Instance
= AllocateZeroPool (sizeof (MNP_INSTANCE_DATA
));
451 if (Instance
== NULL
) {
452 DEBUG ((DEBUG_ERROR
, "MnpServiceBindingCreateChild: Failed to allocate memory for the new instance.\n"));
454 return EFI_OUT_OF_RESOURCES
;
458 // Init the instance data.
460 MnpInitializeInstanceData (MnpServiceData
, Instance
);
462 Status
= gBS
->InstallMultipleProtocolInterfaces (
464 &gEfiManagedNetworkProtocolGuid
,
465 &Instance
->ManagedNetwork
,
468 if (EFI_ERROR (Status
)) {
471 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
479 // Save the instance's childhandle.
481 Instance
->Handle
= *ChildHandle
;
483 Status
= gBS
->OpenProtocol (
484 MnpServiceData
->ServiceHandle
,
485 &gEfiManagedNetworkServiceBindingProtocolGuid
,
487 gMnpDriverBinding
.DriverBindingHandle
,
489 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
491 if (EFI_ERROR (Status
)) {
496 // Add the child instance into ChildrenList.
498 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
500 InsertTailList (&MnpServiceData
->ChildrenList
, &Instance
->InstEntry
);
501 MnpServiceData
->ChildrenNumber
++;
503 gBS
->RestoreTPL (OldTpl
);
507 if (EFI_ERROR (Status
)) {
508 if (Instance
->Handle
!= NULL
) {
509 gBS
->UninstallMultipleProtocolInterfaces (
511 &gEfiManagedNetworkProtocolGuid
,
512 &Instance
->ManagedNetwork
,
524 Destroys a child handle with a set of I/O services.
526 The DestroyChild() function does the opposite of CreateChild(). It removes a
527 protocol that was installed by CreateChild() from ChildHandle. If the removed
528 protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.
530 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
532 @param[in] ChildHandle Handle of the child to destroy.
534 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
535 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that
537 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
538 @retval EFI_ACCESS_DENIED The protocol could not be removed from the
539 ChildHandle because its services are being
541 @retval Others The child handle was not destroyed.
546 MnpServiceBindingDestroyChild (
547 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
548 IN EFI_HANDLE ChildHandle
552 MNP_SERVICE_DATA
*MnpServiceData
;
553 EFI_MANAGED_NETWORK_PROTOCOL
*ManagedNetwork
;
554 MNP_INSTANCE_DATA
*Instance
;
557 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
558 return EFI_INVALID_PARAMETER
;
561 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
564 // Try to retrieve ManagedNetwork Protocol from ChildHandle.
566 Status
= gBS
->OpenProtocol (
568 &gEfiManagedNetworkProtocolGuid
,
569 (VOID
**)&ManagedNetwork
,
570 gMnpDriverBinding
.DriverBindingHandle
,
572 EFI_OPEN_PROTOCOL_GET_PROTOCOL
574 if (EFI_ERROR (Status
)) {
575 return EFI_UNSUPPORTED
;
578 Instance
= MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork
);
581 // MnpServiceBindingDestroyChild may be called twice: first called by
582 // MnpServiceBindingStop, second called by uninstalling the MNP protocol
583 // in this ChildHandle. Use destroyed to make sure the resource clean code
584 // will only excecute once.
586 if (Instance
->Destroyed
) {
590 Instance
->Destroyed
= TRUE
;
593 // Close the Simple Network protocol.
596 MnpServiceData
->ServiceHandle
,
597 &gEfiManagedNetworkServiceBindingProtocolGuid
,
598 MnpServiceData
->MnpDeviceData
->ImageHandle
,
603 // Uninstall the ManagedNetwork protocol.
605 Status
= gBS
->UninstallMultipleProtocolInterfaces (
607 &gEfiManagedNetworkProtocolGuid
,
608 &Instance
->ManagedNetwork
,
611 if (EFI_ERROR (Status
)) {
614 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
618 Instance
->Destroyed
= FALSE
;
622 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
625 // Reset the configuration.
627 ManagedNetwork
->Configure (ManagedNetwork
, NULL
);
630 // Try to flush the RcvdPacketQueue.
632 MnpFlushRcvdDataQueue (Instance
);
635 // Clean the RxTokenMap.
637 NetMapClean (&Instance
->RxTokenMap
);
640 // Remove this instance from the ChildrenList.
642 RemoveEntryList (&Instance
->InstEntry
);
643 MnpServiceData
->ChildrenNumber
--;
645 gBS
->RestoreTPL (OldTpl
);
653 The entry point for Mnp driver which installs the driver binding and component
654 name protocol on its ImageHandle.
656 @param[in] ImageHandle The image handle of the driver.
657 @param[in] SystemTable The system table.
659 @retval EFI_SUCCESS The driver binding and component name protocols are
660 successfully installed.
661 @retval Others Other errors as indicated.
666 MnpDriverEntryPoint (
667 IN EFI_HANDLE ImageHandle
,
668 IN EFI_SYSTEM_TABLE
*SystemTable
671 return EfiLibInstallDriverBindingComponentName2 (