mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/Bus/Usb/UsbNetwork/UsbCdcEcm: Add USB Cdc ECM devices support
This driver provides UEFI driver for USB CDC ECM device Signed-off-by: Richard Ho <richardho@ami.com> Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Michael Kubacki <mikuback@linux.microsoft.com> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Ray Ni <ray.ni@intel.com> Tested-by: Tinh Nguyen <tinhnguyen@os.amperecomputing.com> Acked-by: Hao A Wu <hao.a.wu@intel.com> Reviewed-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Tony Lo <tonylo@ami.com>
This commit is contained in:
parent
fc0d5922f1
commit
5e400d22a0
|
@ -0,0 +1,170 @@
|
|||
/** @file
|
||||
This file contains code for USB Ecm Driver Component Name definitions
|
||||
|
||||
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
#include "UsbCdcEcm.h"
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE gUsbEcmDriverNameTable[] = {
|
||||
{
|
||||
"eng;en",
|
||||
L"USB ECM Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUsbEcmComponentName = {
|
||||
UsbEcmComponentNameGetDriverName,
|
||||
UsbEcmComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUsbEcmComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME)UsbEcmComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)UsbEcmComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
/**
|
||||
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
|
||||
UsbEcmComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
gUsbEcmDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gUsbEcmComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param[in] Controller 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 in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
|
||||
@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
|
||||
UsbEcmComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
|
@ -0,0 +1,502 @@
|
|||
/** @file
|
||||
This file contains code for USB Ethernet Control Model
|
||||
Driver
|
||||
|
||||
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
#include "UsbCdcEcm.h"
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gUsbEcmDriverBinding = {
|
||||
UsbEcmDriverSupported,
|
||||
UsbEcmDriverStart,
|
||||
UsbEcmDriverStop,
|
||||
USB_ECM_DRIVER_VERSION,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
Check if this interface is USB ECM SubType
|
||||
|
||||
@param[in] UsbIo A pointer to the EFI_USB_IO_PROTOCOL instance.
|
||||
|
||||
@retval TRUE USB ECM SubType.
|
||||
@retval FALSE Not USB ECM SubType.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSupportedDevice (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &InterfaceDescriptor);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((InterfaceDescriptor.InterfaceClass == USB_CDC_CLASS) &&
|
||||
(InterfaceDescriptor.InterfaceSubClass == USB_CDC_ECM_SUBCLASS) &&
|
||||
(InterfaceDescriptor.InterfaceProtocol == USB_NO_CLASS_PROTOCOL))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
USB ECM Driver Binding Support.
|
||||
|
||||
@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 other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmDriverSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
(VOID **)&UsbIo,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = IsSupportedDevice (UsbIo) ? EFI_SUCCESS : EFI_UNSUPPORTED;
|
||||
|
||||
gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the USB ECM and USB CDC Data interfaces are from the same device.
|
||||
|
||||
@param[in] UsbEthPath A pointer to the EFI_DEVICE_PATH_PROTOCOL instance.
|
||||
@param[in] UsbCdcDataPath A pointer to the EFI_DEVICE_PATH_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS Is the same device.
|
||||
@retval EFI_NOT_FOUND Is not the same device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IsSameDevice (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *UsbEthPath,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *UsbCdcDataPath
|
||||
)
|
||||
{
|
||||
while (1) {
|
||||
if ((UsbEthPath->Type == ACPI_DEVICE_PATH) && (UsbEthPath->SubType == ACPI_DP)) {
|
||||
if (CompareMem ((ACPI_HID_DEVICE_PATH *)UsbCdcDataPath, (ACPI_HID_DEVICE_PATH *)UsbEthPath, sizeof (ACPI_HID_DEVICE_PATH))) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if ((UsbEthPath->Type == HARDWARE_DEVICE_PATH) && (UsbEthPath->SubType == HW_PCI_DP)) {
|
||||
if (CompareMem ((PCI_DEVICE_PATH *)UsbCdcDataPath, (PCI_DEVICE_PATH *)UsbEthPath, sizeof (PCI_DEVICE_PATH))) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if ((UsbEthPath->Type == MESSAGING_DEVICE_PATH) && (UsbEthPath->SubType == MSG_USB_DP)) {
|
||||
if (IsDevicePathEnd (NextDevicePathNode (UsbEthPath))) {
|
||||
if (((USB_DEVICE_PATH *)UsbEthPath)->ParentPortNumber ==
|
||||
((USB_DEVICE_PATH *)UsbCdcDataPath)->ParentPortNumber)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
if (CompareMem ((USB_DEVICE_PATH *)UsbCdcDataPath, (USB_DEVICE_PATH *)UsbEthPath, sizeof (USB_DEVICE_PATH))) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UsbEthPath = NextDevicePathNode (UsbEthPath);
|
||||
UsbCdcDataPath = NextDevicePathNode (UsbCdcDataPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the USB CDC Data(UsbIo) installed and return USB CDC Data Handle.
|
||||
|
||||
@param[in] UsbEthPath A pointer to the EFI_DEVICE_PATH_PROTOCOL instance.
|
||||
@param[in, out] UsbCdcDataHandle A pointer to the EFI_HANDLE for USB CDC Data.
|
||||
|
||||
@retval TRUE USB CDC Data(UsbIo) installed.
|
||||
@retval FALSE USB CDC Data(UsbIo) did not installed.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsUsbCdcData (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *UsbEthPath,
|
||||
IN OUT EFI_HANDLE *UsbCdcDataHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
EFI_USB_INTERFACE_DESCRIPTOR Interface;
|
||||
EFI_DEVICE_PATH_PROTOCOL *UsbCdcDataPath;
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
(VOID **)&UsbIo
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if ((Interface.InterfaceClass == USB_CDC_DATA_CLASS) &&
|
||||
(Interface.InterfaceSubClass == USB_CDC_DATA_SUBCLASS) &&
|
||||
(Interface.InterfaceProtocol == USB_NO_CLASS_PROTOCOL))
|
||||
{
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
(VOID **)&UsbCdcDataPath
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = IsSameDevice (UsbEthPath, UsbCdcDataPath);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
CopyMem (UsbCdcDataHandle, &HandleBuffer[Index], sizeof (EFI_HANDLE));
|
||||
FreePool (HandleBuffer);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Call Back Function.
|
||||
|
||||
@param[in] Event Event whose notification function is being invoked.
|
||||
@param[in] Context The pointer to the notification function's context,
|
||||
which is implementation-dependent.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
CallbackFunction (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
EFI_USB_INTERFACE_DESCRIPTOR Interface;
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
(VOID **)&UsbIo
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if ((Interface.InterfaceClass == USB_CDC_CLASS) &&
|
||||
(Interface.InterfaceSubClass == USB_CDC_ECM_SUBCLASS) &&
|
||||
(Interface.InterfaceProtocol == USB_NO_CLASS_PROTOCOL))
|
||||
{
|
||||
gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
gBS->CloseEvent (Event);
|
||||
}
|
||||
|
||||
/**
|
||||
USB ECM Driver Binding Start.
|
||||
|
||||
@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_DEVICE_ERROR This driver could not be started due to a device error
|
||||
@retval EFI_OUT_OF_RESOURCES The driver could not install successfully due to a lack of resources.
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmDriverStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Reg;
|
||||
EFI_EVENT Event;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
EFI_DEVICE_PATH_PROTOCOL *UsbEthPath;
|
||||
EFI_HANDLE UsbCdcDataHandle;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
EFI_USB_INTERFACE_DESCRIPTOR Interface;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
(VOID **)&UsbIo,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
(VOID **)&UsbEthPath,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = IsUsbCdcData (UsbEthPath, &UsbCdcDataHandle) ? EFI_SUCCESS : EFI_UNSUPPORTED;
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
|
||||
Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, CallbackFunction, NULL, &Event);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->RegisterProtocolNotify (&gEfiUsbIoProtocolGuid, Event, &Reg);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UsbEthDriver = AllocateZeroPool (sizeof (USB_ETHERNET_DRIVER));
|
||||
if (!UsbEthDriver) {
|
||||
gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = LoadAllDescriptor (UsbIo, &UsbEthDriver->Config);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
GetEndpoint (UsbIo, UsbEthDriver);
|
||||
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
UsbEthDriver->Signature = USB_ETHERNET_SIGNATURE;
|
||||
UsbEthDriver->NumOfInterface = Interface.InterfaceNumber;
|
||||
UsbEthDriver->UsbCdcDataHandle = UsbCdcDataHandle;
|
||||
UsbEthDriver->UsbIo = UsbIo;
|
||||
UsbEthDriver->UsbEth.UsbEthReceive = UsbEthEcmReceive;
|
||||
UsbEthDriver->UsbEth.UsbEthTransmit = UsbEthEcmTransmit;
|
||||
UsbEthDriver->UsbEth.UsbEthInterrupt = UsbEthEcmInterrupt;
|
||||
UsbEthDriver->UsbEth.UsbEthMacAddress = GetUsbEthMacAddress;
|
||||
UsbEthDriver->UsbEth.UsbEthMaxBulkSize = UsbEthEcmBulkSize;
|
||||
UsbEthDriver->UsbEth.UsbHeaderFunDescriptor = GetUsbHeaderFunDescriptor;
|
||||
UsbEthDriver->UsbEth.UsbUnionFunDescriptor = GetUsbUnionFunDescriptor;
|
||||
UsbEthDriver->UsbEth.UsbEthFunDescriptor = GetUsbEthFunDescriptor;
|
||||
UsbEthDriver->UsbEth.SetUsbEthMcastFilter = SetUsbEthMcastFilter;
|
||||
UsbEthDriver->UsbEth.SetUsbEthPowerPatternFilter = SetUsbEthPowerFilter;
|
||||
UsbEthDriver->UsbEth.GetUsbEthPowerPatternFilter = GetUsbEthPowerFilter;
|
||||
UsbEthDriver->UsbEth.SetUsbEthPacketFilter = SetUsbEthPacketFilter;
|
||||
UsbEthDriver->UsbEth.GetUsbEthStatistic = GetUsbEthStatistic;
|
||||
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&ControllerHandle,
|
||||
&gEdkIIUsbEthProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&(UsbEthDriver->UsbEth)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
FreePool (UsbEthDriver);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
USB ECM Driver Binding Stop.
|
||||
|
||||
@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 other This driver was not removed from this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmDriverStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EDKII_USB_ETHERNET_PROTOCOL *UsbEthProtocol;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEdkIIUsbEthProtocolGuid,
|
||||
(VOID **)&UsbEthProtocol,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (UsbEthProtocol);
|
||||
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
ControllerHandle,
|
||||
&gEdkIIUsbEthProtocolGuid,
|
||||
UsbEthProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
FreePool (UsbEthDriver->Config);
|
||||
FreePool (UsbEthDriver);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Entrypoint of ECM Driver.
|
||||
|
||||
This function is the entrypoint of ECM Driver. It installs Driver Binding
|
||||
Protocols together with Component Name Protocols.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The entry point is executed successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmEntry (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
gUsbEcmDriverBinding.DriverBindingHandle = ImageHandle;
|
||||
gUsbEcmDriverBinding.ImageHandle = ImageHandle;
|
||||
|
||||
return gBS->InstallMultipleProtocolInterfaces (
|
||||
&gUsbEcmDriverBinding.DriverBindingHandle,
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
&gUsbEcmDriverBinding,
|
||||
&gEfiComponentName2ProtocolGuid,
|
||||
&gUsbEcmComponentName2,
|
||||
NULL
|
||||
);
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
/** @file
|
||||
Header file contains code for USB Ethernet Control Model
|
||||
driver definitions
|
||||
|
||||
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#ifndef USB_CDC_ECM_H_
|
||||
#define USB_CDC_ECM_H_
|
||||
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiUsbLib.h>
|
||||
#include <Protocol/UsbIo.h>
|
||||
#include <Protocol/UsbEthernetProtocol.h>
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EDKII_USB_ETHERNET_PROTOCOL UsbEth;
|
||||
EFI_HANDLE UsbCdcDataHandle;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
EFI_USB_CONFIG_DESCRIPTOR *Config;
|
||||
UINT8 NumOfInterface;
|
||||
UINT8 BulkInEndpoint;
|
||||
UINT8 BulkOutEndpoint;
|
||||
UINT8 InterruptEndpoint;
|
||||
EFI_MAC_ADDRESS MacAddress;
|
||||
} USB_ETHERNET_DRIVER;
|
||||
|
||||
#define USB_ECM_DRIVER_VERSION 1
|
||||
#define USB_ETHERNET_BULK_TIMEOUT 1
|
||||
#define USB_ETHERNET_TRANSFER_TIMEOUT 200
|
||||
|
||||
#define USB_ETHERNET_SIGNATURE SIGNATURE_32('u', 'e', 't', 'h')
|
||||
#define USB_ETHERNET_DEV_FROM_THIS(a) CR (a, USB_ETHERNET_DRIVER, UsbEth, USB_ETHERNET_SIGNATURE)
|
||||
|
||||
typedef struct {
|
||||
UINT16 Src;
|
||||
UINT16 Dst;
|
||||
} BIT_MAP;
|
||||
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gUsbEcmComponentName2;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmDriverSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmDriverStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEcmDriverStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
LoadAllDescriptor (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
OUT EFI_USB_CONFIG_DESCRIPTOR **ConfigDesc
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NextDescriptor (
|
||||
IN EFI_USB_CONFIG_DESCRIPTOR *Desc,
|
||||
IN OUT UINTN *Offset
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
GetFunctionalDescriptor (
|
||||
IN EFI_USB_CONFIG_DESCRIPTOR *Config,
|
||||
IN UINT8 FunDescriptorType,
|
||||
OUT VOID *DataBuffer
|
||||
);
|
||||
|
||||
VOID
|
||||
GetEndpoint (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN OUT USB_ETHERNET_DRIVER *UsbEthDriver
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmReceive (
|
||||
IN PXE_CDB *Cdb,
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN OUT VOID *Packet,
|
||||
IN OUT UINTN *PacketLength
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmTransmit (
|
||||
IN PXE_CDB *Cdb,
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN VOID *Packet,
|
||||
IN OUT UINTN *PacketLength
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmInterrupt (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN BOOLEAN IsNewTransfer,
|
||||
IN UINTN PollingInterval,
|
||||
IN EFI_USB_DEVICE_REQUEST *Request
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InterruptCallback (
|
||||
IN VOID *Data,
|
||||
IN UINTN DataLength,
|
||||
IN VOID *Context,
|
||||
IN UINT32 Status
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthMacAddress (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT EFI_MAC_ADDRESS *MacAddress
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmBulkSize (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT UINTN *BulkSize
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbHeaderFunDescriptor (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT USB_HEADER_FUN_DESCRIPTOR *UsbHeaderFunDescriptor
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbUnionFunDescriptor (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT USB_UNION_FUN_DESCRIPTOR *UsbUnionFunDescriptor
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthFunDescriptor (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT USB_ETHERNET_FUN_DESCRIPTOR *UsbEthFunDescriptor
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetUsbEthMcastFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value,
|
||||
IN VOID *McastAddr
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetUsbEthPowerFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value,
|
||||
IN UINT16 Length,
|
||||
IN VOID *PatternFilter
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthPowerFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value,
|
||||
OUT BOOLEAN *PatternActive
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetUsbEthPacketFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthStatistic (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 FeatureSelector,
|
||||
OUT VOID *Statistic
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
## @file
|
||||
# This is Usb Cdc Ecm driver for DXE phase.
|
||||
#
|
||||
# Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = UsbCdcEcm
|
||||
FILE_GUID = 07a84945-685d-48ec-a6a1-1b397579fa76
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = UsbEcmEntry
|
||||
|
||||
[Sources]
|
||||
UsbCdcEcm.c
|
||||
UsbCdcEcm.h
|
||||
UsbEcmFunction.c
|
||||
ComponentName.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
DebugLib
|
||||
UefiUsbLib
|
||||
MemoryAllocationLib
|
||||
BaseMemoryLib
|
||||
|
||||
[Protocols]
|
||||
gEfiUsbIoProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gEdkIIUsbEthProtocolGuid
|
||||
|
||||
[Depex]
|
||||
TRUE
|
|
@ -0,0 +1,880 @@
|
|||
/** @file
|
||||
This file contains code for USB Ethernet descriptor
|
||||
and specific requests implement.
|
||||
|
||||
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include "UsbCdcEcm.h"
|
||||
|
||||
/**
|
||||
Load All of device descriptor.
|
||||
|
||||
@param[in] UsbIo A pointer to the EFI_USB_IO_PROTOCOL instance.
|
||||
@param[out] ConfigDesc A pointer to the configuration descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The request executed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed because the
|
||||
buffer specified by DescriptorLength and Descriptor
|
||||
is not large enough to hold the result of the request.
|
||||
@retval EFI_TIMEOUT A timeout occurred executing the request.
|
||||
@retval EFI_DEVICE_ERROR The request failed due to a device error. The transfer
|
||||
status is returned in Status.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
LoadAllDescriptor (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
OUT EFI_USB_CONFIG_DESCRIPTOR **ConfigDesc
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 TransStatus;
|
||||
EFI_USB_CONFIG_DESCRIPTOR Tmp;
|
||||
|
||||
Status = UsbIo->UsbGetConfigDescriptor (UsbIo, &Tmp);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gBS->AllocatePool (EfiBootServicesData, Tmp.TotalLength, (VOID **)ConfigDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = UsbGetDescriptor (
|
||||
UsbIo,
|
||||
USB_DESC_TYPE_CONFIG << 8 | (Tmp.ConfigurationValue - 1), // zero based
|
||||
0,
|
||||
Tmp.TotalLength,
|
||||
*ConfigDesc,
|
||||
&TransStatus
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns pointer to the next descriptor for the pack of USB descriptors
|
||||
located in continues memory segment
|
||||
|
||||
@param[in] Desc A pointer to the CONFIG_DESCRIPTOR instance.
|
||||
@param[in, out] Offset A pointer to the sum of descriptor length.
|
||||
|
||||
@retval TRUE The request executed successfully.
|
||||
@retval FALSE No next descriptor.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
NextDescriptor (
|
||||
IN EFI_USB_CONFIG_DESCRIPTOR *Desc,
|
||||
IN OUT UINTN *Offset
|
||||
)
|
||||
{
|
||||
if ((Desc == NULL) || (*Offset >= Desc->TotalLength)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (((EFI_USB_CONFIG_DESCRIPTOR *)((char *)Desc+*Offset))->Length == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*Offset += ((EFI_USB_CONFIG_DESCRIPTOR *)((char *)Desc+*Offset))->Length;
|
||||
if ( *Offset >= Desc->TotalLength ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Read Function descriptor
|
||||
|
||||
@param[in] Config A pointer to all of configuration.
|
||||
@param[in] FunDescriptorType USB CDC class descriptor SubType.
|
||||
@param[out] DataBuffer A pointer to the Data of corresponding to device capability.
|
||||
|
||||
@retval EFI_SUCCESS The device capability descriptor was retrieved
|
||||
successfully.
|
||||
@retval EFI_UNSUPPORTED No supported.
|
||||
@retval EFI_NOT_FOUND The device capability descriptor was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetFunctionalDescriptor (
|
||||
IN EFI_USB_CONFIG_DESCRIPTOR *Config,
|
||||
IN UINT8 FunDescriptorType,
|
||||
OUT VOID *DataBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Offset;
|
||||
EFI_USB_INTERFACE_DESCRIPTOR *Interface;
|
||||
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
for (Offset = 0; NextDescriptor (Config, &Offset);) {
|
||||
Interface = (EFI_USB_INTERFACE_DESCRIPTOR *)((UINT8 *)Config + Offset);
|
||||
if (Interface->DescriptorType == CS_INTERFACE) {
|
||||
if (((USB_HEADER_FUN_DESCRIPTOR *)Interface)->DescriptorSubtype == FunDescriptorType) {
|
||||
switch (FunDescriptorType) {
|
||||
case HEADER_FUN_DESCRIPTOR:
|
||||
CopyMem (
|
||||
DataBuffer,
|
||||
(USB_HEADER_FUN_DESCRIPTOR *)Interface,
|
||||
sizeof (USB_HEADER_FUN_DESCRIPTOR)
|
||||
);
|
||||
return EFI_SUCCESS;
|
||||
case UNION_FUN_DESCRIPTOR:
|
||||
CopyMem (
|
||||
DataBuffer,
|
||||
(USB_UNION_FUN_DESCRIPTOR *)Interface,
|
||||
((USB_UNION_FUN_DESCRIPTOR *)Interface)->FunctionLength
|
||||
);
|
||||
return EFI_SUCCESS;
|
||||
case ETHERNET_FUN_DESCRIPTOR:
|
||||
CopyMem (
|
||||
DataBuffer,
|
||||
(USB_ETHERNET_FUN_DESCRIPTOR *)Interface,
|
||||
sizeof (USB_ETHERNET_FUN_DESCRIPTOR)
|
||||
);
|
||||
return EFI_SUCCESS;
|
||||
default:
|
||||
Status = EFI_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Get USB Ethernet IO endpoint and USB CDC data IO endpoint.
|
||||
|
||||
@param[in] UsbIo A pointer to the EFI_USB_IO_PROTOCOL instance.
|
||||
@param[in, out] UsbEthDriver A pointer to the USB_ETHERNET_DRIVER instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
GetEndpoint (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN OUT USB_ETHERNET_DRIVER *UsbEthDriver
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 Index;
|
||||
UINT32 Result;
|
||||
EFI_USB_INTERFACE_DESCRIPTOR Interface;
|
||||
EFI_USB_ENDPOINT_DESCRIPTOR Endpoint;
|
||||
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (Interface.NumEndpoints == 0) {
|
||||
Status = UsbSetInterface (UsbIo, Interface.InterfaceNumber, 1, &Result);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Interface.NumEndpoints; Index++) {
|
||||
Status = UsbIo->UsbGetEndpointDescriptor (UsbIo, Index, &Endpoint);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
switch ((Endpoint.Attributes & (BIT0 | BIT1))) {
|
||||
case USB_ENDPOINT_BULK:
|
||||
if (Endpoint.EndpointAddress & BIT7) {
|
||||
UsbEthDriver->BulkInEndpoint = Endpoint.EndpointAddress;
|
||||
} else {
|
||||
UsbEthDriver->BulkOutEndpoint = Endpoint.EndpointAddress;
|
||||
}
|
||||
|
||||
break;
|
||||
case USB_ENDPOINT_INTERRUPT:
|
||||
UsbEthDriver->InterruptEndpoint = Endpoint.EndpointAddress;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to manage a USB device with the bulk transfer pipe. The endpoint is Bulk in.
|
||||
|
||||
@param[in] Cdb A pointer to the command descriptor block.
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in, out] Packet A pointer to the buffer of data that will be transmitted to USB
|
||||
device or received from USB device.
|
||||
@param[in, out] PacketLength A pointer to the PacketLength.
|
||||
|
||||
@retval EFI_SUCCESS The bulk transfer has been successfully executed.
|
||||
@retval EFI_DEVICE_ERROR The transfer failed. The transfer status is returned in status.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources.
|
||||
@retval EFI_TIMEOUT The control transfer fails due to timeout.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmReceive (
|
||||
IN PXE_CDB *Cdb,
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN OUT VOID *Packet,
|
||||
IN OUT UINTN *PacketLength
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
UINT32 TransStatus;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
UsbEthDriver->UsbCdcDataHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
(VOID **)&UsbIo
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (UsbEthDriver->BulkInEndpoint == 0) {
|
||||
GetEndpoint (UsbIo, UsbEthDriver);
|
||||
}
|
||||
|
||||
Status = UsbIo->UsbBulkTransfer (
|
||||
UsbIo,
|
||||
UsbEthDriver->BulkInEndpoint,
|
||||
Packet,
|
||||
PacketLength,
|
||||
USB_ETHERNET_BULK_TIMEOUT,
|
||||
&TransStatus
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to manage a USB device with the bulk transfer pipe. The endpoint is Bulk out.
|
||||
|
||||
@param[in] Cdb A pointer to the command descriptor block.
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] Packet A pointer to the buffer of data that will be transmitted to USB
|
||||
device or received from USB device.
|
||||
@param[in, out] PacketLength A pointer to the PacketLength.
|
||||
|
||||
@retval EFI_SUCCESS The bulk transfer has been successfully executed.
|
||||
@retval EFI_DEVICE_ERROR The transfer failed. The transfer status is returned in status.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources.
|
||||
@retval EFI_TIMEOUT The control transfer fails due to timeout.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmTransmit (
|
||||
IN PXE_CDB *Cdb,
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN VOID *Packet,
|
||||
IN OUT UINTN *PacketLength
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
UINT32 TransStatus;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
UsbEthDriver->UsbCdcDataHandle,
|
||||
&gEfiUsbIoProtocolGuid,
|
||||
(VOID **)&UsbIo
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (UsbEthDriver->BulkOutEndpoint == 0) {
|
||||
GetEndpoint (UsbIo, UsbEthDriver);
|
||||
}
|
||||
|
||||
Status = UsbIo->UsbBulkTransfer (
|
||||
UsbIo,
|
||||
UsbEthDriver->BulkOutEndpoint,
|
||||
Packet,
|
||||
PacketLength,
|
||||
USB_ETHERNET_BULK_TIMEOUT,
|
||||
&TransStatus
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Async USB transfer callback routine.
|
||||
|
||||
@param[in] Data Data received or sent via the USB Asynchronous Transfer, if the
|
||||
transfer completed successfully.
|
||||
@param[in] DataLength The length of Data received or sent via the Asynchronous
|
||||
Transfer, if transfer successfully completes.
|
||||
@param[in] Context Data passed from UsbAsyncInterruptTransfer() request.
|
||||
@param[in] Status Indicates the result of the asynchronous transfer.
|
||||
|
||||
@retval EFI_SUCCESS The asynchronous USB transfer request has been successfully executed.
|
||||
@retval EFI_DEVICE_ERROR The asynchronous USB transfer request failed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InterruptCallback (
|
||||
IN VOID *Data,
|
||||
IN UINTN DataLength,
|
||||
IN VOID *Context,
|
||||
IN UINT32 Status
|
||||
)
|
||||
{
|
||||
if ((Data == NULL) || (Context == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((EFI_USB_DEVICE_REQUEST *)Data)->Request == USB_CDC_NETWORK_CONNECTION) {
|
||||
CopyMem (
|
||||
(EFI_USB_DEVICE_REQUEST *)Context,
|
||||
(EFI_USB_DEVICE_REQUEST *)Data,
|
||||
sizeof (EFI_USB_DEVICE_REQUEST)
|
||||
);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to manage a USB device with an interrupt transfer pipe.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] IsNewTransfer If TRUE, a new transfer will be submitted to USB controller. If
|
||||
FALSE, the interrupt transfer is deleted from the device's interrupt
|
||||
transfer queue.
|
||||
@param[in] PollingInterval Indicates the periodic rate, in milliseconds, that the transfer is to be
|
||||
executed.This parameter is required when IsNewTransfer is TRUE. The
|
||||
value must be between 1 to 255, otherwise EFI_INVALID_PARAMETER is returned.
|
||||
The units are in milliseconds.
|
||||
@param[in] Request A pointer to the EFI_USB_DEVICE_REQUEST data.
|
||||
|
||||
@retval EFI_SUCCESS The asynchronous USB transfer request transfer has been successfully executed.
|
||||
@retval EFI_DEVICE_ERROR The asynchronous USB transfer request failed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmInterrupt (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN BOOLEAN IsNewTransfer,
|
||||
IN UINTN PollingInterval,
|
||||
IN EFI_USB_DEVICE_REQUEST *Request
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
UINTN DataLength;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
DataLength = 0;
|
||||
|
||||
if (IsNewTransfer) {
|
||||
DataLength = sizeof (EFI_USB_DEVICE_REQUEST) + sizeof (USB_CONNECT_SPEED_CHANGE);
|
||||
Status = UsbEthDriver->UsbIo->UsbAsyncInterruptTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
UsbEthDriver->InterruptEndpoint,
|
||||
IsNewTransfer,
|
||||
PollingInterval,
|
||||
DataLength,
|
||||
(EFI_ASYNC_USB_TRANSFER_CALLBACK)InterruptCallback,
|
||||
Request
|
||||
);
|
||||
} else {
|
||||
Status = UsbEthDriver->UsbIo->UsbAsyncInterruptTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
UsbEthDriver->InterruptEndpoint,
|
||||
IsNewTransfer,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the USB Ethernet Mac Address.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[out] MacAddress A pointer to the caller allocated USB Ethernet Mac Address.
|
||||
|
||||
@retval EFI_SUCCESS The USB Header Functional descriptor was retrieved successfully.
|
||||
@retval EFI_INVALID_PARAMETER UsbHeaderFunDescriptor is NULL.
|
||||
@retval EFI_NOT_FOUND The USB Header Functional descriptor was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthMacAddress (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT EFI_MAC_ADDRESS *MacAddress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
USB_ETHERNET_FUN_DESCRIPTOR UsbEthDescriptor;
|
||||
CHAR16 *Data;
|
||||
CHAR16 *DataPtr;
|
||||
CHAR16 TmpStr[1];
|
||||
UINT8 Index;
|
||||
UINT8 Hi;
|
||||
UINT8 Low;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Status = This->UsbEthFunDescriptor (This, &UsbEthDescriptor);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a:UsbEthFunDescriptor status = %r\n", __func__, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = UsbEthDriver->UsbIo->UsbGetStringDescriptor (
|
||||
UsbEthDriver->UsbIo,
|
||||
0x409, // English-US Language ID
|
||||
UsbEthDescriptor.MacAddress,
|
||||
&Data
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a:UsbGetStringDescriptor status = %r\n", __func__, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
DataPtr = Data;
|
||||
for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
|
||||
CopyMem (TmpStr, DataPtr, sizeof (CHAR16));
|
||||
DataPtr++;
|
||||
Hi = (UINT8)StrHexToUintn (TmpStr);
|
||||
CopyMem (TmpStr, DataPtr, sizeof (CHAR16));
|
||||
DataPtr++;
|
||||
Low = (UINT8)StrHexToUintn (TmpStr);
|
||||
MacAddress->Addr[Index] = (Hi << 4) | Low;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the USB Ethernet Bulk transfer data size.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[out] BulkSize A pointer to the Bulk transfer data size.
|
||||
|
||||
@retval EFI_SUCCESS The bulk transfer data size was retrieved successfully.
|
||||
@retval other Failed to retrieve the bulk transfer data size.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UsbEthEcmBulkSize (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT UINTN *BulkSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_FUN_DESCRIPTOR UsbEthFunDescriptor;
|
||||
|
||||
Status = This->UsbEthFunDescriptor (This, &UsbEthFunDescriptor);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*BulkSize = (UINTN)UsbEthFunDescriptor.MaxSegmentSize;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the USB Header functional Descriptor.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[out] UsbHeaderFunDescriptor A pointer to the caller allocated USB Header Functional Descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The USB Header Functional descriptor was retrieved successfully.
|
||||
@retval EFI_INVALID_PARAMETER UsbHeaderFunDescriptor is NULL.
|
||||
@retval EFI_NOT_FOUND The USB Header Functional descriptor was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbHeaderFunDescriptor (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT USB_HEADER_FUN_DESCRIPTOR *UsbHeaderFunDescriptor
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
if (UsbHeaderFunDescriptor == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = GetFunctionalDescriptor (UsbEthDriver->Config, HEADER_FUN_DESCRIPTOR, UsbHeaderFunDescriptor);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the USB Union functional Descriptor.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[out] UsbUnionFunDescriptor A pointer to the caller allocated USB Union Functional Descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The USB Union Functional descriptor was retrieved successfully.
|
||||
@retval EFI_INVALID_PARAMETER UsbUnionFunDescriptor is NULL.
|
||||
@retval EFI_NOT_FOUND The USB Union Functional descriptor was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbUnionFunDescriptor (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT USB_UNION_FUN_DESCRIPTOR *UsbUnionFunDescriptor
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
if (UsbUnionFunDescriptor == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = GetFunctionalDescriptor (UsbEthDriver->Config, UNION_FUN_DESCRIPTOR, UsbUnionFunDescriptor);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the USB Ethernet functional Descriptor.
|
||||
|
||||
This function get the Mac Address, Ethernet statistics, maximum segment size,
|
||||
number of multicast filters, and number of pattern filters from Ethernet
|
||||
functional Descriptor.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[out] UsbEthFunDescriptor A pointer to the caller allocated USB Ethernet Functional Descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The USB Ethernet Functional descriptor was retrieved successfully.
|
||||
@retval EFI_INVALID_PARAMETER UsbEthFunDescriptor is NULL.
|
||||
@retval EFI_NOT_FOUND The USB Ethernet Functional descriptor was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthFunDescriptor (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
OUT USB_ETHERNET_FUN_DESCRIPTOR *UsbEthFunDescriptor
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
if (UsbEthFunDescriptor == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = GetFunctionalDescriptor (UsbEthDriver->Config, ETHERNET_FUN_DESCRIPTOR, UsbEthFunDescriptor);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This request sets the Ethernet device multicast filters as specified in the
|
||||
sequential list of 48 bit Ethernet multicast addresses.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] Value Number of filters.
|
||||
@param[in] McastAddr A pointer to the value of the multicast addresses.
|
||||
|
||||
@retval EFI_SUCCESS The request executed successfully.
|
||||
@retval EFI_TIMEOUT A timeout occurred executing the request.
|
||||
@retval EFI_DEVICE_ERROR The request failed due to a device error.
|
||||
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
|
||||
@retval EFI_UNSUPPORTED Not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetUsbEthMcastFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value,
|
||||
IN VOID *McastAddr
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_USB_DEVICE_REQUEST Request;
|
||||
UINT32 TransStatus;
|
||||
USB_ETHERNET_FUN_DESCRIPTOR UsbEthFunDescriptor;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Status = This->UsbEthFunDescriptor (This, &UsbEthFunDescriptor);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((UsbEthFunDescriptor.NumberMcFilters << 1) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Request.RequestType = USB_ETHERNET_SET_REQ_TYPE;
|
||||
Request.Request = SET_ETH_MULTICAST_FILTERS_REQ;
|
||||
Request.Value = Value;
|
||||
Request.Index = UsbEthDriver->NumOfInterface;
|
||||
Request.Length = Value * 6;
|
||||
|
||||
return UsbEthDriver->UsbIo->UsbControlTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
&Request,
|
||||
EfiUsbDataOut,
|
||||
USB_ETHERNET_TRANSFER_TIMEOUT,
|
||||
McastAddr,
|
||||
Request.Length,
|
||||
&TransStatus
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This request sets up the specified Ethernet power management pattern filter as
|
||||
described in the data structure.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] Value Number of filters.
|
||||
@param[in] Length Size of the power management pattern filter data.
|
||||
@param[in] PatternFilter A pointer to the power management pattern filter structure.
|
||||
|
||||
@retval EFI_SUCCESS The request executed successfully.
|
||||
@retval EFI_TIMEOUT A timeout occurred executing the request.
|
||||
@retval EFI_DEVICE_ERROR The request failed due to a device error.
|
||||
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
|
||||
@retval EFI_UNSUPPORTED Not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetUsbEthPowerFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value,
|
||||
IN UINT16 Length,
|
||||
IN VOID *PatternFilter
|
||||
)
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST Request;
|
||||
UINT32 TransStatus;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Request.RequestType = USB_ETHERNET_SET_REQ_TYPE;
|
||||
Request.Request = SET_ETH_POWER_MANAGEMENT_PATTERN_FILTER_REQ;
|
||||
Request.Value = Value;
|
||||
Request.Index = UsbEthDriver->NumOfInterface;
|
||||
Request.Length = Length;
|
||||
|
||||
return UsbEthDriver->UsbIo->UsbControlTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
&Request,
|
||||
EfiUsbDataOut,
|
||||
USB_ETHERNET_TRANSFER_TIMEOUT,
|
||||
PatternFilter,
|
||||
Length,
|
||||
&TransStatus
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This request retrieves the status of the specified Ethernet power management
|
||||
pattern filter from the device.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] Value The filter number.
|
||||
@param[out] PatternActive A pointer to the pattern active boolean.
|
||||
|
||||
@retval EFI_SUCCESS The request executed successfully.
|
||||
@retval EFI_TIMEOUT A timeout occurred executing the request.
|
||||
@retval EFI_DEVICE_ERROR The request failed due to a device error.
|
||||
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
|
||||
@retval EFI_UNSUPPORTED Not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthPowerFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value,
|
||||
OUT BOOLEAN *PatternActive
|
||||
)
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST Request;
|
||||
UINT32 TransStatus;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Request.RequestType = USB_ETHERNET_GET_REQ_TYPE;
|
||||
Request.Request = GET_ETH_POWER_MANAGEMENT_PATTERN_FILTER_REQ;
|
||||
Request.Value = Value;
|
||||
Request.Index = UsbEthDriver->NumOfInterface;
|
||||
Request.Length = USB_ETH_POWER_FILTER_LENGTH;
|
||||
|
||||
return UsbEthDriver->UsbIo->UsbControlTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
&Request,
|
||||
EfiUsbDataIn,
|
||||
USB_ETHERNET_TRANSFER_TIMEOUT,
|
||||
PatternActive,
|
||||
USB_ETH_POWER_FILTER_LENGTH,
|
||||
&TransStatus
|
||||
);
|
||||
}
|
||||
|
||||
BIT_MAP gTable[] = {
|
||||
{ PXE_OPFLAGS_RECEIVE_FILTER_UNICAST, USB_ETH_PACKET_TYPE_DIRECTED },
|
||||
{ PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST, USB_ETH_PACKET_TYPE_BROADCAST },
|
||||
{ PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST, USB_ETH_PACKET_TYPE_MULTICAST },
|
||||
{ PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS, USB_ETH_PACKET_TYPE_PROMISCUOUS },
|
||||
{ PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST, USB_ETH_PACKET_TYPE_ALL_MULTICAST },
|
||||
};
|
||||
|
||||
/**
|
||||
Convert value between PXE receive filter and USB ETH packet filter.
|
||||
|
||||
@param[in] Value PXE filter data.
|
||||
@param[out] CdcFilter A pointer to the Ethernet Packet Filter Bitmap value converted by PXE_OPFLAGS.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ConvertFilter (
|
||||
IN UINT16 Value,
|
||||
OUT UINT16 *CdcFilter
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT32 Count;
|
||||
|
||||
Count = sizeof (gTable)/sizeof (gTable[0]);
|
||||
|
||||
for (Index = 0; (gTable[Index].Src != 0) && (Index < Count); Index++) {
|
||||
if (gTable[Index].Src & Value) {
|
||||
*CdcFilter |= gTable[Index].Dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This request is used to configure device Ethernet packet filter settings.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] Value Packet Filter Bitmap.
|
||||
|
||||
@retval EFI_SUCCESS The request executed successfully.
|
||||
@retval EFI_TIMEOUT A timeout occurred executing the request.
|
||||
@retval EFI_DEVICE_ERROR The request failed due to a device error.
|
||||
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
|
||||
@retval EFI_UNSUPPORTED Not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetUsbEthPacketFilter (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 Value
|
||||
)
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST Request;
|
||||
UINT32 TransStatus;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
UINT16 CommandFilter;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
CommandFilter = 0;
|
||||
|
||||
ConvertFilter (Value, &CommandFilter);
|
||||
|
||||
Request.RequestType = USB_ETHERNET_SET_REQ_TYPE;
|
||||
Request.Request = SET_ETH_PACKET_FILTER_REQ;
|
||||
Request.Value = CommandFilter;
|
||||
Request.Index = UsbEthDriver->NumOfInterface;
|
||||
Request.Length = USB_ETH_PACKET_FILTER_LENGTH;
|
||||
|
||||
return UsbEthDriver->UsbIo->UsbControlTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
&Request,
|
||||
EfiUsbNoData,
|
||||
USB_ETHERNET_TRANSFER_TIMEOUT,
|
||||
NULL,
|
||||
USB_ETH_PACKET_FILTER_LENGTH,
|
||||
&TransStatus
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This request is used to retrieve a statistic based on the feature selector.
|
||||
|
||||
@param[in] This A pointer to the EDKII_USB_ETHERNET_PROTOCOL instance.
|
||||
@param[in] FeatureSelector Value of the feature selector.
|
||||
@param[out] Statistic A pointer to the 32 bit unsigned integer.
|
||||
|
||||
@retval EFI_SUCCESS The request executed successfully.
|
||||
@retval EFI_TIMEOUT A timeout occurred executing the request.
|
||||
@retval EFI_DEVICE_ERROR The request failed due to a device error.
|
||||
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
|
||||
@retval EFI_UNSUPPORTED Not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetUsbEthStatistic (
|
||||
IN EDKII_USB_ETHERNET_PROTOCOL *This,
|
||||
IN UINT16 FeatureSelector,
|
||||
OUT VOID *Statistic
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_USB_DEVICE_REQUEST Request;
|
||||
UINT32 TransStatus;
|
||||
USB_ETHERNET_FUN_DESCRIPTOR UsbEthFunDescriptor;
|
||||
USB_ETHERNET_DRIVER *UsbEthDriver;
|
||||
|
||||
UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (This);
|
||||
|
||||
Status = This->UsbEthFunDescriptor (This, &UsbEthFunDescriptor);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (UsbEthFunDescriptor.EthernetStatistics == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Request.RequestType = USB_ETHERNET_GET_REQ_TYPE;
|
||||
Request.Request = GET_ETH_STATISTIC_REQ;
|
||||
Request.Value = FeatureSelector;
|
||||
Request.Index = UsbEthDriver->NumOfInterface;
|
||||
Request.Length = USB_ETH_STATISTIC;
|
||||
|
||||
return UsbEthDriver->UsbIo->UsbControlTransfer (
|
||||
UsbEthDriver->UsbIo,
|
||||
&Request,
|
||||
EfiUsbDataIn,
|
||||
USB_ETHERNET_TRANSFER_TIMEOUT,
|
||||
Statistic,
|
||||
USB_ETH_STATISTIC,
|
||||
&TransStatus
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue