462 lines
17 KiB
C
462 lines
17 KiB
C
/*++
|
|
|
|
Copyright (c) 2005-2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
netdma.h
|
|
|
|
Abstract:
|
|
|
|
This module contains function prototypes and definitons for memory to memory DMA
|
|
providers
|
|
|
|
Author:
|
|
|
|
|
|
Revision history:
|
|
Nov 2006: Added support for a subset of IOAT V2 features (page break and descriptor ring)
|
|
Feb 2005: Original version
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
--*/
|
|
#ifndef _NET_DMA_H
|
|
#define _NET_DMA_H
|
|
|
|
#if NTDDI_VERSION >= NTDDI_VISTASP1
|
|
|
|
#undef NET_DMA_EXPORT
|
|
#if defined(NET_DMA)
|
|
#define NET_DMA_EXPORT
|
|
#else
|
|
#define NET_DMA_EXPORT DECLSPEC_IMPORT
|
|
#endif
|
|
|
|
//
|
|
// flags used in NET_DMA_DESCRIPTOR->ControlFlags
|
|
//
|
|
#define NET_DMA_INTERRUPT_ON_COMPLETION 0x00000001
|
|
#define NET_DMA_SOURCE_NO_SNOOP 0x00000002
|
|
#define NET_DMA_DESTINATION_NO_SNOOP 0x00000004
|
|
#define NET_DMA_STATUS_UPDATE_ON_COMPLETION 0x00000008
|
|
#define NET_DMA_SERIALIZE_TRANSFER 0x00000010 // fence bit
|
|
#define NET_DMA_NULL_TRANSFER 0x00000020
|
|
|
|
//
|
|
// new flags supported in NETDMA V2
|
|
//
|
|
|
|
#define NET_DMA_SOURCE_PAGE_BREAK 0x00000040
|
|
#define NET_DMA_DESTINATION_PAGE_BREAK 0x00000080
|
|
#define NET_DMA_DESTINATION_DCA_ENABLE 0x00000200
|
|
|
|
//
|
|
// flags used in NET_DMA_DESCRIPTOR->ControlFlags with NET_DMA_OP_TYPE_CONTEXT_CHANGE
|
|
//
|
|
#define NET_DMA_DCA_CONTEXT_CHANGE 0x00000001
|
|
|
|
|
|
#define NET_DMA_OP_TYPE_STANDARD_DMA 0x00000000
|
|
#define NET_DMA_OP_TYPE_CONTEXT_CHANGE 0xFF000000
|
|
|
|
|
|
//
|
|
// The low 3 bits in "Completed Descriptor Address" are used
|
|
// to indicate the status of a DMA transfer. The physical and virtual address of
|
|
// "Completed Descriptor Address" of a DMA channel are specified
|
|
// by CompletionVirtualAddress and CompletionPhysicalAddress fields of
|
|
// NET_DMA_CHANNEL_PARAMETERS at the time of allocating a DMA channel
|
|
//
|
|
#define NET_DMA_TRANSFER_STATUS_MASK 0x00000007
|
|
|
|
typedef enum _NET_DMA_TRANSFER_STATUS
|
|
{
|
|
NetDmaTransferStatusActive = 0, // 000 = Active, transfer completed successfully. This was -not- the last pending descriptor
|
|
NetDmaTransferStatusIdle = 1, // 001 = Idle, transfer completed successfully. This was the last pending descriptor
|
|
NetDmaTransferStatusSuspend = 2, // 010 = Suspend completed (no hard error). DMA channel is in Halt state
|
|
NetDmaTransferStatusHalted = 3, // 011 = Halted, operation aborted
|
|
NetDmaTransferStatusArmed = 4 // 100 = Armed, first descriptor has not yet completed and Completed Descriptor Address is not valid
|
|
} NET_DMA_TRANSFER_STATUS, *PNET_DMA_TRANSFER_STATUS;
|
|
|
|
|
|
//
|
|
// NET_DMA_DESCRIPTOR data structure is used to submit a dma transfer to DMA engine
|
|
// DMA descriptors can be chained together. Descriptor structure is modeled after
|
|
// CB DMA descriptors. DMA descriptors are aligned on 64 bit boundary
|
|
//
|
|
typedef struct _NET_DMA_DESCRIPTOR
|
|
{
|
|
union
|
|
{
|
|
ULONG TransferSize; // DMA Transfer size
|
|
// DCA context = the APIC ID of the target CPU
|
|
struct
|
|
{
|
|
ULONG DCAContext:32;
|
|
}DCAContext32;
|
|
struct
|
|
{
|
|
ULONG DCAContext:16;
|
|
ULONG Reserved:16;
|
|
}DCAContext16;
|
|
struct
|
|
{
|
|
ULONG DCAContext:8;
|
|
ULONG Reserved:24;
|
|
}DCAContext8;
|
|
};
|
|
|
|
ULONG ControlFlags; // see NET_DMA_xxx flags
|
|
PHYSICAL_ADDRESS SourceAddress; // Source physical address
|
|
PHYSICAL_ADDRESS DestinationAddress; // Destination physical address
|
|
PHYSICAL_ADDRESS NextDescriptor; // Physical address of the next descriptor in the chain
|
|
union
|
|
{
|
|
ULONG64 Reserved1; // reserved for use by DMA engine (Provider)
|
|
PHYSICAL_ADDRESS NextSourceAddress;
|
|
};
|
|
union
|
|
{
|
|
ULONG64 Reserved2; // reserved for use by DMA engine (Provider)
|
|
PHYSICAL_ADDRESS NextDestinationAddress;
|
|
};
|
|
ULONG64 UserContext1; // Used by netdma driver and/or DMA client
|
|
ULONG64 UserContext2; // Used by netdma driver and/or DMA client
|
|
} NET_DMA_DESCRIPTOR, *PNET_DMA_DESCRIPTOR;
|
|
|
|
|
|
//
|
|
// DMA Provider entry points
|
|
//
|
|
|
|
typedef struct _NET_DMA_CHANNEL_CPU_AFFINITY
|
|
{
|
|
ULONG DmaChannel;
|
|
ULONG CpuNumber;
|
|
}NET_DMA_CHANNEL_CPU_AFFINITY,*PNET_DMA_CHANNEL_CPU_AFFINITY;
|
|
|
|
//
|
|
// DMA channel CPU affinity handler. NETDMA calls this entry point to set the affinity
|
|
// policy of DMA channels
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_CHANNELS_CPU_AFFINITY_HANDLER)(
|
|
__in PVOID ProviderContext, // the Provider context passed to NetDmaRegisterProvider
|
|
__in PNET_DMA_CHANNEL_CPU_AFFINITY CpuAffinityArray, // see NET_DMA_CHANNEL_CPU_AFFINITY
|
|
__in ULONG CpuAffinityArraySize // size of CpuAffinityArray
|
|
);
|
|
|
|
|
|
//
|
|
// NET_DMA_CHANNEL_PARAMETERS is used to set up a DMA channel
|
|
// at the time of allocating the channel
|
|
//
|
|
|
|
#define NET_DMA_CHANNEL_REVISION_1 1
|
|
|
|
#define SIZEOF_NET_DMA_CHANNEL_PARAMETERS_REVISION_1 \
|
|
RTL_SIZEOF_THROUGH_FIELD(NET_DMA_CHANNEL_PARAMETERS, CpuNumber)
|
|
|
|
#if NTDDI_VERSION >= NTDDI_WIN7
|
|
|
|
#define NET_DMA_CHANNEL_REVISION_2 2
|
|
|
|
#define SIZEOF_NET_DMA_CHANNEL_PARAMETERS_REVISION_2 \
|
|
RTL_SIZEOF_THROUGH_FIELD(NET_DMA_CHANNEL_PARAMETERS, ProcessorAffinityMaskEx)
|
|
|
|
#endif
|
|
|
|
typedef struct _NET_DMA_CHANNEL_PARAMETERS
|
|
{
|
|
USHORT Revision; // Structure revision
|
|
USHORT Size; // size of this structure
|
|
ULONG Flags; // TBD
|
|
PVOID CompletionVirtualAddress; // the virtual address where the engine will write the completion status
|
|
PHYSICAL_ADDRESS CompletionPhysicalAddress; // the physical address where the engine will write the completion status
|
|
ULONG ProcessorAffinityMask; // bitmap of CPUs that this channel could be associated with (deprecated in Win7)
|
|
ULONG ChannelPriority; // per CB spec
|
|
ULONG CpuNumber; // provider will fill this with the CPU this channel is associated with
|
|
#if NTDDI_VERSION >= NTDDI_WIN7
|
|
GROUP_AFFINITY ProcessorAffinityMaskEx; // group number and bitmap of CPUs that this channel could be associated with
|
|
#endif
|
|
} NET_DMA_CHANNEL_PARAMETERS, *PNET_DMA_CHANNEL_PARAMETERS;
|
|
|
|
//
|
|
// DMA channel Allocate handler. NETDMA calls this entry point to allocate a DMA channel
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_CHANNEL_ALLOCATE_HANDLER)(
|
|
__in PVOID ProviderContext, // the Provider context passed to NetDmaRegisterProvider
|
|
__in PNET_DMA_CHANNEL_PARAMETERS ChannelParameters, // see NET_DMA_CHANNEL_PARAMETERS
|
|
__in PVOID NetDmaChannelHandle, // NETDMA handle for this channel. used by all calls from Provider to NETDMA regarding this channel
|
|
__deref_out PVOID * pProviderChannelContext // on return holds Provider context for this channel. used in all calls from NETDMA to provider regarding this channel
|
|
);
|
|
|
|
//
|
|
// NETDMA calls this entry point to free a DMA channel. When NETDMA calls this
|
|
// entry points, there are no outstanding DMA operations on this channel. Once
|
|
// NETDMA makes this call, it can not call the provider for any operation on the
|
|
// channel
|
|
//
|
|
|
|
typedef
|
|
VOID
|
|
(*DMA_CHANNEL_FREE_HANDLER)(
|
|
__in PVOID ProviderChannelContext // Provider context for this channel (retuned from DMA_CHANNEL_ALLOCATE_HANDLER in pProviderChannelContext)
|
|
);
|
|
|
|
//
|
|
// NETDMA calls this entry point to start a DMA transfer
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_START_HANDLER)(
|
|
__in PVOID ProviderChannelContext, // Provider context for this channel
|
|
__in PNET_DMA_DESCRIPTOR DescriptorVirtualAddress, // pointer to the virtual address of the first descriptor
|
|
__in PHYSICAL_ADDRESS DescriptorPhysicalAddress, // pointer to the physical address of the first descriptor
|
|
__in ULONG DescriptorCount // number of descriptors
|
|
);
|
|
|
|
//
|
|
// NETDMA calls this entry point to suspend the DMA transfers
|
|
// currently in progress. The provider will return the
|
|
// physical address of the last DMA descriptor that it processed
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_SUSPEND_HANDLER)(
|
|
__in PVOID ProviderChannelContext, // Provider context for this channel
|
|
__deref_out PPHYSICAL_ADDRESS* pLastDescriptor // the physical address of the last processed descriptor
|
|
);
|
|
|
|
//
|
|
// NETDMA calls this entry point to resume DMA operations on
|
|
// a suspended DMA channel
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_RESUME_HANDLER)(
|
|
__in PVOID ProviderChannelContext // Provider context for this channel
|
|
);
|
|
|
|
//
|
|
// NETDMA calls this entry point to abort all DMA transfers
|
|
// that have been scheduled on a DMA channel
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_ABORT_HANDLER)(
|
|
__in PVOID ProviderChannelContext // Provider context for this channel
|
|
);
|
|
|
|
//
|
|
// NETDMA calls this entry point to append a chain of DMA descriptors
|
|
// to the last descriptor on a DMA channel
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_APPEND_HANDLER)(
|
|
__in PVOID ProviderChannelContext, // Provider context for this channel
|
|
__in PNET_DMA_DESCRIPTOR DescriptorVirtualAddress, // pointer to the virtual address of the first descriptor to append
|
|
__in PHYSICAL_ADDRESS DescriptorPhysicalAddress, // pointer to the physical address of the first descriptor to append
|
|
__in ULONG DescriptorCount // number of descriptors
|
|
);
|
|
|
|
//
|
|
// TBD:
|
|
//
|
|
typedef
|
|
NTSTATUS
|
|
(*DMA_RESET_HANDLER)(
|
|
__in PVOID ProviderChannelContext
|
|
);
|
|
|
|
|
|
//
|
|
// DMA providers use NET_DMA_PROVIDER_CHARACTERISTICS structure in the call to
|
|
// NetDmaRegisterProvider
|
|
//
|
|
#define NET_DMA_PROVIDER_REVISION_1 1
|
|
#define NET_DMA_PROVIDER_REVISION_2 2
|
|
|
|
//
|
|
// Flags for use in the NET_DMA_PROVIDER_CHARACTERISTICS structure
|
|
//
|
|
#define NET_DMA_PROVIDER_CHARACTERISTICS_DCA_SUPPORTED 0x00000001
|
|
|
|
#if NTDDI_VERSION >= NTDDI_WIN7
|
|
#define NET_DMA_PROVIDER_SUPPORTS_PROC_GROUPS 0x00000002
|
|
#endif
|
|
|
|
//
|
|
// For back-compat with Vista headers
|
|
//
|
|
#if NTDDI_VERSION < NTDDI_WIN7
|
|
#define NET_DMA_PROVIDER_ATTRIBUTES_DCA_SUPPORTED NET_DMA_PROVIDER_CHARACTERISTICS_DCA_SUPPORTED
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct _NET_DMA_PROVIDER_CHARACTERISTICS
|
|
{
|
|
UCHAR MajorVersion; // Major version of the DMA provider
|
|
UCHAR MinorVersion; // Minor version of the DMA provider
|
|
USHORT Size; // the size of this structure
|
|
ULONG Flags; // Possible values listed below
|
|
PDEVICE_OBJECT PhysicalDeviceObject; // The physical device object PnP associates with this device
|
|
ULONG MaxDmaChannelCount; // Maximum number of DMA channels
|
|
DMA_CHANNELS_CPU_AFFINITY_HANDLER SetDmaChannelCpuAffinity; // Set channel CPU affinity handler
|
|
DMA_CHANNEL_ALLOCATE_HANDLER AllocateDmaChannel; // Allocate DMA channel handler
|
|
DMA_CHANNEL_FREE_HANDLER FreeDmaChannel; // Free DMA channel handler
|
|
DMA_START_HANDLER StartDma; // Start DMA handler
|
|
DMA_SUSPEND_HANDLER SuspendDma; // Suspend DMA handler
|
|
DMA_RESUME_HANDLER ResumeDma; // Resume DMA handler
|
|
DMA_ABORT_HANDLER AbortDma; // Abort DMA handler
|
|
DMA_APPEND_HANDLER AppendDma; // Append DMA handler
|
|
DMA_RESET_HANDLER ResetChannel; // Reset channel handler
|
|
UNICODE_STRING FriendlyName; // Provider's friendly name
|
|
} NET_DMA_PROVIDER_CHARACTERISTICS, *PNET_DMA_PROVIDER_CHARACTERISTICS;
|
|
|
|
//
|
|
// DMA providers call NetDmaRegisterProvider to register an instance of a
|
|
// DMA provider. An instance of a DMA provider is associated with a device
|
|
// (DMA engine). Providers usually make this call in their AddDevice entry point.
|
|
// Note: the reason that the call has to be made during AddDevice and not
|
|
// START IRP is because allocating MSI-X resources has to be done in
|
|
// FILTER_RESOURCE_REQUIREMENTS that is sent to the device drivers before
|
|
// the START IRP
|
|
//
|
|
__drv_requiresIRQL(PASSIVE_LEVEL)
|
|
NET_DMA_EXPORT
|
|
NTSTATUS
|
|
NetDmaRegisterProvider(
|
|
__in PVOID ProviderContext, // Provider context for this device
|
|
__in PVOID * pNetDmaProviderHandle, // upon return, this will hold NETDMA handle for this device
|
|
__in PNET_DMA_PROVIDER_CHARACTERISTICS ProviderCharacteristics // provider's characteristics
|
|
);
|
|
|
|
//
|
|
// DMA providers call NetDmaDeregisterProvider to deregister a provider
|
|
// that was previously registered by a call to NetDmaRegisterProvider
|
|
// the call is usually made while handling REMOVE IRP.
|
|
//
|
|
__drv_requiresIRQL(PASSIVE_LEVEL)
|
|
NET_DMA_EXPORT
|
|
VOID
|
|
NetDmaDeregisterProvider(
|
|
__in PVOID NetDmaProviderHandle // Handle obtained by the call to NetDmaRegisterProvider
|
|
);
|
|
|
|
//
|
|
// DMA providers use this structure in the call to NetDmaProviderStart
|
|
//
|
|
|
|
typedef struct _NET_DMA_PROVIDER_ATTRIBUTES
|
|
{
|
|
UCHAR MajorHwVersion; // Major version of the DMA provider
|
|
UCHAR MinorHwVersion; // Minor version of the DMA provider
|
|
USHORT Size; // the size of this structure
|
|
ULONG Flags; // TBD
|
|
ULONG VendorId; // vendor ID
|
|
ULONG DmaChannelCount; // number of DMA channels
|
|
ULONG MaximumTransferSize; // Maximum DMA transfer size (minimum of 4K)
|
|
PHYSICAL_ADDRESS MaximumAddressSpace; // Maximum physical adddress that can be addressed by this device
|
|
} NET_DMA_PROVIDER_ATTRIBUTES, *PNET_DMA_PROVIDER_ATTRIBUTES;
|
|
|
|
//
|
|
// DMA providers call NetDmaProviderStart to notify NETDMA that all the DMA channels
|
|
// on a provider are initialized and ready to be used. DMA providers call this API in the
|
|
// context of handling START IRP.
|
|
//
|
|
NET_DMA_EXPORT
|
|
VOID
|
|
NetDmaProviderStart(
|
|
__in PVOID NetDmaProviderHandle, // Handle obtained by the call to NetDmaRegisterProvider
|
|
__in PNET_DMA_PROVIDER_ATTRIBUTES ProviderAttributes // the provider's device attributes
|
|
);
|
|
|
|
//
|
|
// DMA providers call NetDmaProviderStop to notify NETDMA that a previously started
|
|
// DMA engine is no longer available.
|
|
// DMA providers call this API in the context of handling REMOVE or STOP IRP. NETDMA will wait
|
|
// for outstanding DMA operations to complete and frees all the DMA channels
|
|
// before returning back from this API
|
|
//
|
|
NET_DMA_EXPORT
|
|
VOID
|
|
NetDmaProviderStop(
|
|
__in PVOID NetDmaProviderHandle // Handle obtained by the call to NetDmaRegisterProvider
|
|
);
|
|
|
|
//
|
|
// DMA providers call NetDmaIsr in their ISR handler
|
|
//
|
|
NET_DMA_EXPORT
|
|
VOID
|
|
NetDmaIsr(
|
|
__in PVOID NetDmaChannelHandle,
|
|
__in PHYSICAL_ADDRESS DmaDescriptor,
|
|
__out PULONG pCpuNumber
|
|
);
|
|
|
|
//
|
|
// DMA providers call NetDmaInterruptDpc in their interrupt DPC handler
|
|
//
|
|
NET_DMA_EXPORT
|
|
VOID
|
|
NetDmaInterruptDpc(
|
|
__in PVOID NetDmaChannelHandle, // DMA channel
|
|
__in_opt PHYSICAL_ADDRESS DmaDescriptor // optional if this is called for reasons other DMA completion
|
|
);
|
|
|
|
|
|
NET_DMA_EXPORT
|
|
UINT
|
|
NetDmaGetVersion(
|
|
VOID
|
|
);
|
|
|
|
|
|
typedef enum _NET_DMA_PNP_NOTIFICATION_CODE
|
|
{
|
|
NetDmaNotificationProviderRegistered = 1, // a provider has registered. not used by providers
|
|
NetDmaNotificationProviderArrival, // a provider is ready for use. not used by providers
|
|
NetDmaNotificationProviderRemoval, // a provider is about to be removed. not used by providers
|
|
NetDmaNotificationChannelArrival, // a DMA channel has become available. not used by providers
|
|
NetDmaNotificationProviderPowerDown, // the DMA provider is going to D3.
|
|
NetDmaNotificationProviderPowerUp, // the DMA provider is back to D0
|
|
NetDmaNotificationMax
|
|
}NET_DMA_PNP_NOTIFICATION_CODE, *PNET_DMA_PNP_NOTIFICATION_CODE;
|
|
|
|
#define NET_DMA_PNP_NOTIFICATION_REVISION_1 1
|
|
|
|
typedef struct _NET_DMA_PNP_NOTIFICATION
|
|
{
|
|
ULONG StructureRevision;
|
|
ULONG StructureSize;
|
|
NET_DMA_PNP_NOTIFICATION_CODE NotificationCode;
|
|
PVOID Buffer;
|
|
ULONG BufferLength;
|
|
}NET_DMA_PNP_NOTIFICATION, *PNET_DMA_PNP_NOTIFICATION;
|
|
|
|
//
|
|
// this API is available to Providers version 1.1 and above
|
|
//
|
|
NET_DMA_EXPORT
|
|
VOID
|
|
NetDmaPnPEventNotify(
|
|
__in PVOID NetDmaProviderHandle, // Provider handle
|
|
__in PNET_DMA_PNP_NOTIFICATION PnPEvent // PnP and Power Management event
|
|
);
|
|
|
|
#endif // NTDDI_VISTASP1
|
|
|
|
#endif //_NET_DMA_H
|
|
|
|
|