How to support SR_IOV in NDIS 630

Hello All,

I am working on NDIS SRIOV driver, here is my code in NDIS_MINIPORT_DRIVER_CHARACTERISTICS.InitializeHandlerEx:

if (status == NDIS_STATUS_SUCCESS)
{
NdisZeroMemory(&miniportAttributes, sizeof(miniportAttributes));
NDIS_HYPERVISOR_INFO hypervisorInfo;
NDIS_SRIOV_CAPABILITIES sriovCap;
NDIS_SRIOV_CAPABILITIES currentSriovCap;
NDIS_NIC_SWITCH_CAPABILITIES nicSwitchCap;
NDIS_NIC_SWITCH_CAPABILITIES currentNicSwitchCap;

	miniportAttributes.HardwareAssistAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
	miniportAttributes.HardwareAssistAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_2;
	miniportAttributes.HardwareAssistAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;

	sriovCap.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	sriovCap.Header.Size = NDIS_SIZEOF_SRIOV_CAPABILITIES_REVISION_1;

	currentSriovCap.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	currentSriovCap.Header.Size = NDIS_SIZEOF_SRIOV_CAPABILITIES_REVISION_1;

	hypervisorInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	hypervisorInfo.Header.Revision = NDIS_HYPERVISOR_INFO_REVISION_1;
	hypervisorInfo.Header.Size = NDIS_SIZEOF_HYPERVISOR_INFO_REVISION_1;
	NdisGetHypervisorInfo(&hypervisorInfo);

	if (hypervisorInfo.PartitionType == NdisHypervisorPartitionTypeMsHvParent)
	{
		DbgPrint("sriov PF\n");
		sriovCap.SriovCapabilities = NDIS_SRIOV_CAPS_SRIOV_SUPPORTED | NDIS_SRIOV_CAPS_PF_MINIPORT;
		currentSriovCap.SriovCapabilities = NDIS_SRIOV_CAPS_SRIOV_SUPPORTED | NDIS_SRIOV_CAPS_PF_MINIPORT;

		nicSwitchCap.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
		nicSwitchCap.Header.Revision = NDIS_NIC_SWITCH_CAPABILITIES_REVISION_2;
		nicSwitchCap.Header.Size = NDIS_SIZEOF_NIC_SWITCH_CAPABILITIES_REVISION_2;
		nicSwitchCap.MaxNumMacAddresses = 3;
		nicSwitchCap.MaxNumQueuePairs =12;
		nicSwitchCap.MaxNumQueuePairsPerNonDefaultVPort = 2;
		nicSwitchCap.MaxNumSwitches = 1;
		nicSwitchCap.MaxNumVFs = 2;
		nicSwitchCap.MaxNumVPorts = 3;
		//nicSwitchCap.NumMacAddressesPerPort = 1;
		//nicSwitchCap.NumTotalMacAddresses = 3;

		currentNicSwitchCap.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
		currentNicSwitchCap.Header.Revision = NDIS_NIC_SWITCH_CAPABILITIES_REVISION_2;
		currentNicSwitchCap.Header.Size = NDIS_SIZEOF_NIC_SWITCH_CAPABILITIES_REVISION_2;
		//currentNicSwitchCap.MaxNumMacAddresses = 3;
		currentNicSwitchCap.MaxNumQueuePairs = 8;
		currentNicSwitchCap.MaxNumQueuePairsPerNonDefaultVPort = 2;
		currentNicSwitchCap.MaxNumSwitches = 1;
		currentNicSwitchCap.MaxNumVFs = 2;
		currentNicSwitchCap.MaxNumVPorts = 3;
		//currentNicSwitchCap.NumMacAddressesPerPort = 1;
		//currentNicSwitchCap.NumTotalMacAddresses = 3;
		
		//miniportAttributes.HardwareAssistAttributes.HardwareNicSwitchCapabilities = &nicSwitchCap;
		//miniportAttributes.HardwareAssistAttributes.CurrentNicSwitchCapabilities = &currentNicSwitchCap;
	}
	else if (hypervisorInfo.PartitionType == NdisHypervisorPartitionMsHvChild) {
		sriovCap.SriovCapabilities = NDIS_SRIOV_CAPS_SRIOV_SUPPORTED | NDIS_SRIOV_CAPS_VF_MINIPORT;
		currentSriovCap.SriovCapabilities = NDIS_SRIOV_CAPS_SRIOV_SUPPORTED | NDIS_SRIOV_CAPS_VF_MINIPORT;
	}
	else {
		DbgPrint("not pf nor vf\n");
	}

	miniportAttributes.HardwareAssistAttributes.HardwareSriovCapabilities = &sriovCap;
	miniportAttributes.HardwareAssistAttributes.CurrentSriovCapabilities = &currentSriovCap;

	status = NdisMSetMiniportAttributes(miniportAdapterHandle, &miniportAttributes);
	if (status != NDIS_STATUS_SUCCESS)
	{
		DbgPrint("sriov config failed %x\n", status);
	}

	status = NdisMEnableVirtualization(miniportAdapterHandle, 0, FALSE, FALSE, FALSE);
	if (status != NDIS_STATUS_SUCCESS)
	{
		DbgPrint("NdisMEnableVirtualization disable failed %x\n", status);
	}
	status = NdisMEnableVirtualization(miniportAdapterHandle, 1, FALSE, FALSE, TRUE);
	//status = EnableVirtualization(miniportAdapterHandle, 1, FALSE, FALSE, TRUE);
	if (status != NDIS_STATUS_SUCCESS)
	{
		DbgPrint("NdisMEnableVirtualization enable failed %x\n", status);
	
	}
}

but NdisMEnableVirtualization always return STATUS_DEVICE_CONFIGURATION_ERROR, and Powershell shows IovEnabled=True but IovSupport=False.
I am not really sure about how to support SR-IOV according to docs of MS, can any one give me some advice.

regards,
BX

maybe need pcie acs cap https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/pcivirt/#hardware-requirements