MdeModulePkg/Bus/Usb/UsbNetwork/UsbRndis: Add USB RNDIS devices support

This driver provides UEFI driver for USB RNDIS 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:
Richard Ho
2023-07-13 14:15:32 +08:00
committed by mergify[bot]
parent 8dab4eebe4
commit fc0d5922f1
13 changed files with 7286 additions and 0 deletions

View File

@@ -0,0 +1,263 @@
/** @file
This file contains code for USB network common driver
component name definitions
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "DriverBinding.h"
extern EFI_DRIVER_BINDING_PROTOCOL gNetworkCommonDriverBinding;
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE gNetworkCommonDriverNameTable[] = {
{
"eng;en",
L"Network Common Driver"
},
{
NULL,
NULL
}
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gNetworkCommonControllerNameTable = NULL;
EFI_STATUS
EFIAPI
NetworkCommonComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
NetworkCommonComponentNameGetControllerName (
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 gNetworkCommonComponentName = {
NetworkCommonComponentNameGetDriverName,
NetworkCommonComponentNameGetControllerName,
"eng"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gNetworkCommonComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME)NetworkCommonComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)NetworkCommonComponentNameGetControllerName,
"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
NetworkCommonComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gNetworkCommonDriverNameTable,
DriverName,
(BOOLEAN)(This == &gNetworkCommonComponentName)
);
}
/**
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
NetworkCommonComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
CHAR16 *HandleName;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
if ((Language == NULL) || (ControllerName == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
Controller,
gNetworkCommonDriverBinding.DriverBindingHandle,
&gEdkIIUsbEthProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
Controller,
ChildHandle,
&gEdkIIUsbEthProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->HandleProtocol (Controller, &gEfiUsbIoProtocolGuid, (VOID **)&UsbIo);
if (!EFI_ERROR (Status)) {
Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
if (EFI_ERROR (Status)) {
return Status;
}
Status = UsbIo->UsbGetStringDescriptor (UsbIo, 0x409, DevDesc.StrManufacturer, &HandleName);
if (EFI_ERROR (Status)) {
return Status;
}
*ControllerName = HandleName;
if (gNetworkCommonControllerNameTable != NULL) {
FreeUnicodeStringTable (gNetworkCommonControllerNameTable);
gNetworkCommonControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gNetworkCommonComponentName.SupportedLanguages,
&gNetworkCommonControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = AddUnicodeString2 (
"en",
gNetworkCommonComponentName2.SupportedLanguages,
&gNetworkCommonControllerNameTable,
HandleName,
FALSE
);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gNetworkCommonControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gNetworkCommonComponentName)
);
}
return EFI_UNSUPPORTED;
}

View File

@@ -0,0 +1,595 @@
/** @file
This file contains code for USB network binding driver
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "DriverBinding.h"
PXE_SW_UNDI *gPxe = NULL;
NIC_DEVICE *gLanDeviceList[MAX_LAN_INTERFACE];
UINT32 gRateLimitingCredit;
UINT32 gRateLimitingPollTimer;
BOOLEAN gRateLimitingEnable;
EFI_DRIVER_BINDING_PROTOCOL gNetworkCommonDriverBinding = {
NetworkCommonSupported,
NetworkCommonDriverStart,
NetworkCommonDriverStop,
NETWORK_COMMON_DRIVER_VERSION,
NULL,
NULL
};
/**
Create MAC Device Path
@param[in, out] Dev A pointer to the EFI_DEVICE_PATH_PROTOCOL instance.
@param[in] BaseDev A pointer to the EFI_DEVICE_PATH_PROTOCOL instance.
@param[in] Nic A pointer to the Network interface controller data.
@retval EFI_OUT_OF_RESOURCES The device path could not be created successfully due to a lack of resources.
@retval EFI_SUCCESS MAC device path created successfully.
**/
EFI_STATUS
CreateMacDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL **Dev,
IN EFI_DEVICE_PATH_PROTOCOL *BaseDev,
IN NIC_DATA *Nic
)
{
EFI_STATUS Status;
MAC_ADDR_DEVICE_PATH MacAddrNode;
EFI_DEVICE_PATH_PROTOCOL *EndNode;
UINT8 *DevicePath;
UINT16 TotalLength;
UINT16 BaseLength;
ZeroMem (&MacAddrNode, sizeof (MAC_ADDR_DEVICE_PATH));
CopyMem (&MacAddrNode.MacAddress, &Nic->MacAddr, sizeof (EFI_MAC_ADDRESS));
MacAddrNode.Header.Type = MESSAGING_DEVICE_PATH;
MacAddrNode.Header.SubType = MSG_MAC_ADDR_DP;
MacAddrNode.Header.Length[0] = (UINT8)sizeof (MacAddrNode);
MacAddrNode.Header.Length[1] = 0;
EndNode = BaseDev;
while (!IsDevicePathEnd (EndNode)) {
EndNode = NextDevicePathNode (EndNode);
}
BaseLength = (UINT16)((UINTN)(EndNode) - (UINTN)(BaseDev));
TotalLength = (UINT16)(BaseLength + sizeof (MacAddrNode) + sizeof (EFI_DEVICE_PATH_PROTOCOL));
Status = gBS->AllocatePool (EfiBootServicesData, TotalLength, (VOID **)&DevicePath);
if (EFI_ERROR (Status)) {
return Status;
}
*Dev = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
CopyMem (DevicePath, (CHAR8 *)BaseDev, BaseLength);
DevicePath += BaseLength;
CopyMem (DevicePath, (CHAR8 *)&MacAddrNode, sizeof (MacAddrNode));
DevicePath += sizeof (MacAddrNode);
CopyMem (DevicePath, (CHAR8 *)EndNode, sizeof (EFI_DEVICE_PATH_PROTOCOL));
return EFI_SUCCESS;
}
/**
Network Common 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
NetworkCommonSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EDKII_USB_ETHERNET_PROTOCOL *UsbEth;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
(VOID **)&UsbEth,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
/**
Network Common 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
NetworkCommonDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *UsbEthPath;
EDKII_USB_ETHERNET_PROTOCOL *UsbEth;
EFI_MAC_ADDRESS MacAddress;
UINTN BulkDataSize;
NIC_DEVICE *NicDevice;
UINT8 *TmpPxePointer;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
(VOID **)&UsbEth,
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_BY_DRIVER
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
ZeroMem (&MacAddress, sizeof (EFI_MAC_ADDRESS));
Status = UsbEth->UsbEthMacAddress (UsbEth, &MacAddress);
ASSERT_EFI_ERROR (Status);
Status = UsbEth->UsbEthMaxBulkSize (UsbEth, &BulkDataSize);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
NicDevice = AllocateZeroPool (sizeof (NIC_DEVICE) + BulkDataSize + 4096);
if (!NicDevice) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_OUT_OF_RESOURCES;
}
// for alignment adjustment
if (gPxe == NULL) {
TmpPxePointer = NULL;
TmpPxePointer = AllocateZeroPool (sizeof (PXE_SW_UNDI) + 16);
if (!TmpPxePointer) {
if (NicDevice != NULL) {
FreePool (NicDevice);
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_OUT_OF_RESOURCES;
} else {
// check for paragraph alignment here
if (((UINTN)TmpPxePointer & 0x0F) != 0) {
gPxe = (PXE_SW_UNDI *)(TmpPxePointer + 8);
} else {
gPxe = (PXE_SW_UNDI *)TmpPxePointer;
}
if (gPxe == NULL) {
if (NicDevice != NULL) {
FreePool (NicDevice);
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_OUT_OF_RESOURCES;
}
PxeStructInit (gPxe);
}
}
NicDevice->NiiProtocol.Id = (UINT64)(UINTN)(gPxe);
NicDevice->NiiProtocol.IfNum = gPxe->IFcnt | gPxe->IFcntExt << 8;
UpdateNicNum (&NicDevice->NicInfo, gPxe);
NicDevice->NicInfo.Signature = NIC_DATA_SIGNATURE;
NicDevice->NicInfo.UsbEth = UsbEth;
NicDevice->NicInfo.MaxSegmentSize = (UINT16)BulkDataSize;
NicDevice->NicInfo.CableDetect = 0;
NicDevice->ReceiveBuffer = ALIGN_POINTER ((VOID *)NicDevice, 4096);
CopyMem ((CHAR8 *)&(NicDevice->NicInfo.MacAddr), (CHAR8 *)&MacAddress, sizeof (MacAddress));
NicDevice->NicInfo.TxBufferCount = 0;
if (NicDevice->NiiProtocol.IfNum < MAX_LAN_INTERFACE) {
gLanDeviceList[NicDevice->NiiProtocol.IfNum] = NicDevice;
} else {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
if (TmpPxePointer != NULL) {
FreePool (TmpPxePointer);
}
if (NicDevice != NULL) {
FreePool (NicDevice);
}
return EFI_DEVICE_ERROR;
}
Status = CreateMacDevicePath (
&NicDevice->DevPath,
UsbEthPath,
&NicDevice->NicInfo
);
if (EFI_ERROR (Status)) {
UpdateNicNum (NULL, gPxe);
if (TmpPxePointer != NULL) {
FreePool (TmpPxePointer);
}
}
NicDevice->Signature = UNDI_DEV_SIGNATURE;
NicDevice->NiiProtocol.Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;
NicDevice->NiiProtocol.Type = EfiNetworkInterfaceUndi;
NicDevice->NiiProtocol.MajorVer = PXE_ROMID_MAJORVER;
NicDevice->NiiProtocol.MinorVer = PXE_ROMID_MINORVER;
NicDevice->NiiProtocol.ImageSize = 0;
NicDevice->NiiProtocol.ImageAddr = 0;
NicDevice->NiiProtocol.Ipv6Supported = TRUE;
NicDevice->NiiProtocol.StringId[0] = 'U';
NicDevice->NiiProtocol.StringId[1] = 'N';
NicDevice->NiiProtocol.StringId[2] = 'D';
NicDevice->NiiProtocol.StringId[3] = 'I';
NicDevice->DeviceHandle = NULL;
NicDevice->NicInfo.RateLimitingEnable = gRateLimitingEnable;
NicDevice->NicInfo.RateLimitingCreditCount = 0;
NicDevice->NicInfo.RateLimitingCredit = gRateLimitingCredit;
NicDevice->NicInfo.RateLimitingPollTimer = gRateLimitingPollTimer;
NicDevice->NicInfo.RateLimiter = NULL;
ZeroMem (&NicDevice->NicInfo.Request, sizeof (EFI_USB_DEVICE_REQUEST));
Status = UsbEth->UsbEthInterrupt (UsbEth, TRUE, NETWORK_COMMON_POLLING_INTERVAL, &NicDevice->NicInfo.Request);
ASSERT_EFI_ERROR (Status);
Status = gBS->InstallMultipleProtocolInterfaces (
&NicDevice->DeviceHandle,
&gEfiNetworkInterfaceIdentifierProtocolGuid_31,
&NicDevice->NiiProtocol,
&gEfiDevicePathProtocolGuid,
NicDevice->DevPath,
NULL
);
if (EFI_ERROR (Status)) {
if (NicDevice->NiiProtocol.IfNum < MAX_LAN_INTERFACE) {
gLanDeviceList[NicDevice->NiiProtocol.IfNum] = NULL;
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
if (TmpPxePointer != NULL) {
FreePool (TmpPxePointer);
}
if (NicDevice->DevPath != NULL) {
FreePool (NicDevice->DevPath);
}
if (NicDevice != NULL) {
FreePool (NicDevice);
}
return EFI_DEVICE_ERROR;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
(VOID **)&UsbEth,
This->DriverBindingHandle,
NicDevice->DeviceHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
return Status;
}
/**
Network Common 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
NetworkCommonDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
BOOLEAN AllChildrenStopped;
UINTN Index;
EDKII_USB_ETHERNET_PROTOCOL *UsbEth;
NIC_DEVICE *NicDevice;
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiProtocol;
if (NumberOfChildren == 0) {
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiNetworkInterfaceIdentifierProtocolGuid_31,
(VOID **)&NiiProtocol,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
NicDevice = UNDI_DEV_FROM_THIS (NiiProtocol);
Status = gBS->UninstallMultipleProtocolInterfaces (
ControllerHandle,
&gEfiNetworkInterfaceIdentifierProtocolGuid_31,
&NicDevice->NiiProtocol,
&gEfiDevicePathProtocolGuid,
NicDevice->DevPath,
NULL
);
if (EFI_ERROR (Status)) {
return Status;
}
FreePool (NicDevice->DevPath);
FreePool (NicDevice);
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
AllChildrenStopped = TRUE;
for (Index = 0; Index < NumberOfChildren; Index++) {
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index],
&gEfiNetworkInterfaceIdentifierProtocolGuid_31,
(VOID **)&NiiProtocol,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
continue;
}
NicDevice = UNDI_DEV_FROM_THIS (NiiProtocol);
gBS->CloseProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiNetworkInterfaceIdentifierProtocolGuid_31,
&NicDevice->NiiProtocol,
&gEfiDevicePathProtocolGuid,
NicDevice->DevPath,
NULL
);
if (EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
ControllerHandle,
&gEdkIIUsbEthProtocolGuid,
(VOID **)&UsbEth,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
FreePool (NicDevice->DevPath);
FreePool (NicDevice);
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return Status;
}
/**
Entrypoint of Network Common Driver.
This function is the entrypoint of Network Common 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
NetworkCommonEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
gNetworkCommonDriverBinding.DriverBindingHandle = ImageHandle;
gNetworkCommonDriverBinding.ImageHandle = ImageHandle;
gRateLimitingEnable = PcdGetBool (PcdEnableUsbNetworkRateLimiting);
gRateLimitingCredit = PcdGet32 (PcdUsbNetworkRateLimitingCredit);
gRateLimitingPollTimer = PcdGet32 (PcdUsbNetworkRateLimitingFactor);
Status = gBS->InstallMultipleProtocolInterfaces (
&gNetworkCommonDriverBinding.DriverBindingHandle,
&gEfiDriverBindingProtocolGuid,
&gNetworkCommonDriverBinding,
&gEfiComponentName2ProtocolGuid,
&gNetworkCommonComponentName2,
NULL
);
return Status;
}

View File

@@ -0,0 +1,266 @@
/** @file
Header file for for USB network common driver
Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef DRIVER_BINDING_H_
#define DRIVER_BINDING_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/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiUsbLib.h>
#include <Protocol/UsbIo.h>
#include <Protocol/NetworkInterfaceIdentifier.h>
#include <Protocol/UsbEthernetProtocol.h>
#define NETWORK_COMMON_DRIVER_VERSION 1
#define NETWORK_COMMON_POLLING_INTERVAL 0x10
#define RX_BUFFER_COUNT 32
#define TX_BUFFER_COUNT 32
#define MEMORY_REQUIRE 0
#define UNDI_DEV_SIGNATURE SIGNATURE_32('u','n','d','i')
#define UNDI_DEV_FROM_THIS(a) CR(a, NIC_DEVICE, NiiProtocol, UNDI_DEV_SIGNATURE)
#define UNDI_DEV_FROM_NIC(a) CR(a, NIC_DEVICE, NicInfo, UNDI_DEV_SIGNATURE)
#pragma pack(1)
typedef struct {
UINT8 DestAddr[PXE_HWADDR_LEN_ETHER];
UINT8 SrcAddr[PXE_HWADDR_LEN_ETHER];
UINT16 Protocol;
} ETHERNET_HEADER;
#pragma pack()
typedef struct {
UINTN Signature;
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL NiiProtocol;
EFI_HANDLE DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *BaseDevPath;
EFI_DEVICE_PATH_PROTOCOL *DevPath;
NIC_DATA NicInfo;
VOID *ReceiveBuffer;
} NIC_DEVICE;
typedef VOID (*API_FUNC)(
PXE_CDB *,
NIC_DATA *
);
extern PXE_SW_UNDI *gPxe;
extern NIC_DEVICE *gLanDeviceList[MAX_LAN_INTERFACE];
extern EFI_COMPONENT_NAME2_PROTOCOL gNetworkCommonComponentName2;
EFI_STATUS
EFIAPI
NetworkCommonSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
NetworkCommonDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
NetworkCommonDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
VOID
PxeStructInit (
OUT PXE_SW_UNDI *PxeSw
);
VOID
UpdateNicNum (
IN NIC_DATA *Nic,
IN OUT PXE_SW_UNDI *PxeSw
);
EFI_STATUS
EFIAPI
UndiApiEntry (
IN UINT64 Cdb
);
UINTN
MapIt (
IN NIC_DATA *Nic,
IN UINT64 MemAddr,
IN UINT32 Size,
IN UINT32 Direction,
OUT UINT64 MappedAddr
);
VOID
UnMapIt (
IN NIC_DATA *Nic,
IN UINT64 MemAddr,
IN UINT32 Size,
IN UINT32 Direction,
IN UINT64 MappedAddr
);
VOID
UndiGetState (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiStart (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiStop (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiGetInitInfo (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiGetConfigInfo (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiInitialize (
IN PXE_CDB *Cdb,
IN OUT NIC_DATA *Nic
);
VOID
UndiReset (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiShutdown (
IN PXE_CDB *Cdb,
IN OUT NIC_DATA *Nic
);
VOID
UndiInterruptEnable (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiReceiveFilter (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiStationAddress (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiStatistics (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiMcastIp2Mac (
IN OUT PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiNvData (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiGetStatus (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiFillHeader (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiTransmit (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
VOID
UndiReceive (
IN PXE_CDB *Cdb,
IN NIC_DATA *Nic
);
UINT16
Initialize (
IN PXE_CDB *Cdb,
IN OUT NIC_DATA *Nic
);
UINT16
Transmit (
IN PXE_CDB *Cdb,
IN OUT NIC_DATA *Nic,
IN UINT64 CpbAddr,
IN UINT16 OpFlags
);
UINT16
Receive (
IN PXE_CDB *Cdb,
IN OUT NIC_DATA *Nic,
IN UINT64 CpbAddr,
IN OUT UINT64 DbAddr
);
UINT16
SetFilter (
IN NIC_DATA *Nic,
IN UINT16 SetFilter,
IN UINT64 CpbAddr,
IN UINT32 CpbSize
);
UINT16
Statistics (
IN NIC_DATA *Nic,
IN UINT64 DbAddr,
IN UINT16 DbSize
);
#endif

View File

@@ -0,0 +1,48 @@
## @file
# This is Usb Network Common 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 = NetworkCommon
FILE_GUID = ca6eb4f4-f1d6-4375-97d6-18856871e1bf
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = NetworkCommonEntry
[Sources]
DriverBinding.c
DriverBinding.h
ComponentName.c
PxeFunction.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiLib
DebugLib
UefiUsbLib
MemoryAllocationLib
BaseMemoryLib
[Protocols]
gEfiNetworkInterfaceIdentifierProtocolGuid_31
gEfiUsbIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiDriverBindingProtocolGuid
gEdkIIUsbEthProtocolGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUsbNetworkRateLimiting
gEfiMdeModulePkgTokenSpaceGuid.PcdUsbNetworkRateLimitingCredit
gEfiMdeModulePkgTokenSpaceGuid.PcdUsbNetworkRateLimitingFactor
[Depex]
TRUE

File diff suppressed because it is too large Load Diff