NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg

Signed-off-by: Liming Gao <liming.gao@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
This commit is contained in:
Liming Gao
2019-05-15 20:02:18 +08:00
parent c0fd7f734e
commit 4542f8b813
147 changed files with 24 additions and 24 deletions

View File

@@ -0,0 +1,341 @@
/** @file
UEFI Component Name(2) protocol implementation for MnpDxe driver.
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "MnpImpl.h"
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gMnpComponentName = {
MnpComponentNameGetDriverName,
MnpComponentNameGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gMnpComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) MnpComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) MnpComponentNameGetControllerName,
"en"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMnpDriverNameTable[] = {
{
"eng;en",
L"MNP Network Service Driver"
},
{
NULL,
NULL
}
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMnpControllerNameTable = NULL;
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param[out] DriverName A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
MnpComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mMnpDriverNameTable,
DriverName,
(BOOLEAN) (This == &gMnpComponentName)
);
}
/**
Update the component name for the MNP child handle.
@param Mnp[in] A pointer to the EFI_MANAGED_NETWORK_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
CHAR16 HandleName[80];
EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
EFI_SIMPLE_NETWORK_MODE SnpModeData;
UINTN OffSet;
UINTN Index;
if (Mnp == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (Mnp);
//
// Format the child name into the string buffer as:
// MNP (MAC=FF-FF-FF-FF-FF-FF, ProtocolType=0x0800, VlanId=0)
//
Status = Mnp->GetModeData (Mnp, &MnpConfigData, &SnpModeData);
if (!EFI_ERROR (Status)) {
OffSet = 0;
//
// Print the MAC address.
//
OffSet += UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"MNP (MAC="
);
for (Index = 0; Index < SnpModeData.HwAddressSize; Index++) {
OffSet += UnicodeSPrint (
HandleName + OffSet,
sizeof (HandleName) - OffSet * sizeof (CHAR16),
L"%02X-",
SnpModeData.CurrentAddress.Addr[Index]
);
}
ASSERT (OffSet > 0);
//
// Remove the last '-'
//
OffSet--;
//
// Print the ProtocolType and VLAN ID for this instance.
//
OffSet += UnicodeSPrint (
HandleName + OffSet,
sizeof (HandleName) - OffSet * sizeof (CHAR16),
L", ProtocolType=0x%X, VlanId=%d)",
MnpConfigData.ProtocolTypeFilter,
Instance->MnpServiceData->VlanId
);
} else if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"MNP (Not started)"
);
} else {
return Status;
}
if (gMnpControllerNameTable != NULL) {
FreeUnicodeStringTable (gMnpControllerNameTable);
gMnpControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gMnpComponentName.SupportedLanguages,
&gMnpControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gMnpComponentName2.SupportedLanguages,
&gMnpControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
Currently not implemented.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] ControllerHandle The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param[in] ChildHandle The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param[out] ControllerName A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name
specified by This, ControllerHandle, ChildHandle,
and Language was returned in ControllerName.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
MnpComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
//
// Only provide names for MNP child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gMnpDriverBinding.DriverBindingHandle,
&gEfiSimpleNetworkProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiManagedNetworkProtocolGuid,
(VOID **)&Mnp,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Mnp);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gMnpControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gMnpComponentName)
);
}

View File

@@ -0,0 +1,144 @@
/** @file
The header file of UEFI Component Name(2) protocol.
Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _COMPONENT_NAME_H_
#define _COMPONENT_NAME_H_
#include <Protocol/ComponentName.h>
#include <Protocol/ComponentName2.h>
extern EFI_COMPONENT_NAME2_PROTOCOL gMnpComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gMnpComponentName;
extern EFI_UNICODE_STRING_TABLE *gMnpControllerNameTable;
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param[out] DriverName A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
MnpComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
Currently not implemented.
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param[in] ControllerHandle The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param[in] ChildHandle The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param[in] Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param[out] ControllerName A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name
specified by This, ControllerHandle, ChildHandle,
and Language was returned in ControllerName.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
MnpComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,683 @@
/** @file
Implementation of driver entry point and driver binding protocol.
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "MnpDriver.h"
#include "MnpImpl.h"
#include "MnpVlan.h"
EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
MnpDriverBindingSupported,
MnpDriverBindingStart,
MnpDriverBindingStop,
0xa,
NULL,
NULL
};
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
EFIAPI
MnpDestroyServiceDataEntry (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
MNP_SERVICE_DATA *MnpServiceData;
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
return MnpDestroyServiceData (MnpServiceData);
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
EFIAPI
MnpDestroyServiceChildEntry (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
MNP_SERVICE_DATA *MnpServiceData;
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
return MnpDestroyServiceChild (MnpServiceData);
}
/**
Test to see if this driver supports ControllerHandle. This service
is called by the EFI boot service ConnectController(). In
order to make drivers as small as possible, there are a few calling
restrictions for this service. ConnectController() must
follow these calling restrictions. If any other agent wishes to call
Supported() it must also follow these calling restrictions.
@param[in] This Protocol instance pointer.
@param[in] ControllerHandle Handle of device to test.
@param[in] RemainingDevicePath Optional parameter use to pick a specific
child device to start.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_ALREADY_STARTED This driver is already running on this device.
@retval Others This driver does not support this device.
**/
EFI_STATUS
EFIAPI
MnpDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
//
// Test to open the Simple Network protocol BY_DRIVER.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleNetworkProtocolGuid,
(VOID **) &Snp,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the openned SNP protocol.
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiSimpleNetworkProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
/**
Start this driver on ControllerHandle. This service is called by the
EFI boot service ConnectController(). In order to make drivers as small
as possible, there are a few calling restrictions for this service.
ConnectController() must follow these calling restrictions. If any other
agent wishes to call Start() it must also follow these calling restrictions.
@param[in] This Protocol instance pointer.
@param[in] ControllerHandle Handle of device to bind driver to.
@param[in] RemainingDevicePath Optional parameter use to pick a specific
child device to start.
@retval EFI_SUCCESS This driver is added to ControllerHandle.
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Mnp Service Data.
@retval Others This driver does not support this device.
**/
EFI_STATUS
EFIAPI
MnpDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
MNP_SERVICE_DATA *MnpServiceData;
MNP_DEVICE_DATA *MnpDeviceData;
LIST_ENTRY *Entry;
VLAN_TCI *VlanVariable;
UINTN NumberOfVlan;
UINTN Index;
VlanVariable = NULL;
//
// Initialize the Mnp Device Data
//
MnpDeviceData = AllocateZeroPool (sizeof (MNP_DEVICE_DATA));
if (MnpDeviceData == NULL) {
DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));
return EFI_OUT_OF_RESOURCES;
}
Status = MnpInitializeDeviceData (MnpDeviceData, This->DriverBindingHandle, ControllerHandle);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status));
FreePool (MnpDeviceData);
return Status;
}
//
// Check whether NIC driver has already produced VlanConfig protocol
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiVlanConfigProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
//
// NIC hardware already implement VLAN,
// no need to provide software VLAN implementation in MNP driver
//
MnpDeviceData->NumberOfVlan = 0;
ZeroMem (&MnpDeviceData->VlanConfig, sizeof (EFI_VLAN_CONFIG_PROTOCOL));
MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);
Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
goto Exit;
}
//
// Install VLAN Config Protocol
//
Status = gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiVlanConfigProtocolGuid,
&MnpDeviceData->VlanConfig,
NULL
);
if (EFI_ERROR (Status)) {
goto Exit;
}
//
// Get current VLAN configuration from EFI Variable
//
NumberOfVlan = 0;
Status = MnpGetVlanVariable (MnpDeviceData, &NumberOfVlan, &VlanVariable);
if (EFI_ERROR (Status)) {
//
// No VLAN is set, create a default MNP service data for untagged frame
//
MnpDeviceData->NumberOfVlan = 0;
MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);
Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
goto Exit;
}
//
// Create MNP service data for each VLAN
//
MnpDeviceData->NumberOfVlan = NumberOfVlan;
for (Index = 0; Index < NumberOfVlan; Index++) {
MnpServiceData = MnpCreateServiceData (
MnpDeviceData,
VlanVariable[Index].Bits.Vid,
(UINT8) VlanVariable[Index].Bits.Priority
);
if (MnpServiceData == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
}
Exit:
if (VlanVariable != NULL) {
FreePool (VlanVariable);
}
if (EFI_ERROR (Status)) {
//
// Destroy all MNP service data
//
while (!IsListEmpty (&MnpDeviceData->ServiceList)) {
Entry = GetFirstNode (&MnpDeviceData->ServiceList);
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
MnpDestroyServiceData (MnpServiceData);
}
//
// Uninstall the VLAN Config Protocol if any
//
if (MnpDeviceData->VlanConfig.Set != NULL) {
gBS->UninstallMultipleProtocolInterfaces (
MnpDeviceData->ControllerHandle,
&gEfiVlanConfigProtocolGuid,
&MnpDeviceData->VlanConfig,
NULL
);
}
//
// Destroy Mnp Device Data
//
MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);
FreePool (MnpDeviceData);
}
return Status;
}
/**
Stop this driver on ControllerHandle. This service is called by the
EFI boot service DisconnectController(). In order to make drivers as
small as possible, there are a few calling restrictions for this service.
DisconnectController() must follow these calling restrictions. If any other
agent wishes to call Stop() it must also follow these calling restrictions.
@param[in] This Protocol instance pointer.
@param[in] ControllerHandle Handle of device to stop driver on.
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If
number of children is zero stop the entire
bus driver.
@param[in] ChildHandleBuffer List of Child Handles to Stop.
@retval EFI_SUCCESS This driver is removed ControllerHandle.
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
**/
EFI_STATUS
EFIAPI
MnpDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
EFI_STATUS Status;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
LIST_ENTRY *List;
UINTN ListLength;
//
// Try to retrieve MNP service binding protocol from the ControllerHandle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid,
(VOID **) &ServiceBinding,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
//
// Retrieve VLAN Config Protocol from the ControllerHandle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiVlanConfigProtocolGuid,
(VOID **) &VlanConfig,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "MnpDriverBindingStop: try to stop unknown Controller.\n"));
return EFI_DEVICE_ERROR;
}
MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (VlanConfig);
} else {
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);
MnpDeviceData = MnpServiceData->MnpDeviceData;
}
if (NumberOfChildren == 0) {
//
// Destroy all MNP service data
//
List = &MnpDeviceData->ServiceList;
Status = NetDestroyLinkList (
List,
MnpDestroyServiceDataEntry,
NULL,
&ListLength
);
if (EFI_ERROR (Status) || ListLength !=0) {
return EFI_DEVICE_ERROR;
}
//
// Uninstall the VLAN Config Protocol if any
//
if (MnpDeviceData->VlanConfig.Set != NULL) {
gBS->UninstallMultipleProtocolInterfaces (
MnpDeviceData->ControllerHandle,
&gEfiVlanConfigProtocolGuid,
&MnpDeviceData->VlanConfig,
NULL
);
}
//
// Destroy Mnp Device Data
//
MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);
FreePool (MnpDeviceData);
if (gMnpControllerNameTable != NULL) {
FreeUnicodeStringTable (gMnpControllerNameTable);
gMnpControllerNameTable = NULL;
}
return EFI_SUCCESS;
}
//
// Stop all MNP child
//
List = &MnpDeviceData->ServiceList;
Status = NetDestroyLinkList (
List,
MnpDestroyServiceChildEntry,
NULL,
&ListLength
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Creates a child handle with a set of I/O services.
@param[in] This Protocol instance pointer.
@param[in, out] ChildHandle Pointer to the handle of the child to create. If
it is NULL, then a new handle is created. If
it is not NULL, then the I/O services are added
to the existing child handle.
@retval EFI_SUCCES The protocol was added to ChildHandle.
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to
create the child.
@retval Others The child handle was not created.
**/
EFI_STATUS
EFIAPI
MnpServiceBindingCreateChild (
IN EFI_SERVICE_BINDING_PROTOCOL *This,
IN OUT EFI_HANDLE *ChildHandle
)
{
EFI_STATUS Status;
MNP_SERVICE_DATA *MnpServiceData;
MNP_INSTANCE_DATA *Instance;
VOID *MnpSb;
EFI_TPL OldTpl;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
}
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);
//
// Allocate buffer for the new instance.
//
Instance = AllocateZeroPool (sizeof (MNP_INSTANCE_DATA));
if (Instance == NULL) {
DEBUG ((EFI_D_ERROR, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));
return EFI_OUT_OF_RESOURCES;
}
//
// Init the instance data.
//
MnpInitializeInstanceData (MnpServiceData, Instance);
Status = gBS->InstallMultipleProtocolInterfaces (
ChildHandle,
&gEfiManagedNetworkProtocolGuid,
&Instance->ManagedNetwork,
NULL
);
if (EFI_ERROR (Status)) {
DEBUG (
(EFI_D_ERROR,
"MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
Status)
);
goto ErrorExit;
}
//
// Save the instance's childhandle.
//
Instance->Handle = *ChildHandle;
Status = gBS->OpenProtocol (
MnpServiceData->ServiceHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid,
(VOID **) &MnpSb,
gMnpDriverBinding.DriverBindingHandle,
Instance->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
//
// Add the child instance into ChildrenList.
//
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
InsertTailList (&MnpServiceData->ChildrenList, &Instance->InstEntry);
MnpServiceData->ChildrenNumber++;
gBS->RestoreTPL (OldTpl);
ErrorExit:
if (EFI_ERROR (Status)) {
if (Instance->Handle != NULL) {
gBS->UninstallMultipleProtocolInterfaces (
Instance->Handle,
&gEfiManagedNetworkProtocolGuid,
&Instance->ManagedNetwork,
NULL
);
}
FreePool (Instance);
}
return Status;
}
/**
Destroys a child handle with a set of I/O services.
The DestroyChild() function does the opposite of CreateChild(). It removes a
protocol that was installed by CreateChild() from ChildHandle. If the removed
protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
instance.
@param[in] ChildHandle Handle of the child to destroy.
@retval EFI_SUCCES The protocol was removed from ChildHandle.
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that
is being removed.
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
@retval EFI_ACCESS_DENIED The protocol could not be removed from the
ChildHandle because its services are being
used.
@retval Others The child handle was not destroyed.
**/
EFI_STATUS
EFIAPI
MnpServiceBindingDestroyChild (
IN EFI_SERVICE_BINDING_PROTOCOL *This,
IN EFI_HANDLE ChildHandle
)
{
EFI_STATUS Status;
MNP_SERVICE_DATA *MnpServiceData;
EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;
MNP_INSTANCE_DATA *Instance;
EFI_TPL OldTpl;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
}
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);
//
// Try to retrieve ManagedNetwork Protocol from ChildHandle.
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiManagedNetworkProtocolGuid,
(VOID **) &ManagedNetwork,
gMnpDriverBinding.DriverBindingHandle,
ChildHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);
//
// MnpServiceBindingDestroyChild may be called twice: first called by
// MnpServiceBindingStop, second called by uninstalling the MNP protocol
// in this ChildHandle. Use destroyed to make sure the resource clean code
// will only excecute once.
//
if (Instance->Destroyed) {
return EFI_SUCCESS;
}
Instance->Destroyed = TRUE;
//
// Close the Simple Network protocol.
//
gBS->CloseProtocol (
MnpServiceData->ServiceHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid,
MnpServiceData->MnpDeviceData->ImageHandle,
ChildHandle
);
//
// Uninstall the ManagedNetwork protocol.
//
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandle,
&gEfiManagedNetworkProtocolGuid,
&Instance->ManagedNetwork,
NULL
);
if (EFI_ERROR (Status)) {
DEBUG (
(EFI_D_ERROR,
"MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
Status)
);
Instance->Destroyed = FALSE;
return Status;
}
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
// Reset the configuration.
//
ManagedNetwork->Configure (ManagedNetwork, NULL);
//
// Try to flush the RcvdPacketQueue.
//
MnpFlushRcvdDataQueue (Instance);
//
// Clean the RxTokenMap.
//
NetMapClean (&Instance->RxTokenMap);
//
// Remove this instance from the ChildrenList.
//
RemoveEntryList (&Instance->InstEntry);
MnpServiceData->ChildrenNumber--;
gBS->RestoreTPL (OldTpl);
FreePool (Instance);
return Status;
}
/**
The entry point for Mnp driver which installs the driver binding and component
name protocol on its ImageHandle.
@param[in] ImageHandle The image handle of the driver.
@param[in] SystemTable The system table.
@retval EFI_SUCCES The driver binding and component name protocols are
successfully installed.
@retval Others Other errors as indicated.
**/
EFI_STATUS
EFIAPI
MnpDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gMnpDriverBinding,
ImageHandle,
&gMnpComponentName,
&gMnpComponentName2
);
}

View File

@@ -0,0 +1,268 @@
/** @file
Declaration of strctures and functions for MnpDxe driver.
Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _MNP_DRIVER_H_
#define _MNP_DRIVER_H_
#include <Uefi.h>
#include <Protocol/ManagedNetwork.h>
#include <Protocol/SimpleNetwork.h>
#include <Protocol/ServiceBinding.h>
#include <Protocol/VlanConfig.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/NetLib.h>
#include <Library/DpcLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PrintLib.h>
#include "ComponentName.h"
#define MNP_DEVICE_DATA_SIGNATURE SIGNATURE_32 ('M', 'n', 'p', 'D')
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding;
typedef struct {
UINT32 Signature;
EFI_HANDLE ControllerHandle;
EFI_HANDLE ImageHandle;
EFI_VLAN_CONFIG_PROTOCOL VlanConfig;
UINTN NumberOfVlan;
CHAR16 *MacString;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
//
// List of MNP_SERVICE_DATA
//
LIST_ENTRY ServiceList;
//
// Number of configured MNP Service Binding child
//
UINTN ConfiguredChildrenNumber;
LIST_ENTRY GroupAddressList;
UINT32 GroupAddressCount;
LIST_ENTRY FreeTxBufList;
LIST_ENTRY AllTxBufList;
UINT32 TxBufCount;
NET_BUF_QUEUE FreeNbufQue;
INTN NbufCnt;
EFI_EVENT PollTimer;
BOOLEAN EnableSystemPoll;
EFI_EVENT TimeoutCheckTimer;
EFI_EVENT MediaDetectTimer;
UINT32 UnicastCount;
UINT32 BroadcastCount;
UINT32 MulticastCount;
UINT32 PromiscuousCount;
//
// The size of the data buffer in the MNP_PACKET_BUFFER used to
// store a packet.
//
UINT32 BufferLength;
UINT32 PaddingSize;
NET_BUF *RxNbufCache;
} MNP_DEVICE_DATA;
#define MNP_DEVICE_DATA_FROM_THIS(a) \
CR ( \
(a), \
MNP_DEVICE_DATA, \
VlanConfig, \
MNP_DEVICE_DATA_SIGNATURE \
)
#define MNP_SERVICE_DATA_SIGNATURE SIGNATURE_32 ('M', 'n', 'p', 'S')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
MNP_DEVICE_DATA *MnpDeviceData;
EFI_HANDLE ServiceHandle;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
LIST_ENTRY ChildrenList;
UINTN ChildrenNumber;
UINT32 Mtu;
UINT16 VlanId;
UINT8 Priority;
} MNP_SERVICE_DATA;
#define MNP_SERVICE_DATA_FROM_THIS(a) \
CR ( \
(a), \
MNP_SERVICE_DATA, \
ServiceBinding, \
MNP_SERVICE_DATA_SIGNATURE \
)
#define MNP_SERVICE_DATA_FROM_LINK(a) \
CR ( \
(a), \
MNP_SERVICE_DATA, \
Link, \
MNP_SERVICE_DATA_SIGNATURE \
)
/**
Test to see if this driver supports ControllerHandle. This service
is called by the EFI boot service ConnectController(). In
order to make drivers as small as possible, there are a few calling
restrictions for this service. ConnectController() must
follow these calling restrictions. If any other agent wishes to call
Supported() it must also follow these calling restrictions.
@param[in] This Protocol instance pointer.
@param[in] ControllerHandle Handle of device to test.
@param[in] RemainingDevicePath Optional parameter use to pick a specific
child device to start.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_ALREADY_STARTED This driver is already running on this device.
@retval Others This driver does not support this device.
**/
EFI_STATUS
EFIAPI
MnpDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
/**
Start this driver on ControllerHandle. This service is called by the
EFI boot service ConnectController(). In order to make drivers as small
as possible, there are a few calling restrictions for this service.
ConnectController() must follow these calling restrictions. If any other
agent wishes to call Start() it must also follow these calling restrictions.
@param[in] This Protocol instance pointer.
@param[in] ControllerHandle Handle of device to bind driver to.
@param[in] RemainingDevicePath Optional parameter use to pick a specific
child device to start.
@retval EFI_SUCCESS This driver is added to ControllerHandle.
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Mnp Service Data.
@retval Others This driver does not support this device.
**/
EFI_STATUS
EFIAPI
MnpDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
/**
Stop this driver on ControllerHandle. This service is called by the
EFI boot service DisconnectController(). In order to make drivers as
small as possible, there are a few calling restrictions for this service.
DisconnectController() must follow these calling restrictions. If any other
agent wishes to call Stop() it must also follow these calling restrictions.
@param[in] This Protocol instance pointer.
@param[in] ControllerHandle Handle of device to stop driver on.
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If
number of children is zero stop the entire
bus driver.
@param[in] ChildHandleBuffer List of Child Handles to Stop.
@retval EFI_SUCCESS This driver is removed ControllerHandle.
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
**/
EFI_STATUS
EFIAPI
MnpDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
);
/**
Creates a child handle with a set of I/O services.
@param[in] This Protocol instance pointer.
@param[in, out] ChildHandle Pointer to the handle of the child to create. If
it is NULL, then a new handle is created. If
it is not NULL, then the I/O services are added
to the existing child handle.
@retval EFI_SUCCES The protocol was added to ChildHandle.
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to
create the child.
@retval Others The child handle was not created.
**/
EFI_STATUS
EFIAPI
MnpServiceBindingCreateChild (
IN EFI_SERVICE_BINDING_PROTOCOL *This,
IN OUT EFI_HANDLE *ChildHandle
);
/**
Destroys a child handle with a set of I/O services.
The DestroyChild() function does the opposite of CreateChild(). It removes a
protocol that was installed by CreateChild() from ChildHandle. If the removed
protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
instance.
@param[in] ChildHandle Handle of the child to destroy.
@retval EFI_SUCCES The protocol was removed from ChildHandle.
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that
is being removed.
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
@retval EFI_ACCESS_DENIED The protocol could not be removed from the
ChildHandle because its services are being
used.
@retval Others The child handle was not destroyed.
**/
EFI_STATUS
EFIAPI
MnpServiceBindingDestroyChild (
IN EFI_SERVICE_BINDING_PROTOCOL *This,
IN EFI_HANDLE ChildHandle
);
#endif

View File

@@ -0,0 +1,68 @@
## @file
# This module produces EFI MNP Protocol, EFI MNP Servie Binding Protocol and EFI VLAN Protocol.
#
# This module produces EFI Managed Network Protocol upon EFI Simple Network Protocol,
# to provide raw asynchronous network I/O services. It also produces EFI VLAN Protocol
# to provide manageability interface for VLAN configuration.
#
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MnpDxe
MODULE_UNI_FILE = MnpDxe.uni
FILE_GUID = 025BBFC7-E6A9-4b8b-82AD-6815A1AEAF4A
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = MnpDriverEntryPoint
UNLOAD_IMAGE = NetLibDefaultUnload
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
# DRIVER_BINDING = gMnpDriverBinding
# COMPONENT_NAME = gMnpComponentName
# COMPONENT_NAME2 = gMnpComponentName2
#
[Sources]
MnpMain.c
MnpIo.c
ComponentName.h
MnpDriver.h
ComponentName.c
MnpDriver.c
MnpConfig.c
MnpImpl.h
MnpVlan.h
MnpVlan.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
MemoryAllocationLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
DebugLib
NetLib
DpcLib
[Protocols]
gEfiManagedNetworkServiceBindingProtocolGuid ## BY_START
gEfiSimpleNetworkProtocolGuid ## TO_START
gEfiManagedNetworkProtocolGuid ## BY_START
## BY_START
## UNDEFINED # variable
gEfiVlanConfigProtocolGuid
[UserExtensions.TianoCore."ExtraFiles"]
MnpDxeExtra.uni

View File

@@ -0,0 +1,18 @@
// /** @file
// This module produces EFI MNP Protocol, EFI MNP Servie Binding Protocol and EFI VLAN Protocol.
//
// This module produces EFI Managed Network Protocol upon EFI Simple Network Protocol,
// to provide raw asynchronous network I/O services. It also produces EFI VLAN Protocol
// to provide manageability interface for VLAN configuration.
//
// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Produces EFI MNP Protocol, EFI MNP Servie Binding Protocol and EFI VLAN Protocol"
#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI Managed Network Protocol upon EFI Simple Network Protocol to provide raw asynchronous network I/O services. It also produces EFI VLAN Protocol to provide manageability interface for VLAN configuration."

View File

@@ -0,0 +1,14 @@
// /** @file
// MnpDxe Localized Strings and Content
//
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"MNP DXE Driver"

898
NetworkPkg/MnpDxe/MnpImpl.h Normal file
View File

@@ -0,0 +1,898 @@
/** @file
Declaration of structures and functions of MnpDxe driver.
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _MNP_IMPL_H_
#define _MNP_IMPL_H_
#include "MnpDriver.h"
#define NET_ETHER_FCS_SIZE 4
#define MNP_SYS_POLL_INTERVAL (10 * TICKS_PER_MS) // 10 milliseconds
#define MNP_TIMEOUT_CHECK_INTERVAL (50 * TICKS_PER_MS) // 50 milliseconds
#define MNP_MEDIA_DETECT_INTERVAL (500 * TICKS_PER_MS) // 500 milliseconds
#define MNP_TX_TIMEOUT_TIME (500 * TICKS_PER_MS) // 500 milliseconds
#define MNP_INIT_NET_BUFFER_NUM 512
#define MNP_NET_BUFFER_INCREASEMENT 64
#define MNP_MAX_NET_BUFFER_NUM 65536
#define MNP_TX_BUFFER_INCREASEMENT 32 // Same as the recycling Q length for xmit_done in UNDI command.
#define MNP_MAX_TX_BUFFER_NUM 65536
#define MNP_MAX_RCVD_PACKET_QUE_SIZE 256
#define MNP_RECEIVE_UNICAST 0x01
#define MNP_RECEIVE_BROADCAST 0x02
#define UNICAST_PACKET MNP_RECEIVE_UNICAST
#define BROADCAST_PACKET MNP_RECEIVE_BROADCAST
#define MNP_INSTANCE_DATA_SIGNATURE SIGNATURE_32 ('M', 'n', 'p', 'I')
#define MNP_INSTANCE_DATA_FROM_THIS(a) \
CR ( \
(a), \
MNP_INSTANCE_DATA, \
ManagedNetwork, \
MNP_INSTANCE_DATA_SIGNATURE \
)
typedef struct {
UINT32 Signature;
MNP_SERVICE_DATA *MnpServiceData;
EFI_HANDLE Handle;
LIST_ENTRY InstEntry;
EFI_MANAGED_NETWORK_PROTOCOL ManagedNetwork;
BOOLEAN Configured;
BOOLEAN Destroyed;
LIST_ENTRY GroupCtrlBlkList;
NET_MAP RxTokenMap;
LIST_ENTRY RxDeliveredPacketQueue;
LIST_ENTRY RcvdPacketQueue;
UINTN RcvdPacketQueueSize;
EFI_MANAGED_NETWORK_CONFIG_DATA ConfigData;
UINT8 ReceiveFilter;
} MNP_INSTANCE_DATA;
typedef struct {
LIST_ENTRY AddrEntry;
EFI_MAC_ADDRESS Address;
INTN RefCnt;
} MNP_GROUP_ADDRESS;
typedef struct {
LIST_ENTRY CtrlBlkEntry;
MNP_GROUP_ADDRESS *GroupAddress;
} MNP_GROUP_CONTROL_BLOCK;
typedef struct {
LIST_ENTRY WrapEntry;
MNP_INSTANCE_DATA *Instance;
EFI_MANAGED_NETWORK_RECEIVE_DATA RxData;
NET_BUF *Nbuf;
UINT64 TimeoutTick;
} MNP_RXDATA_WRAP;
#define MNP_TX_BUF_WRAP_SIGNATURE SIGNATURE_32 ('M', 'T', 'B', 'W')
typedef struct {
UINT32 Signature;
LIST_ENTRY WrapEntry; // Link to FreeTxBufList
LIST_ENTRY AllEntry; // Link to AllTxBufList
BOOLEAN InUse;
UINT8 TxBuf[1];
} MNP_TX_BUF_WRAP;
/**
Initialize the mnp device context data.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@param[in] ImageHandle The driver image handle.
@param[in] ControllerHandle Handle of device to bind driver to.
@retval EFI_SUCCESS The mnp service context is initialized.
@retval EFI_UNSUPPORTED ControllerHandle does not support Simple Network Protocol.
@retval Others Other errors as indicated.
**/
EFI_STATUS
MnpInitializeDeviceData (
IN OUT MNP_DEVICE_DATA *MnpDeviceData,
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ControllerHandle
);
/**
Destroy the MNP device context data.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@param[in] ImageHandle The driver image handle.
**/
VOID
MnpDestroyDeviceData (
IN OUT MNP_DEVICE_DATA *MnpDeviceData,
IN EFI_HANDLE ImageHandle
);
/**
Create mnp service context data.
@param[in] MnpDeviceData Pointer to the mnp device context data.
@param[in] VlanId The VLAN ID.
@param[in] Priority The VLAN priority. If VlanId is 0,
Priority is ignored.
@return A pointer to MNP_SERVICE_DATA or NULL if failed to create MNP service context.
**/
MNP_SERVICE_DATA *
MnpCreateServiceData (
IN MNP_DEVICE_DATA *MnpDeviceData,
IN UINT16 VlanId,
IN UINT8 Priority OPTIONAL
);
/**
Initialize the mnp service context data.
@param[in, out] MnpServiceData Pointer to the mnp service context data.
@param[in] ImageHandle The driver image handle.
@param[in] ControllerHandle Handle of device to bind driver to.
@retval EFI_SUCCESS The mnp service context is initialized.
@retval EFI_UNSUPPORTED ControllerHandle does not support Simple Network Protocol.
@retval Others Other errors as indicated.
**/
EFI_STATUS
MnpInitializeServiceData (
IN OUT MNP_SERVICE_DATA *MnpServiceData,
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ControllerHandle
);
/**
Destroy the MNP service context data.
@param[in, out] MnpServiceData Pointer to the mnp service context data.
@retval EFI_SUCCESS The mnp service context is destroyed.
@retval Others Errors as indicated.
**/
EFI_STATUS
MnpDestroyServiceData (
IN OUT MNP_SERVICE_DATA *MnpServiceData
);
/**
Destroy all child of the MNP service data.
@param[in, out] MnpServiceData Pointer to the mnp service context data.
@retval EFI_SUCCESS All child are destroyed.
@retval Others Failed to destroy all child.
**/
EFI_STATUS
MnpDestroyServiceChild (
IN OUT MNP_SERVICE_DATA *MnpServiceData
);
/**
Find the MNP Service Data for given VLAN ID.
@param[in] MnpDeviceData Pointer to the mnp device context data.
@param[in] VlanId The VLAN ID.
@return A pointer to MNP_SERVICE_DATA or NULL if not found.
**/
MNP_SERVICE_DATA *
MnpFindServiceData (
IN MNP_DEVICE_DATA *MnpDeviceData,
IN UINT16 VlanId
);
/**
Initialize the mnp instance context data.
@param[in] MnpServiceData Pointer to the mnp service context data.
@param[in, out] Instance Pointer to the mnp instance context data
to initialize.
**/
VOID
MnpInitializeInstanceData (
IN MNP_SERVICE_DATA *MnpServiceData,
IN OUT MNP_INSTANCE_DATA *Instance
);
/**
Check whether the token specified by Arg matches the token in Item.
@param[in] Map Pointer to the NET_MAP.
@param[in] Item Pointer to the NET_MAP_ITEM.
@param[in] Arg Pointer to the Arg, it's a pointer to the token to
check.
@retval EFI_SUCCESS The token specified by Arg is different from the
token in Item.
@retval EFI_ACCESS_DENIED The token specified by Arg is the same as that in
Item.
**/
EFI_STATUS
EFIAPI
MnpTokenExist (
IN NET_MAP *Map,
IN NET_MAP_ITEM *Item,
IN VOID *Arg
);
/**
Cancel the token specified by Arg if it matches the token in Item.
@param[in, out] Map Pointer to the NET_MAP.
@param[in, out] Item Pointer to the NET_MAP_ITEM.
@param[in] Arg Pointer to the Arg, it's a pointer to the
token to cancel.
@retval EFI_SUCCESS The Arg is NULL, and the token in Item is cancelled,
or the Arg isn't NULL, and the token in Item is
different from the Arg.
@retval EFI_ABORTED The Arg isn't NULL, the token in Item mathces the
Arg, and the token is cancelled.
**/
EFI_STATUS
EFIAPI
MnpCancelTokens (
IN OUT NET_MAP *Map,
IN OUT NET_MAP_ITEM *Item,
IN VOID *Arg
);
/**
Flush the instance's received data.
@param[in, out] Instance Pointer to the mnp instance context data.
**/
VOID
MnpFlushRcvdDataQueue (
IN OUT MNP_INSTANCE_DATA *Instance
);
/**
Configure the Instance using ConfigData.
@param[in, out] Instance Pointer to the mnp instance context data.
@param[in] ConfigData Pointer to the configuration data used to configure
the isntance.
@retval EFI_SUCCESS The Instance is configured.
@retval EFI_UNSUPPORTED EnableReceiveTimestamps is on and the
implementation doesn't support it.
@retval Others Other errors as indicated.
**/
EFI_STATUS
MnpConfigureInstance (
IN OUT MNP_INSTANCE_DATA *Instance,
IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL
);
/**
Do the group operations for this instance.
@param[in, out] Instance Pointer to the instance context data.
@param[in] JoinFlag Set to TRUE to join a group. Set to TRUE to
leave a group/groups.
@param[in] MacAddress Pointer to the group address to join or leave.
@param[in] CtrlBlk Pointer to the group control block if JoinFlag
is FALSE.
@retval EFI_SUCCESS The group operation finished.
@retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources.
@retval Others Other errors as indicated.
**/
EFI_STATUS
MnpGroupOp (
IN OUT MNP_INSTANCE_DATA *Instance,
IN BOOLEAN JoinFlag,
IN EFI_MAC_ADDRESS *MacAddress OPTIONAL,
IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL
);
/**
Validates the Mnp transmit token.
@param[in] Instance Pointer to the Mnp instance context data.
@param[in] Token Pointer to the transmit token to check.
@return The Token is valid or not.
**/
BOOLEAN
MnpIsValidTxToken (
IN MNP_INSTANCE_DATA *Instance,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
);
/**
Build the packet to transmit from the TxData passed in.
@param[in] MnpServiceData Pointer to the mnp service context data.
@param[in] TxData Pointer to the transmit data containing the information
to build the packet.
@param[out] PktBuf Pointer to record the address of the packet.
@param[out] PktLen Pointer to a UINT32 variable used to record the packet's
length.
@retval EFI_SUCCESS TxPackage is built.
@retval EFI_OUT_OF_RESOURCES The deliver fails due to lack of memory resource.
**/
EFI_STATUS
MnpBuildTxPacket (
IN MNP_SERVICE_DATA *MnpServiceData,
IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData,
OUT UINT8 **PktBuf,
OUT UINT32 *PktLen
);
/**
Synchronously send out the packet.
This functon places the packet buffer to SNP driver's tansmit queue. The packet
can be considered successfully sent out once SNP acccetp the packet, while the
packet buffer recycle is deferred for better performance.
@param[in] MnpServiceData Pointer to the mnp service context data.
@param[in] Packet Pointer to the pakcet buffer.
@param[in] Length The length of the packet.
@param[in, out] Token Pointer to the token the packet generated from.
@retval EFI_SUCCESS The packet is sent out.
@retval EFI_TIMEOUT Time out occurs, the packet isn't sent.
@retval EFI_DEVICE_ERROR An unexpected network error occurs.
**/
EFI_STATUS
MnpSyncSendPacket (
IN MNP_SERVICE_DATA *MnpServiceData,
IN UINT8 *Packet,
IN UINT32 Length,
IN OUT EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
);
/**
Try to deliver the received packet to the instance.
@param[in, out] Instance Pointer to the mnp instance context data.
@retval EFI_SUCCESS The received packet is delivered, or there is no
packet to deliver, or there is no available receive
token.
@retval EFI_OUT_OF_RESOURCES The deliver fails due to lack of memory resource.
**/
EFI_STATUS
MnpInstanceDeliverPacket (
IN OUT MNP_INSTANCE_DATA *Instance
);
/**
Recycle the RxData and other resources used to hold and deliver the received
packet.
@param[in] Event The event this notify function registered to.
@param[in] Context Pointer to the context data registerd to the Event.
**/
VOID
EFIAPI
MnpRecycleRxData (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Try to receive a packet and deliver it.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@retval EFI_SUCCESS add return value to function comment
@retval EFI_NOT_STARTED The simple network protocol is not started.
@retval EFI_NOT_READY No packet received.
@retval EFI_DEVICE_ERROR An unexpected error occurs.
**/
EFI_STATUS
MnpReceivePacket (
IN OUT MNP_DEVICE_DATA *MnpDeviceData
);
/**
Allocate a free NET_BUF from MnpDeviceData->FreeNbufQue. If there is none
in the queue, first try to allocate some and add them into the queue, then
fetch the NET_BUF from the updated FreeNbufQue.
@param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
@return Pointer to the allocated free NET_BUF structure, if NULL the
operation is failed.
**/
NET_BUF *
MnpAllocNbuf (
IN OUT MNP_DEVICE_DATA *MnpDeviceData
);
/**
Try to reclaim the Nbuf into the buffer pool.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@param[in, out] Nbuf Pointer to the NET_BUF to free.
**/
VOID
MnpFreeNbuf (
IN OUT MNP_DEVICE_DATA *MnpDeviceData,
IN OUT NET_BUF *Nbuf
);
/**
Allocate a free TX buffer from MnpDeviceData->FreeTxBufList. If there is none
in the queue, first try to recycle some from SNP, then try to allocate some and add
them into the queue, then fetch the NET_BUF from the updated FreeTxBufList.
@param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
@return Pointer to the allocated free NET_BUF structure, if NULL the
operation is failed.
**/
UINT8 *
MnpAllocTxBuf (
IN OUT MNP_DEVICE_DATA *MnpDeviceData
);
/**
Try to recycle all the transmitted buffer address from SNP.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@retval EFI_SUCCESS Successed to recyclethe transmitted buffer address.
@retval Others Failed to recyclethe transmitted buffer address.
**/
EFI_STATUS
MnpRecycleTxBuf (
IN OUT MNP_DEVICE_DATA *MnpDeviceData
);
/**
Remove the received packets if timeout occurs.
@param[in] Event The event this notify function registered to.
@param[in] Context Pointer to the context data registered to the event.
**/
VOID
EFIAPI
MnpCheckPacketTimeout (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Poll to update MediaPresent field in SNP ModeData by Snp.GetStatus().
@param[in] Event The event this notify function registered to.
@param[in] Context Pointer to the context data registered to the event.
**/
VOID
EFIAPI
MnpCheckMediaStatus (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Poll to receive the packets from Snp. This function is either called by upperlayer
protocols/applications or the system poll timer notify mechanism.
@param[in] Event The event this notify function registered to.
@param[in] Context Pointer to the context data registered to the event.
**/
VOID
EFIAPI
MnpSystemPoll (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Returns the operational parameters for the current MNP child driver. May also
support returning the underlying SNP driver mode data.
The GetModeData() function is used to read the current mode data (operational
parameters) from the MNP or the underlying SNP.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[out] MnpConfigData Pointer to storage for MNP operational parameters. Type
EFI_MANAGED_NETWORK_CONFIG_DATA is defined in "Related
Definitions" below.
@param[out] SnpModeData Pointer to storage for SNP operational parameters. This
feature may be unsupported. Type EFI_SIMPLE_NETWORK_MODE
is defined in the EFI_SIMPLE_NETWORK_PROTOCOL.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER This is NULL.
@retval EFI_UNSUPPORTED The requested feature is unsupported in this
MNP implementation.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured. The default values are returned in
MnpConfigData if it is not NULL.
@retval Others The mode data could not be read.
**/
EFI_STATUS
EFIAPI
MnpGetModeData (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
);
/**
Sets or clears the operational parameters for the MNP child driver.
The Configure() function is used to set, change, or reset the operational
parameters for the MNP child driver instance. Until the operational parameters
have been set, no network traffic can be sent or received by this MNP child
driver instance. Once the operational parameters have been reset, no more
traffic can be sent or received until the operational parameters have been set
again.
Each MNP child driver instance can be started and stopped independently of
each other by setting or resetting their receive filter settings with the
Configure() function.
After any successful call to Configure(), the MNP child driver instance is
started. The internal periodic timer (if supported) is enabled. Data can be
transmitted and may be received if the receive filters have also been enabled.
Note: If multiple MNP child driver instances will receive the same packet
because of overlapping receive filter settings, then the first MNP child
driver instance will receive the original packet and additional instances will
receive copies of the original packet.
Note: Warning: Receive filter settings that overlap will consume extra
processor and/or DMA resources and degrade system and network performance.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] MnpConfigData Pointer to configuration data that will be assigned
to the MNP child driver instance. If NULL, the MNP
child driver instance is reset to startup defaults
and all pending transmit and receive requests are
flushed. Type EFI_MANAGED_NETWORK_CONFIG_DATA is
defined in EFI_MANAGED_NETWORK_PROTOCOL.GetModeData().
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is
TRUE:
* This is NULL.
* MnpConfigData.ProtocolTypeFilter is not
valid.
The operational data for the MNP child driver
instance is unchanged.
@retval EFI_OUT_OF_RESOURCES Required system resources (usually memory)
could not be allocated.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_UNSUPPORTED The requested feature is unsupported in
this [MNP] implementation. The operational data
for the MNP child driver instance is unchanged.
@retval EFI_DEVICE_ERROR An unexpected network or system error
occurred. The MNP child driver instance has
been reset to startup defaults.
@retval Others The MNP child driver instance has been reset to
startup defaults.
**/
EFI_STATUS
EFIAPI
MnpConfigure (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL
);
/**
Translates an IP multicast address to a hardware (MAC) multicast address. This
function may be unsupported in some MNP implementations.
The McastIpToMac() function translates an IP multicast address to a hardware
(MAC) multicast address. This function may be implemented by calling the
underlying EFI_SIMPLE_NETWORK. MCastIpToMac() function, which may also be
unsupported in some MNP implementations.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Ipv6Flag Set to TRUE to if IpAddress is an IPv6 multicast address.
Set to FALSE if IpAddress is an IPv4 multicast address.
@param[in] IpAddress Pointer to the multicast IP address (in network byte
order) to convert.
@param[out] MacAddress Pointer to the resulting multicast MAC address.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER One of the following conditions is TRUE:
* This is NULL.
* IpAddress is NULL.
* IpAddress is not a valid multicast IP
address.
* MacAddress is NULL.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_UNSUPPORTED The requested feature is unsupported in this
MNP implementation.
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
@retval Others The address could not be converted.
**/
EFI_STATUS
EFIAPI
MnpMcastIpToMac (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN BOOLEAN Ipv6Flag,
IN EFI_IP_ADDRESS *IpAddress,
OUT EFI_MAC_ADDRESS *MacAddress
);
/**
Enables and disables receive filters for multicast address. This function may
be unsupported in some MNP implementations.
The Groups() function only adds and removes multicast MAC addresses from the
filter list. The MNP driver does not transmit or process Internet Group
Management Protocol (IGMP) packets. If JoinFlag is FALSE and MacAddress is
NULL, then all joined groups are left.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] JoinFlag Set to TRUE to join this multicast group.
Set to FALSE to leave this multicast group.
@param[in] MacAddress Pointer to the multicast MAC group (address) to join or
leave.
@retval EFI_SUCCESS The requested operation completed successfully.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
* This is NULL.
* JoinFlag is TRUE and MacAddress is NULL.
* MacAddress is not a valid multicast MAC
address.
* The MNP multicast group settings are
unchanged.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_ALREADY_STARTED The supplied multicast group is already joined.
@retval EFI_NOT_FOUND The supplied multicast group is not joined.
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP
implementation.
@retval Others The requested operation could not be completed.
The MNP multicast group settings are unchanged.
**/
EFI_STATUS
EFIAPI
MnpGroups (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN BOOLEAN JoinFlag,
IN EFI_MAC_ADDRESS *MacAddress OPTIONAL
);
/**
Places asynchronous outgoing data packets into the transmit queue.
The Transmit() function places a completion token into the transmit packet
queue. This function is always asynchronous.
The caller must fill in the Token.Event and Token.TxData fields in the
completion token, and these fields cannot be NULL. When the transmit operation
completes, the MNP updates the Token.Status field and the Token.Event is
signaled.
Note: There may be a performance penalty if the packet needs to be
defragmented before it can be transmitted by the network device. Systems in
which performance is critical should review the requirements and features of
the underlying communications device and drivers.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Token Pointer to a token associated with the transmit data
descriptor. Type EFI_MANAGED_NETWORK_COMPLETION_TOKEN
is defined in "Related Definitions" below.
@retval EFI_SUCCESS The transmit completion token was cached.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is
TRUE:
* This is NULL.
* Token is NULL.
* Token.Event is NULL.
* Token.TxData is NULL.
* Token.TxData.DestinationAddress is not
NULL and Token.TxData.HeaderLength is zero.
* Token.TxData.FragmentCount is zero.
* (Token.TxData.HeaderLength +
Token.TxData.DataLength) is not equal to the
sum of the
Token.TxData.FragmentTable[].FragmentLength
fields.
* One or more of the
Token.TxData.FragmentTable[].FragmentLength
fields is zero.
* One or more of the
Token.TxData.FragmentTable[].FragmentBufferfields
is NULL.
* Token.TxData.DataLength is greater than MTU.
@retval EFI_ACCESS_DENIED The transmit completion token is already in the
transmit queue.
@retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
lack of system resources (usually memory).
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_NOT_READY The transmit request could not be queued because
the transmit queue is full.
**/
EFI_STATUS
EFIAPI
MnpTransmit (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
);
/**
Aborts an asynchronous transmit or receive request.
The Cancel() function is used to abort a pending transmit or receive request.
If the token is in the transmit or receive request queues, after calling this
function, Token.Status will be set to EFI_ABORTED and then Token.Event will be
signaled. If the token is not in one of the queues, which usually means that
the asynchronous operation has completed, this function will not signal the
token and EFI_NOT_FOUND is returned.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Token Pointer to a token that has been issued by
EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or
EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL, all
pending tokens are aborted.
@retval EFI_SUCCESS The asynchronous I/O request was aborted and
Token.Event was signaled. When Token is NULL,
all pending requests were aborted and their
events were signaled.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_INVALID_PARAMETER This is NULL.
@retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O
request was not found in the transmit or
receive queue. It has either completed or was
not issued by Transmit() and Receive().
**/
EFI_STATUS
EFIAPI
MnpCancel (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL
);
/**
Places an asynchronous receiving request into the receiving queue.
The Receive() function places a completion token into the receive packet
queue. This function is always asynchronous.
The caller must fill in the Token.Event field in the completion token, and
this field cannot be NULL. When the receive operation completes, the MNP
updates the Token.Status and Token.RxData fields and the Token.Event is
signaled.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Token Pointer to a token associated with the receive
data descriptor. Type
EFI_MANAGED_NETWORK_COMPLETION_TOKEN is defined in
EFI_MANAGED_NETWORK_PROTOCOL.Transmit().
@retval EFI_SUCCESS The receive completion token was cached.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is
TRUE:
* This is NULL.
* Token is NULL.
* Token.Event is NULL
@retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
lack of system resources (usually memory).
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_ACCESS_DENIED The receive completion token was already in the
receive queue.
@retval EFI_NOT_READY The receive request could not be queued because
the receive queue is full.
**/
EFI_STATUS
EFIAPI
MnpReceive (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
);
/**
Polls for incoming data packets and processes outgoing data packets.
The Poll() function can be used by network drivers and applications to
increase the rate that data packets are moved between the communications
device and the transmit and receive queues.
Normally, a periodic timer event internally calls the Poll() function. But, in
some systems, the periodic timer event may not call Poll() fast enough to
transmit and/or receive all data packets without missing packets. Drivers and
applications that are experiencing packet loss should try calling the Poll()
function more often.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@retval EFI_SUCCESS Incoming or outgoing data was processed.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The
MNP child driver instance has been reset to startup
defaults.
@retval EFI_NOT_READY No incoming or outgoing data was processed. Consider
increasing the polling rate.
@retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive
queue. Consider increasing the polling rate.
**/
EFI_STATUS
EFIAPI
MnpPoll (
IN EFI_MANAGED_NETWORK_PROTOCOL *This
);
/**
Configure the Snp receive filters according to the instances' receive filter
settings.
@param[in] MnpDeviceData Pointer to the mnp device context data.
@retval EFI_SUCCESS The receive filters is configured.
@retval EFI_OUT_OF_RESOURCES The receive filters can't be configured due
to lack of memory resource.
**/
EFI_STATUS
MnpConfigReceiveFilters (
IN MNP_DEVICE_DATA *MnpDeviceData
);
#endif

1133
NetworkPkg/MnpDxe/MnpIo.c Normal file

File diff suppressed because it is too large Load Diff

789
NetworkPkg/MnpDxe/MnpMain.c Normal file
View File

@@ -0,0 +1,789 @@
/** @file
Implementation of Managed Network Protocol public services.
Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "MnpImpl.h"
/**
Returns the operational parameters for the current MNP child driver. May also
support returning the underlying SNP driver mode data.
The GetModeData() function is used to read the current mode data (operational
parameters) from the MNP or the underlying SNP.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[out] MnpConfigData Pointer to storage for MNP operational parameters. Type
EFI_MANAGED_NETWORK_CONFIG_DATA is defined in "Related
Definitions" below.
@param[out] SnpModeData Pointer to storage for SNP operational parameters. This
feature may be unsupported. Type EFI_SIMPLE_NETWORK_MODE
is defined in the EFI_SIMPLE_NETWORK_PROTOCOL.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER This is NULL.
@retval EFI_UNSUPPORTED The requested feature is unsupported in this
MNP implementation.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured. The default values are returned in
MnpConfigData if it is not NULL.
@retval Others The mode data could not be read.
**/
EFI_STATUS
EFIAPI
MnpGetModeData (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
)
{
MNP_INSTANCE_DATA *Instance;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
EFI_TPL OldTpl;
EFI_STATUS Status;
UINT32 InterruptStatus;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (MnpConfigData != NULL) {
//
// Copy the instance configuration data.
//
CopyMem (MnpConfigData, &Instance->ConfigData, sizeof (*MnpConfigData));
}
if (SnpModeData != NULL) {
//
// Copy the underlayer Snp mode data.
//
Snp = Instance->MnpServiceData->MnpDeviceData->Snp;
//
// Upon successful return of GetStatus(), the Snp->Mode->MediaPresent
// will be updated to reflect any change of media status
//
Snp->GetStatus (Snp, &InterruptStatus, NULL);
CopyMem (SnpModeData, Snp->Mode, sizeof (*SnpModeData));
}
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
} else {
Status = EFI_SUCCESS;
}
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Sets or clears the operational parameters for the MNP child driver.
The Configure() function is used to set, change, or reset the operational
parameters for the MNP child driver instance. Until the operational parameters
have been set, no network traffic can be sent or received by this MNP child
driver instance. Once the operational parameters have been reset, no more
traffic can be sent or received until the operational parameters have been set
again.
Each MNP child driver instance can be started and stopped independently of
each other by setting or resetting their receive filter settings with the
Configure() function.
After any successful call to Configure(), the MNP child driver instance is
started. The internal periodic timer (if supported) is enabled. Data can be
transmitted and may be received if the receive filters have also been enabled.
Note: If multiple MNP child driver instances will receive the same packet
because of overlapping receive filter settings, then the first MNP child
driver instance will receive the original packet and additional instances will
receive copies of the original packet.
Note: Warning: Receive filter settings that overlap will consume extra
processor and/or DMA resources and degrade system and network performance.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] MnpConfigData Pointer to configuration data that will be assigned
to the MNP child driver instance. If NULL, the MNP
child driver instance is reset to startup defaults
and all pending transmit and receive requests are
flushed. Type EFI_MANAGED_NETWORK_CONFIG_DATA is
defined in EFI_MANAGED_NETWORK_PROTOCOL.GetModeData().
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is
TRUE:
* This is NULL.
* MnpConfigData.ProtocolTypeFilter is not
valid.
The operational data for the MNP child driver
instance is unchanged.
@retval EFI_OUT_OF_RESOURCES Required system resources (usually memory)
could not be allocated.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_UNSUPPORTED The requested feature is unsupported in
this [MNP] implementation. The operational data
for the MNP child driver instance is unchanged.
@retval EFI_DEVICE_ERROR An unexpected network or system error
occurred. The MNP child driver instance has
been reset to startup defaults.
@retval Others The MNP child driver instance has been reset to
startup defaults.
**/
EFI_STATUS
EFIAPI
MnpConfigure (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL
)
{
MNP_INSTANCE_DATA *Instance;
EFI_TPL OldTpl;
EFI_STATUS Status;
if ((This == NULL) ||
((MnpConfigData != NULL) &&
(MnpConfigData->ProtocolTypeFilter > 0) &&
(MnpConfigData->ProtocolTypeFilter <= 1500))
) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if ((MnpConfigData == NULL) && (!Instance->Configured)) {
//
// If the instance is not configured and a reset is requested, just return.
//
Status = EFI_SUCCESS;
goto ON_EXIT;
}
//
// Configure the instance.
//
Status = MnpConfigureInstance (Instance, MnpConfigData);
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Translates an IP multicast address to a hardware (MAC) multicast address. This
function may be unsupported in some MNP implementations.
The McastIpToMac() function translates an IP multicast address to a hardware
(MAC) multicast address. This function may be implemented by calling the
underlying EFI_SIMPLE_NETWORK. MCastIpToMac() function, which may also be
unsupported in some MNP implementations.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Ipv6Flag Set to TRUE to if IpAddress is an IPv6 multicast address.
Set to FALSE if IpAddress is an IPv4 multicast address.
@param[in] IpAddress Pointer to the multicast IP address (in network byte
order) to convert.
@param[out] MacAddress Pointer to the resulting multicast MAC address.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER One of the following conditions is TRUE:
* This is NULL.
* IpAddress is NULL.
* IpAddress is not a valid multicast IP
address.
* MacAddress is NULL.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_UNSUPPORTED The requested feature is unsupported in this
MNP implementation.
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
@retval Others The address could not be converted.
**/
EFI_STATUS
EFIAPI
MnpMcastIpToMac (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN BOOLEAN Ipv6Flag,
IN EFI_IP_ADDRESS *IpAddress,
OUT EFI_MAC_ADDRESS *MacAddress
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
EFI_TPL OldTpl;
EFI_IPv6_ADDRESS *Ip6Address;
if ((This == NULL) || (IpAddress == NULL) || (MacAddress == NULL)) {
return EFI_INVALID_PARAMETER;
}
Ip6Address = &IpAddress->v6;
if ((Ipv6Flag && !IP6_IS_MULTICAST (Ip6Address)) ||
(!Ipv6Flag && !IP4_IS_MULTICAST (EFI_NTOHL (*IpAddress)))
) {
//
// The IP address passed in is not a multicast address.
//
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
goto ON_EXIT;
}
Snp = Instance->MnpServiceData->MnpDeviceData->Snp;
ASSERT (Snp != NULL);
ZeroMem (MacAddress, sizeof (EFI_MAC_ADDRESS));
if (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) {
if (!Ipv6Flag) {
//
// Translate the IPv4 address into a multicast MAC address if the NIC is an
// ethernet NIC according to RFC1112..
//
MacAddress->Addr[0] = 0x01;
MacAddress->Addr[1] = 0x00;
MacAddress->Addr[2] = 0x5E;
MacAddress->Addr[3] = (UINT8) (IpAddress->v4.Addr[1] & 0x7F);
MacAddress->Addr[4] = IpAddress->v4.Addr[2];
MacAddress->Addr[5] = IpAddress->v4.Addr[3];
} else {
//
// Translate the IPv6 address into a multicast MAC address if the NIC is an
// ethernet NIC according to RFC2464.
//
MacAddress->Addr[0] = 0x33;
MacAddress->Addr[1] = 0x33;
MacAddress->Addr[2] = Ip6Address->Addr[12];
MacAddress->Addr[3] = Ip6Address->Addr[13];
MacAddress->Addr[4] = Ip6Address->Addr[14];
MacAddress->Addr[5] = Ip6Address->Addr[15];
}
Status = EFI_SUCCESS;
} else {
//
// Invoke Snp to translate the multicast IP address.
//
Status = Snp->MCastIpToMac (
Snp,
Ipv6Flag,
IpAddress,
MacAddress
);
}
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Enables and disables receive filters for multicast address. This function may
be unsupported in some MNP implementations.
The Groups() function only adds and removes multicast MAC addresses from the
filter list. The MNP driver does not transmit or process Internet Group
Management Protocol (IGMP) packets. If JoinFlag is FALSE and MacAddress is
NULL, then all joined groups are left.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] JoinFlag Set to TRUE to join this multicast group.
Set to FALSE to leave this multicast group.
@param[in] MacAddress Pointer to the multicast MAC group (address) to join or
leave.
@retval EFI_SUCCESS The requested operation completed successfully.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
* This is NULL.
* JoinFlag is TRUE and MacAddress is NULL.
* MacAddress is not a valid multicast MAC
address.
* The MNP multicast group settings are
unchanged.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_ALREADY_STARTED The supplied multicast group is already joined.
@retval EFI_NOT_FOUND The supplied multicast group is not joined.
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP
implementation.
@retval Others The requested operation could not be completed.
The MNP multicast group settings are unchanged.
**/
EFI_STATUS
EFIAPI
MnpGroups (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN BOOLEAN JoinFlag,
IN EFI_MAC_ADDRESS *MacAddress OPTIONAL
)
{
MNP_INSTANCE_DATA *Instance;
EFI_SIMPLE_NETWORK_MODE *SnpMode;
MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk;
MNP_GROUP_ADDRESS *GroupAddress;
LIST_ENTRY *ListEntry;
BOOLEAN AddressExist;
EFI_TPL OldTpl;
EFI_STATUS Status;
if (This == NULL || (JoinFlag && (MacAddress == NULL))) {
//
// This is NULL, or it's a join operation but MacAddress is NULL.
//
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
SnpMode = Instance->MnpServiceData->MnpDeviceData->Snp->Mode;
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
goto ON_EXIT;
}
if ((!Instance->ConfigData.EnableMulticastReceive) ||
((MacAddress != NULL) && !NET_MAC_IS_MULTICAST (MacAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize))) {
//
// The instance isn't configured to do mulitcast receive. OR
// the passed in MacAddress is not a mutlticast mac address.
//
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
Status = EFI_SUCCESS;
AddressExist = FALSE;
GroupCtrlBlk = NULL;
if (MacAddress != NULL) {
//
// Search the instance's GroupCtrlBlkList to find the specific address.
//
NET_LIST_FOR_EACH (ListEntry, &Instance->GroupCtrlBlkList) {
GroupCtrlBlk = NET_LIST_USER_STRUCT (
ListEntry,
MNP_GROUP_CONTROL_BLOCK,
CtrlBlkEntry
);
GroupAddress = GroupCtrlBlk->GroupAddress;
if (0 == CompareMem (
MacAddress,
&GroupAddress->Address,
SnpMode->HwAddressSize
)) {
//
// There is already the same multicast mac address configured.
//
AddressExist = TRUE;
break;
}
}
if (JoinFlag && AddressExist) {
//
// The multicast mac address to join already exists.
//
Status = EFI_ALREADY_STARTED;
}
if (!JoinFlag && !AddressExist) {
//
// The multicast mac address to leave doesn't exist in this instance.
//
Status = EFI_NOT_FOUND;
}
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
} else if (IsListEmpty (&Instance->GroupCtrlBlkList)) {
//
// The MacAddress is NULL and there is no configured multicast mac address,
// just return.
//
goto ON_EXIT;
}
//
// OK, it is time to take action.
//
Status = MnpGroupOp (Instance, JoinFlag, MacAddress, GroupCtrlBlk);
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Places asynchronous outgoing data packets into the transmit queue.
The Transmit() function places a completion token into the transmit packet
queue. This function is always asynchronous.
The caller must fill in the Token.Event and Token.TxData fields in the
completion token, and these fields cannot be NULL. When the transmit operation
completes, the MNP updates the Token.Status field and the Token.Event is
signaled.
Note: There may be a performance penalty if the packet needs to be
defragmented before it can be transmitted by the network device. Systems in
which performance is critical should review the requirements and features of
the underlying communications device and drivers.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Token Pointer to a token associated with the transmit data
descriptor. Type EFI_MANAGED_NETWORK_COMPLETION_TOKEN
is defined in "Related Definitions" below.
@retval EFI_SUCCESS The transmit completion token was cached.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is
TRUE:
* This is NULL.
* Token is NULL.
* Token.Event is NULL.
* Token.TxData is NULL.
* Token.TxData.DestinationAddress is not
NULL and Token.TxData.HeaderLength is zero.
* Token.TxData.FragmentCount is zero.
* (Token.TxData.HeaderLength +
Token.TxData.DataLength) is not equal to the
sum of the
Token.TxData.FragmentTable[].FragmentLength
fields.
* One or more of the
Token.TxData.FragmentTable[].FragmentLength
fields is zero.
* One or more of the
Token.TxData.FragmentTable[].FragmentBufferfields
is NULL.
* Token.TxData.DataLength is greater than MTU.
@retval EFI_ACCESS_DENIED The transmit completion token is already in the
transmit queue.
@retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
lack of system resources (usually memory).
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_NOT_READY The transmit request could not be queued because
the transmit queue is full.
**/
EFI_STATUS
EFIAPI
MnpTransmit (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
MNP_SERVICE_DATA *MnpServiceData;
UINT8 *PktBuf;
UINT32 PktLen;
EFI_TPL OldTpl;
if ((This == NULL) || (Token == NULL)) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
goto ON_EXIT;
}
if (!MnpIsValidTxToken (Instance, Token)) {
//
// The Token is invalid.
//
Status = EFI_INVALID_PARAMETER;
goto ON_EXIT;
}
MnpServiceData = Instance->MnpServiceData;
NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
//
// Build the tx packet
//
Status = MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// OK, send the packet synchronously.
//
Status = MnpSyncSendPacket (MnpServiceData, PktBuf, PktLen, Token);
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Places an asynchronous receiving request into the receiving queue.
The Receive() function places a completion token into the receive packet
queue. This function is always asynchronous.
The caller must fill in the Token.Event field in the completion token, and
this field cannot be NULL. When the receive operation completes, the MNP
updates the Token.Status and Token.RxData fields and the Token.Event is
signaled.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Token Pointer to a token associated with the receive
data descriptor. Type
EFI_MANAGED_NETWORK_COMPLETION_TOKEN is defined in
EFI_MANAGED_NETWORK_PROTOCOL.Transmit().
@retval EFI_SUCCESS The receive completion token was cached.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_INVALID_PARAMETER One or more of the following conditions is
TRUE:
* This is NULL.
* Token is NULL.
* Token.Event is NULL
@retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
lack of system resources (usually memory).
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
The MNP child driver instance has been reset to
startup defaults.
@retval EFI_ACCESS_DENIED The receive completion token was already in the
receive queue.
@retval EFI_NOT_READY The receive request could not be queued because
the receive queue is full.
**/
EFI_STATUS
EFIAPI
MnpReceive (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
EFI_TPL OldTpl;
if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
goto ON_EXIT;
}
//
// Check whether this token(event) is already in the rx token queue.
//
Status = NetMapIterate (&Instance->RxTokenMap, MnpTokenExist, (VOID *) Token);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// Insert the Token into the RxTokenMap.
//
Status = NetMapInsertTail (&Instance->RxTokenMap, (VOID *) Token, NULL);
if (!EFI_ERROR (Status)) {
//
// Try to deliver any buffered packets.
//
Status = MnpInstanceDeliverPacket (Instance);
//
// Dispatch the DPC queued by the NotifyFunction of Token->Event.
//
DispatchDpc ();
}
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Aborts an asynchronous transmit or receive request.
The Cancel() function is used to abort a pending transmit or receive request.
If the token is in the transmit or receive request queues, after calling this
function, Token.Status will be set to EFI_ABORTED and then Token.Event will be
signaled. If the token is not in one of the queues, which usually means that
the asynchronous operation has completed, this function will not signal the
token and EFI_NOT_FOUND is returned.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@param[in] Token Pointer to a token that has been issued by
EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or
EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL, all
pending tokens are aborted.
@retval EFI_SUCCESS The asynchronous I/O request was aborted and
Token.Event was signaled. When Token is NULL,
all pending requests were aborted and their
events were signaled.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_INVALID_PARAMETER This is NULL.
@retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O
request was not found in the transmit or
receive queue. It has either completed or was
not issued by Transmit() and Receive().
**/
EFI_STATUS
EFIAPI
MnpCancel (
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
EFI_TPL OldTpl;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
goto ON_EXIT;
}
//
// Iterate the RxTokenMap to cancel the specified Token.
//
Status = NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, (VOID *) Token);
if (Token != NULL) {
Status = (Status == EFI_ABORTED) ? EFI_SUCCESS : EFI_NOT_FOUND;
}
//
// Dispatch the DPC queued by the NotifyFunction of the cancled token's events.
//
DispatchDpc ();
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Polls for incoming data packets and processes outgoing data packets.
The Poll() function can be used by network drivers and applications to
increase the rate that data packets are moved between the communications
device and the transmit and receive queues.
Normally, a periodic timer event internally calls the Poll() function. But, in
some systems, the periodic timer event may not call Poll() fast enough to
transmit and/or receive all data packets without missing packets. Drivers and
applications that are experiencing packet loss should try calling the Poll()
function more often.
@param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
@retval EFI_SUCCESS Incoming or outgoing data was processed.
@retval EFI_NOT_STARTED This MNP child driver instance has not been
configured.
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The
MNP child driver instance has been reset to startup
defaults.
@retval EFI_NOT_READY No incoming or outgoing data was processed. Consider
increasing the polling rate.
@retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive
queue. Consider increasing the polling rate.
**/
EFI_STATUS
EFIAPI
MnpPoll (
IN EFI_MANAGED_NETWORK_PROTOCOL *This
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
EFI_TPL OldTpl;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (!Instance->Configured) {
Status = EFI_NOT_STARTED;
goto ON_EXIT;
}
//
// Try to receive packets.
//
Status = MnpReceivePacket (Instance->MnpServiceData->MnpDeviceData);
//
// Dispatch the DPC queued by the NotifyFunction of rx token's events.
//
DispatchDpc ();
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
}

732
NetworkPkg/MnpDxe/MnpVlan.c Normal file
View File

@@ -0,0 +1,732 @@
/** @file
VLAN Config Protocol implementation and VLAN packet process routine.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "MnpImpl.h"
#include "MnpVlan.h"
VLAN_DEVICE_PATH mVlanDevicePathTemplate = {
{
MESSAGING_DEVICE_PATH,
MSG_VLAN_DP,
{
(UINT8) (sizeof (VLAN_DEVICE_PATH)),
(UINT8) ((sizeof (VLAN_DEVICE_PATH)) >> 8)
}
},
0
};
EFI_VLAN_CONFIG_PROTOCOL mVlanConfigProtocolTemplate = {
VlanConfigSet,
VlanConfigFind,
VlanConfigRemove
};
/**
Create a child handle for the VLAN ID.
@param[in] ImageHandle The driver image handle.
@param[in] ControllerHandle Handle of device to bind driver to.
@param[in] VlanId The VLAN ID.
@param[out] Devicepath Pointer to returned device path for child handle.
@return The handle of VLAN child or NULL if failed to create VLAN child.
**/
EFI_HANDLE
MnpCreateVlanChild (
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ControllerHandle,
IN UINT16 VlanId,
OUT EFI_DEVICE_PATH_PROTOCOL **Devicepath OPTIONAL
)
{
EFI_HANDLE ChildHandle;
VLAN_DEVICE_PATH VlanNode;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_DEVICE_PATH_PROTOCOL *VlanDevicePath;
EFI_STATUS Status;
//
// Try to get parent device path
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
ImageHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return NULL;
}
//
// Construct device path for child handle: MAC + VLAN
//
CopyMem (&VlanNode, &mVlanDevicePathTemplate, sizeof (VLAN_DEVICE_PATH));
VlanNode.VlanId = VlanId;
VlanDevicePath = AppendDevicePathNode (
ParentDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &VlanNode
);
if (VlanDevicePath == NULL) {
return NULL;
}
//
// Create child VLAN handle by installing DevicePath protocol
//
ChildHandle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&ChildHandle,
&gEfiDevicePathProtocolGuid,
VlanDevicePath,
NULL
);
if (EFI_ERROR (Status)) {
FreePool (VlanDevicePath);
return NULL;
}
if (Devicepath != NULL) {
*Devicepath = VlanDevicePath;
}
return ChildHandle;
}
/**
Remove VLAN tag from a packet.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@param[in, out] Nbuf Pointer to the NET_BUF to remove VLAN tag.
@param[out] VlanId Pointer to the returned VLAN ID.
@retval TRUE VLAN tag is removed from this packet.
@retval FALSE There is no VLAN tag in this packet.
**/
BOOLEAN
MnpRemoveVlanTag (
IN OUT MNP_DEVICE_DATA *MnpDeviceData,
IN OUT NET_BUF *Nbuf,
OUT UINT16 *VlanId
)
{
UINT8 *Packet;
UINTN ProtocolOffset;
UINT16 ProtocolType;
VLAN_TCI VlanTag;
ProtocolOffset = MnpDeviceData->Snp->Mode->HwAddressSize * 2;
//
// Get the packet buffer.
//
Packet = NetbufGetByte (Nbuf, 0, NULL);
ASSERT (Packet != NULL);
//
// Check whether this is VLAN tagged frame by Ether Type
//
*VlanId = 0;
ProtocolType = NTOHS (*(UINT16 *) (Packet + ProtocolOffset));
if (ProtocolType != ETHER_TYPE_VLAN) {
//
// Not a VLAN tagged frame
//
return FALSE;
}
VlanTag.Uint16 = NTOHS (*(UINT16 *) (Packet + ProtocolOffset + sizeof (ProtocolType)));
*VlanId = VlanTag.Bits.Vid;
//
// Move hardware address (DA + SA) 4 bytes right to override VLAN tag
//
CopyMem (Packet + NET_VLAN_TAG_LEN, Packet, ProtocolOffset);
//
// Remove VLAN tag from the Nbuf
//
NetbufTrim (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD);
return TRUE;
}
/**
Build the vlan packet to transmit from the TxData passed in.
@param MnpServiceData Pointer to the mnp service context data.
@param TxData Pointer to the transmit data containing the
information to build the packet.
@param ProtocolType Pointer to the Ethernet protocol type.
@param Packet Pointer to record the address of the packet.
@param Length Pointer to a UINT32 variable used to record the
packet's length.
**/
VOID
MnpInsertVlanTag (
IN MNP_SERVICE_DATA *MnpServiceData,
IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData,
OUT UINT16 *ProtocolType,
IN OUT UINT8 **Packet,
IN OUT UINT32 *Length
)
{
VLAN_TCI *VlanTci;
UINT16 *Tpid;
UINT16 *EtherType;
MNP_DEVICE_DATA *MnpDeviceData;
EFI_SIMPLE_NETWORK_MODE *SnpMode;
MnpDeviceData = MnpServiceData->MnpDeviceData;
SnpMode = MnpDeviceData->Snp->Mode;
*ProtocolType = ETHER_TYPE_VLAN;
*Length = *Length + NET_VLAN_TAG_LEN;
*Packet = *Packet - NET_VLAN_TAG_LEN;
Tpid = (UINT16 *) (*Packet + SnpMode->MediaHeaderSize - sizeof (*ProtocolType));
VlanTci = (VLAN_TCI *) (UINTN) (Tpid + 1);
if (TxData->HeaderLength != 0) {
//
// Media header is in packet, move DA+SA 4 bytes left
//
CopyMem (
*Packet,
*Packet + NET_VLAN_TAG_LEN,
SnpMode->MediaHeaderSize - sizeof (*ProtocolType)
);
*Tpid = HTONS (ETHER_TYPE_VLAN);
} else {
//
// Media header not in packet, VLAN TCI and original protocol type becomes payload
//
EtherType = (UINT16 *) (UINTN) (VlanTci + 1);
*EtherType = HTONS (TxData->ProtocolType);
}
VlanTci->Bits.Vid = MnpServiceData->VlanId;
VlanTci->Bits.Cfi = VLAN_TCI_CFI_CANONICAL_MAC;
VlanTci->Bits.Priority = MnpServiceData->Priority;
VlanTci->Uint16 = HTONS (VlanTci->Uint16);
}
/**
Check VLAN configuration variable and delete the duplicative content if has identical Vlan ID.
@param[in] MnpDeviceData Pointer to the MNP device context data.
@param[in] Buffer Pointer to the buffer contains the array of VLAN_TCI.
@param[in] NumberOfVlan Pointer to number of VLAN.
@param[out] NewNumberOfVlan Pointer to number of unique VLAN.
@retval EFI_SUCCESS The VLAN variable is successfully checked.
@retval EFI_OUT_OF_RESOURCES There is not enough resource to set the configuration.
**/
EFI_STATUS
MnpCheckVlanVariable (
IN MNP_DEVICE_DATA *MnpDeviceData,
IN VLAN_TCI *Buffer,
IN UINTN NumberOfVlan,
OUT UINTN *NewNumberOfVlan
)
{
UINTN Index;
UINTN Index2;
UINTN Count;
BOOLEAN FoundDuplicateItem;
EFI_STATUS Status;
Count = 0;
FoundDuplicateItem = FALSE;
Status = EFI_SUCCESS;
for (Index = 0; Index < NumberOfVlan; Index++) {
for (Index2 = Index + 1; Index2 < NumberOfVlan; Index2++) {
if (Buffer[Index].Bits.Vid == Buffer[Index2].Bits.Vid) {
FoundDuplicateItem = TRUE;
Count++;
break;
}
}
if (FoundDuplicateItem) {
for (Index2 = Index +1; Index2 < NumberOfVlan; Index++, Index2++) {
CopyMem (Buffer + Index, Buffer + Index2, sizeof (VLAN_TCI));
}
}
FoundDuplicateItem = FALSE;
}
*NewNumberOfVlan = NumberOfVlan - Count;
if (Count != 0) {
Status = MnpSetVlanVariable (MnpDeviceData, *NewNumberOfVlan, Buffer);
}
return Status;
}
/**
Get VLAN configuration variable.
@param[in] MnpDeviceData Pointer to the MNP device context data.
@param[out] NumberOfVlan Pointer to number of VLAN to be returned.
@param[out] VlanVariable Pointer to the buffer to return requested
array of VLAN_TCI.
@retval EFI_SUCCESS The array of VLAN_TCI was returned in VlanVariable
and number of VLAN was returned in NumberOfVlan.
@retval EFI_NOT_FOUND VLAN configuration variable not found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the configuration.
**/
EFI_STATUS
MnpGetVlanVariable (
IN MNP_DEVICE_DATA *MnpDeviceData,
OUT UINTN *NumberOfVlan,
OUT VLAN_TCI **VlanVariable
)
{
UINTN BufferSize;
EFI_STATUS Status;
VLAN_TCI *Buffer;
UINTN NewNumberOfVlan;
//
// Get VLAN configuration from EFI Variable
//
Buffer = NULL;
BufferSize = 0;
Status = gRT->GetVariable (
MnpDeviceData->MacString,
&gEfiVlanConfigProtocolGuid,
NULL,
&BufferSize,
NULL
);
if (Status != EFI_BUFFER_TOO_SMALL) {
return EFI_NOT_FOUND;
}
//
// Allocate buffer to read the variable
//
Buffer = AllocateZeroPool (BufferSize);
if (Buffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = gRT->GetVariable (
MnpDeviceData->MacString,
&gEfiVlanConfigProtocolGuid,
NULL,
&BufferSize,
Buffer
);
if (EFI_ERROR (Status)) {
FreePool (Buffer);
return Status;
}
Status = MnpCheckVlanVariable (MnpDeviceData, Buffer, BufferSize / sizeof (VLAN_TCI), &NewNumberOfVlan);
if (!EFI_ERROR (Status)) {
*NumberOfVlan = NewNumberOfVlan;
*VlanVariable = Buffer;
}
return Status;
}
/**
Set VLAN configuration variable.
@param[in] MnpDeviceData Pointer to the MNP device context data.
@param[in] NumberOfVlan Number of VLAN in array VlanVariable.
@param[in] VlanVariable Pointer to array of VLAN_TCI.
@retval EFI_SUCCESS The VLAN variable is successfully set.
@retval EFI_OUT_OF_RESOURCES There is not enough resource to set the configuration.
**/
EFI_STATUS
MnpSetVlanVariable (
IN MNP_DEVICE_DATA *MnpDeviceData,
IN UINTN NumberOfVlan,
IN VLAN_TCI *VlanVariable
)
{
return gRT->SetVariable (
MnpDeviceData->MacString,
&gEfiVlanConfigProtocolGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
NumberOfVlan * sizeof (VLAN_TCI),
VlanVariable
);
}
/**
Create a VLAN device or modify the configuration parameter of an
already-configured VLAN.
The Set() function is used to create a new VLAN device or change the VLAN
configuration parameters. If the VlanId hasn't been configured in the
physical Ethernet device, a new VLAN device will be created. If a VLAN with
this VlanId is already configured, then related configuration will be updated
as the input parameters.
If VlanId is zero, the VLAN device will send and receive untagged frames.
Otherwise, the VLAN device will send and receive VLAN-tagged frames containing the VlanId.
If VlanId is out of scope of (0-4094), EFI_INVALID_PARAMETER is returned.
If Priority is out of the scope of (0-7), then EFI_INVALID_PARAMETER is returned.
If there is not enough system memory to perform the registration, then
EFI_OUT_OF_RESOURCES is returned.
@param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL.
@param[in] VlanId A unique identifier (1-4094) of the VLAN which is being created
or modified, or zero (0).
@param[in] Priority 3 bit priority in VLAN header. Priority 0 is default value. If
VlanId is zero (0), Priority is ignored.
@retval EFI_SUCCESS The VLAN is successfully configured.
@retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE:
- This is NULL.
- VlanId is an invalid VLAN Identifier.
- Priority is invalid.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to perform the registration.
**/
EFI_STATUS
EFIAPI
VlanConfigSet (
IN EFI_VLAN_CONFIG_PROTOCOL *This,
IN UINT16 VlanId,
IN UINT8 Priority
)
{
EFI_STATUS Status;
MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
VLAN_TCI *OldVariable;
VLAN_TCI *NewVariable;
UINTN NumberOfVlan;
UINTN Index;
BOOLEAN IsAdd;
LIST_ENTRY *Entry;
if ((This == NULL) || (VlanId > 4094) || (Priority > 7)) {
return EFI_INVALID_PARAMETER;
}
IsAdd = FALSE;
MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (This);
if (MnpDeviceData->NumberOfVlan == 0) {
//
// No existing VLAN, this is the first VLAN to add
//
IsAdd = TRUE;
Entry = GetFirstNode (&MnpDeviceData->ServiceList);
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
if (VlanId != 0) {
//
// VlanId is not 0, need destroy the default MNP service data
//
Status = MnpDestroyServiceChild (MnpServiceData);
if (EFI_ERROR (Status)) {
return Status;
}
Status = MnpDestroyServiceData (MnpServiceData);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Create a new MNP service data for this VLAN
//
MnpServiceData = MnpCreateServiceData (MnpDeviceData, VlanId, Priority);
if (MnpServiceData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
}
} else {
//
// Try to find VlanId in existing VLAN list
//
MnpServiceData = MnpFindServiceData (MnpDeviceData, VlanId);
if (MnpServiceData == NULL) {
//
// VlanId not found, create a new MNP service data
//
IsAdd = TRUE;
MnpServiceData = MnpCreateServiceData (MnpDeviceData, VlanId, Priority);
if (MnpServiceData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
}
}
MnpServiceData->VlanId = VlanId;
MnpServiceData->Priority = Priority;
if (IsAdd) {
MnpDeviceData->NumberOfVlan++;
}
//
// Update VLAN configuration variable
//
OldVariable = NULL;
NewVariable = NULL;
NumberOfVlan = 0;
MnpGetVlanVariable (MnpDeviceData, &NumberOfVlan, &OldVariable);
if (IsAdd) {
//
// VLAN not exist - add
//
NewVariable = AllocateZeroPool ((NumberOfVlan + 1) * sizeof (VLAN_TCI));
if (NewVariable == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
if (OldVariable != NULL) {
CopyMem (NewVariable, OldVariable, NumberOfVlan * sizeof (VLAN_TCI));
}
Index = NumberOfVlan++;
} else {
//
// VLAN already exist - update
//
for (Index = 0; Index < NumberOfVlan; Index++) {
if (OldVariable[Index].Bits.Vid == VlanId) {
break;
}
}
ASSERT (Index < NumberOfVlan);
NewVariable = OldVariable;
OldVariable = NULL;
}
NewVariable[Index].Bits.Vid = VlanId;
NewVariable[Index].Bits.Priority = Priority;
Status = MnpSetVlanVariable (MnpDeviceData, NumberOfVlan, NewVariable);
FreePool (NewVariable);
Exit:
if (OldVariable != NULL) {
FreePool (OldVariable);
}
return Status;
}
/**
Find configuration information for specified VLAN or all configured VLANs.
The Find() function is used to find the configuration information for matching
VLAN and allocate a buffer into which those entries are copied.
@param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL.
@param[in] VlanId Pointer to VLAN identifier. Set to NULL to find all
configured VLANs.
@param[out] NumberOfVlan The number of VLANs which is found by the specified criteria.
@param[out] Entries The buffer which receive the VLAN configuration.
@retval EFI_SUCCESS The VLAN is successfully found.
@retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE:
- This is NULL.
- Specified VlanId is invalid.
@retval EFI_NOT_FOUND No matching VLAN is found.
**/
EFI_STATUS
EFIAPI
VlanConfigFind (
IN EFI_VLAN_CONFIG_PROTOCOL *This,
IN UINT16 *VlanId OPTIONAL,
OUT UINT16 *NumberOfVlan,
OUT EFI_VLAN_FIND_DATA **Entries
)
{
MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
LIST_ENTRY *Entry;
EFI_VLAN_FIND_DATA *VlanData;
if ((This == NULL) || (VlanId != NULL && *VlanId > 4094) || (NumberOfVlan == NULL) || (Entries == NULL)) {
return EFI_INVALID_PARAMETER;
}
*NumberOfVlan = 0;
*Entries = NULL;
MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (This);
if (MnpDeviceData->NumberOfVlan == 0) {
return EFI_NOT_FOUND;
}
if (VlanId == NULL) {
//
// Return all current VLAN configuration
//
*NumberOfVlan = (UINT16) MnpDeviceData->NumberOfVlan;
VlanData = AllocateZeroPool (*NumberOfVlan * sizeof (EFI_VLAN_FIND_DATA));
if (VlanData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
*Entries = VlanData;
NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
VlanData->VlanId = MnpServiceData->VlanId;
VlanData->Priority = MnpServiceData->Priority;
VlanData++;
}
return EFI_SUCCESS;
}
//
// VlanId is specified, try to find it in current VLAN list
//
MnpServiceData = MnpFindServiceData (MnpDeviceData, *VlanId);
if (MnpServiceData == NULL) {
return EFI_NOT_FOUND;
}
VlanData = AllocateZeroPool (sizeof (EFI_VLAN_FIND_DATA));
if (VlanData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
VlanData->VlanId = MnpServiceData->VlanId;
VlanData->Priority = MnpServiceData->Priority;
*NumberOfVlan = 1;
*Entries = VlanData;
return EFI_SUCCESS;
}
/**
Remove the configured VLAN device.
The Remove() function is used to remove the specified VLAN device.
If the VlanId is out of the scope of (0-4094), EFI_INVALID_PARAMETER is returned.
If specified VLAN hasn't been previously configured, EFI_NOT_FOUND is returned.
@param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL.
@param[in] VlanId Identifier (0-4094) of the VLAN to be removed.
@retval EFI_SUCCESS The VLAN is successfully removed.
@retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE:
- This is NULL.
- VlanId is an invalid parameter.
@retval EFI_NOT_FOUND The to-be-removed VLAN does not exist.
**/
EFI_STATUS
EFIAPI
VlanConfigRemove (
IN EFI_VLAN_CONFIG_PROTOCOL *This,
IN UINT16 VlanId
)
{
EFI_STATUS Status;
MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
LIST_ENTRY *Entry;
VLAN_TCI *VlanVariable;
VLAN_TCI *VlanData;
if ((This == NULL) || (VlanId > 4094)) {
return EFI_INVALID_PARAMETER;
}
MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (This);
if (MnpDeviceData->NumberOfVlan == 0) {
return EFI_NOT_FOUND;
}
//
// Try to find the VlanId
//
MnpServiceData = MnpFindServiceData (MnpDeviceData, VlanId);
if (MnpServiceData == NULL) {
return EFI_NOT_FOUND;
}
MnpDeviceData->NumberOfVlan--;
if ((VlanId != 0) || (MnpDeviceData->NumberOfVlan != 0)) {
//
// If VlanId is not 0 or VlanId is 0 and it is not the last VLAN to remove,
// destroy its MNP service data
//
Status = MnpDestroyServiceChild (MnpServiceData);
if (EFI_ERROR (Status)) {
return Status;
}
Status = MnpDestroyServiceData (MnpServiceData);
if (EFI_ERROR (Status)) {
return Status;
}
}
if ((VlanId != 0) && (MnpDeviceData->NumberOfVlan == 0)) {
//
// This is the last VLAN to be removed, restore the default MNP service data
//
MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);
if (MnpServiceData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
}
//
// Update VLAN configuration variable
//
VlanVariable = NULL;
if (MnpDeviceData->NumberOfVlan != 0) {
VlanVariable = AllocatePool (MnpDeviceData->NumberOfVlan * sizeof (VLAN_TCI));
if (VlanVariable == NULL) {
return EFI_OUT_OF_RESOURCES;
}
VlanData = VlanVariable;
NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
VlanData->Bits.Vid = MnpServiceData->VlanId;
VlanData->Bits.Priority = MnpServiceData->Priority;
VlanData++;
}
}
Status = MnpSetVlanVariable (MnpDeviceData, MnpDeviceData->NumberOfVlan, VlanVariable);
if (VlanVariable != NULL) {
FreePool (VlanVariable);
}
return Status;
}

205
NetworkPkg/MnpDxe/MnpVlan.h Normal file
View File

@@ -0,0 +1,205 @@
/** @file
Header file to be included by MnpVlan.c.
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __MNP_VLAN_H__
#define __MNP_VLAN_H__
#include "MnpDriver.h"
extern EFI_VLAN_CONFIG_PROTOCOL mVlanConfigProtocolTemplate;
/**
Create a child handle for the VLAN ID.
@param[in] ImageHandle The driver image handle.
@param[in] ControllerHandle Handle of device to bind driver to.
@param[in] VlanId The VLAN ID.
@param[out] Devicepath Pointer to returned device path for child handle.
@return The handle of VLAN child or NULL if failed to create VLAN child.
**/
EFI_HANDLE
MnpCreateVlanChild (
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ControllerHandle,
IN UINT16 VlanId,
OUT EFI_DEVICE_PATH_PROTOCOL **Devicepath OPTIONAL
);
/**
Remove VLAN tag of a packet.
@param[in, out] MnpDeviceData Pointer to the mnp device context data.
@param[in, out] Nbuf Pointer to the NET_BUF to remove VLAN tag.
@param[out] VlanId Pointer to the returned VLAN ID.
@retval TRUE VLAN tag is removed from this packet.
@retval FALSE There is no VLAN tag in this packet.
**/
BOOLEAN
MnpRemoveVlanTag (
IN OUT MNP_DEVICE_DATA *MnpDeviceData,
IN OUT NET_BUF *Nbuf,
OUT UINT16 *VlanId
);
/**
Build the vlan packet to transmit from the TxData passed in.
@param MnpServiceData Pointer to the mnp service context data.
@param TxData Pointer to the transmit data containing the
information to build the packet.
@param ProtocolType Pointer to the Ethernet protocol type.
@param Packet Pointer to record the address of the packet.
@param Length Pointer to a UINT32 variable used to record the
packet's length.
**/
VOID
MnpInsertVlanTag (
IN MNP_SERVICE_DATA *MnpServiceData,
IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData,
OUT UINT16 *ProtocolType,
IN OUT UINT8 **Packet,
IN OUT UINT32 *Length
);
/**
Get VLAN configuration variable.
@param[in] MnpDeviceData Pointer to the MNP device context data.
@param[out] NumberOfVlan Pointer to number of VLAN to be returned.
@param[out] VlanVariable Pointer to the buffer to return requested
array of VLAN_TCI.
@retval EFI_SUCCESS The array of VLAN_TCI was returned in VlanVariable
and number of VLAN was returned in NumberOfVlan.
@retval EFI_NOT_FOUND VLAN configuration variable not found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the configuration.
**/
EFI_STATUS
MnpGetVlanVariable (
IN MNP_DEVICE_DATA *MnpDeviceData,
OUT UINTN *NumberOfVlan,
OUT VLAN_TCI **VlanVariable
);
/**
Set VLAN configuration variable.
@param[in] MnpDeviceData Pointer to the MNP device context data.
@param[in] NumberOfVlan Number of VLAN in array VlanVariable.
@param[in] VlanVariable Pointer to array of VLAN_TCI.
@retval EFI_SUCCESS The VLAN variable is successfully set.
@retval EFI_OUT_OF_RESOURCES There is not enough resource to set the configuration.
**/
EFI_STATUS
MnpSetVlanVariable (
IN MNP_DEVICE_DATA *MnpDeviceData,
IN UINTN NumberOfVlan,
IN VLAN_TCI *VlanVariable
);
/**
Create a VLAN device or modify the configuration parameter of an
already-configured VLAN.
The Set() function is used to create a new VLAN device or change the VLAN
configuration parameters. If the VlanId hasn't been configured in the
physical Ethernet device, a new VLAN device will be created. If a VLAN with
this VlanId is already configured, then related configuration will be updated
as the input parameters.
If VlanId is zero, the VLAN device will send and receive untagged frames.
Otherwise, the VLAN device will send and receive VLAN-tagged frames containing the VlanId.
If VlanId is out of scope of (0-4094), EFI_INVALID_PARAMETER is returned.
If Priority is out of the scope of (0-7), then EFI_INVALID_PARAMETER is returned.
If there is not enough system memory to perform the registration, then
EFI_OUT_OF_RESOURCES is returned.
@param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL.
@param[in] VlanId A unique identifier (1-4094) of the VLAN which is being created
or modified, or zero (0).
@param[in] Priority 3 bit priority in VLAN header. Priority 0 is default value. If
VlanId is zero (0), Priority is ignored.
@retval EFI_SUCCESS The VLAN is successfully configured.
@retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE:
- This is NULL.
- VlanId is an invalid VLAN Identifier.
- Priority is invalid.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to perform the registration.
**/
EFI_STATUS
EFIAPI
VlanConfigSet (
IN EFI_VLAN_CONFIG_PROTOCOL *This,
IN UINT16 VlanId,
IN UINT8 Priority
);
/**
Find configuration information for specified VLAN or all configured VLANs.
The Find() function is used to find the configuration information for matching
VLAN and allocate a buffer into which those entries are copied.
@param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL.
@param[in] VlanId Pointer to VLAN identifier. Set to NULL to find all
configured VLANs.
@param[out] NumberOfVlan The number of VLANs which is found by the specified criteria.
@param[out] Entries The buffer which receive the VLAN configuration.
@retval EFI_SUCCESS The VLAN is successfully found.
@retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE:
- This is NULL.
- Specified VlanId is invalid.
@retval EFI_NOT_FOUND No matching VLAN is found.
**/
EFI_STATUS
EFIAPI
VlanConfigFind (
IN EFI_VLAN_CONFIG_PROTOCOL *This,
IN UINT16 *VlanId OPTIONAL,
OUT UINT16 *NumberOfVlan,
OUT EFI_VLAN_FIND_DATA **Entries
);
/**
Remove the configured VLAN device.
The Remove() function is used to remove the specified VLAN device.
If the VlanId is out of the scope of (0-4094), EFI_INVALID_PARAMETER is returned.
If specified VLAN hasn't been previously configured, EFI_NOT_FOUND is returned.
@param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL.
@param[in] VlanId Identifier (0-4094) of the VLAN to be removed.
@retval EFI_SUCCESS The VLAN is successfully removed.
@retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE:
- This is NULL.
- VlanId is an invalid parameter.
@retval EFI_NOT_FOUND The to-be-removed VLAN does not exist.
**/
EFI_STATUS
EFIAPI
VlanConfigRemove (
IN EFI_VLAN_CONFIG_PROTOCOL *This,
IN UINT16 VlanId
);
#endif