📄 mux.h
字号:
// Adapter handle for NDIS up-calls related to this virtual miniport.
NDIS_HANDLE MiniportAdapterHandle;
// Virtual miniport's power state.
NDIS_DEVICE_POWER_STATE MPDevicePowerState;
// Has our Halt entry point been called?
BOOLEAN MiniportHalting;
// Do we need to indicate receive complete?
BOOLEAN IndicateRcvComplete;
// Do we need to indicate status complete?
BOOLEAN IndicateStatusComplete;
// Synchronization fields
BOOLEAN MiniportInitPending;
NDIS_EVENT MiniportInitEvent;
// Uncompleted Sends/Requests to the adapter below.
ULONG OutstandingSends;
// Count outstanding indications, including received
// packets, passed up to protocols on this VELAN.
ULONG OutstandingReceives;
// Packet pool for send packets
NDIS_HANDLE SendPacketPoolHandle;
// Packet pool for receive packets
NDIS_HANDLE RecvPacketPoolHandle;
// A request block that is used to forward a request presented
// to the virtual miniport, to the lower binding. Since NDIS
// serializes requests to a miniport, we only need one of these
// per VELAN.
//
MUX_NDIS_REQUEST Request;
PULONG BytesNeeded;
PULONG BytesReadOrWritten;
// Have we queued a request because the lower binding is
// at a low power state?
BOOLEAN QueuedRequest;
// Have we started to deinitialize this VELAN?
BOOLEAN DeInitializing;
// configuration
UCHAR PermanentAddress[ETH_LENGTH_OF_ADDRESS];
UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
NDIS_STRING CfgDeviceName; // used as the unique
// ID for the VELAN
ULONG VElanNumber; // logical Elan number
//
// ----- Buffer Management: Header buffers and Protocol buffers ----
//
// Some standard miniport parameters (OID values).
ULONG PacketFilter;
ULONG LookAhead;
ULONG LinkSpeed;
ULONG MaxBusySends;
ULONG MaxBusyRecvs;
// Packet counts
ULONG64 GoodTransmits;
ULONG64 GoodReceives;
ULONG NumTxSinceLastAdjust;
// Count of transmit errors
ULONG TxAbortExcessCollisions;
ULONG TxLateCollisions;
ULONG TxDmaUnderrun;
ULONG TxLostCRS;
ULONG TxOKButDeferred;
ULONG OneRetry;
ULONG MoreThanOneRetry;
ULONG TotalRetries;
ULONG TransmitFailuresOther;
// Count of receive errors
ULONG RcvCrcErrors;
ULONG RcvAlignmentErrors;
ULONG RcvResourceErrors;
ULONG RcvDmaOverrunErrors;
ULONG RcvCdtFrames;
ULONG RcvRuntErrors;
#if IEEE_VLAN_SUPPORT
ULONG RcvFormatErrors;
ULONG RcvVlanIdErrors;
#endif
ULONG RegNumTcb;
// Multicast list
MUX_MAC_ADDRESS McastAddrs[VELAN_MAX_MCAST_LIST];
ULONG McastAddrCount;
#if IEEE_VLAN_SUPPORT
ULONG VlanId;
NDIS_HANDLE BufferPoolHandle;
NPAGED_LOOKASIDE_LIST TagLookaside;
#endif
NDIS_STATUS LastIndicatedStatus;
NDIS_STATUS LatestUnIndicateStatus;
NDIS_SPIN_LOCK Lock;
PNDIS_PACKET ReceivedPackets[MAX_RECEIVE_PACKET_ARRAY_SIZE];
ULONG ReceivedPacketCount;
} VELAN, *PVELAN;
#if IEEE_VLAN_SUPPORT
#define TPID 0x0081
//
// Define tag_header structure
//
typedef struct _VLAN_TAG_HEADER
{
UCHAR TagInfo[2];
} VLAN_TAG_HEADER, *PVLAN_TAG_HEADER;
//
// Define context struct that used when the lower driver
// uses non-packet indication. It contains the original
// context, the tagging information and the tag-header
// length
//
typedef struct _MUX_RCV_CONTEXT
{
ULONG TagHeaderLen;
NDIS_PACKET_8021Q_INFO NdisPacket8021QInfo;
PVOID MacRcvContext;
}MUX_RCV_CONTEXT, *PMUX_RCV_CONTEXT;
//
// Macro definitions for VLAN support
//
#define VLAN_TAG_HEADER_SIZE 4
#define VLANID_DEFAULT 0
#define VLAN_ID_MAX 0xfff
#define VLAN_ID_MIN 0x0
#define USER_PRIORITY_MASK 0xe0
#define CANONICAL_FORMAT_ID_MASK 0x10
#define HIGH_VLAN_ID_MASK 0x0F
//
// Get information for tag headre
//
#define GET_CANONICAL_FORMAT_ID_FROM_TAG(_pTagHeader) \
((_pTagHeader)->TagInfo[0] & CANONICAL_FORMAT_ID_MASK)
#define GET_USER_PRIORITY_FROM_TAG(_pTagHeader) \
((_pTagHeader)->TagInfo[0] & USER_PRIORITY_MASK)
#define GET_VLAN_ID_FROM_TAG(_pTagHeader) \
(ULONG)(((USHORT)((_pTagHeader)->TagInfo[0] & HIGH_VLAN_ID_MASK) << 8) | (USHORT)((_pTagHeader)->TagInfo[1]))
//
// Clear the tag header struct
//
#define INITIALIZE_TAG_HEADER_TO_ZERO(_pTagHeader) \
{ \
_pTagHeader->TagInfo[0] = 0; \
_pTagHeader->TagInfo[1] = 0; \
}
//
// Set VLAN information to tag header
// Before we called all the set macro, first we need to initialize pTagHeader to be 0
//
#define SET_CANONICAL_FORMAT_ID_TO_TAG(_pTagHeader, _CanonicalFormatId) \
(_pTagHeader)->TagInfo[0] |= ((UCHAR)(_CanonicalFormatId) << 4)
#define SET_USER_PRIORITY_TO_TAG(_pTagHeader, _UserPriority) \
(_pTagHeader)->TagInfo[0] |= ((UCHAR)(_UserPriority) << 5)
#define SET_VLAN_ID_TO_TAG(_pTagHeader, _VlanId) \
{ \
(_pTagHeader)->TagInfo[0] |= (((UCHAR)((_VlanId) >> 8)) & 0x0f); \
(_pTagHeader)->TagInfo[1] |= (UCHAR)(_VlanId); \
}
//
// Copy tagging information in the indicated frame to per packet info
//
#define COPY_TAG_INFO_FROM_HEADER_TO_PACKET_INFO(_Ieee8021qInfo, _pTagHeader) \
{ \
(_Ieee8021qInfo).TagHeader.UserPriority = ((_pTagHeader->TagInfo[0] & USER_PRIORITY_MASK) >> 5); \
(_Ieee8021qInfo).TagHeader.CanonicalFormatId = ((_pTagHeader->TagInfo[0] & CANONICAL_FORMAT_ID_MASK) >> 4); \
(_Ieee8021qInfo).TagHeader.VlanId = (((USHORT)(_pTagHeader->TagInfo[0] & HIGH_VLAN_ID_MASK) << 8)| (USHORT)(_pTagHeader->TagInfo[1])); \
}
//
// Function to handle tagging on sending side
//
NDIS_STATUS
MPHandleSendTagging(
IN PVELAN pVElan,
IN PNDIS_PACKET Packet,
IN OUT PNDIS_PACKET MyPacket
);
//
// Functions to handle tagging on receiving side with packet indication
//
NDIS_STATUS
PtHandleRcvTagging(
IN PVELAN pVElan,
IN PNDIS_PACKET Packet,
IN OUT PNDIS_PACKET MyPacket,
OUT PBOOLEAN bContinue
);
#endif //IEEE_VLAN_SUPPORT
//
// Macro definitions for others.
//
//
// Is a given power state a low-power state?
//
#define MUX_IS_LOW_POWER_STATE(_PwrState) \
((_PwrState) > NdisDeviceStateD0)
#define MUX_INIT_ADAPT_RW_LOCK(_pAdapt) \
NdisInitializeReadWriteLock(&(_pAdapt)->ReadWriteLock)
#define MUX_ACQUIRE_ADAPT_READ_LOCK(_pAdapt, _pLockState) \
NdisAcquireReadWriteLock(&(_pAdapt)->ReadWriteLock, \
FALSE, \
_pLockState)
#define MUX_RELEASE_ADAPT_READ_LOCK(_pAdapt, _pLockState) \
NdisReleaseReadWriteLock(&(_pAdapt)->ReadWriteLock, \
_pLockState)
#define MUX_ACQUIRE_ADAPT_WRITE_LOCK(_pAdapt, _pLockState) \
NdisAcquireReadWriteLock(&(_pAdapt)->ReadWriteLock, \
TRUE, \
_pLockState)
#define MUX_RELEASE_ADAPT_WRITE_LOCK(_pAdapt, _pLockState) \
NdisReleaseReadWriteLock(&(_pAdapt)->ReadWriteLock, \
_pLockState)
#define MUX_INCR_PENDING_RECEIVES(_pVElan) \
NdisInterlockedIncrement((PLONG)&pVElan->OutstandingReceives)
#define MUX_DECR_PENDING_RECEIVES(_pVElan) \
NdisInterlockedDecrement((PLONG)&pVElan->OutstandingReceives)
#define MUX_INCR_PENDING_SENDS(_pVElan) \
NdisInterlockedIncrement((PLONG)&pVElan->OutstandingSends)
#define MUX_DECR_PENDING_SENDS(_pVElan) \
NdisInterlockedDecrement((PLONG)&pVElan->OutstandingSends)
#define MUX_INCR_STATISTICS(_pUlongVal) \
NdisInterlockedIncrement((PLONG)_pUlongVal)
#define MUX_INCR_STATISTICS64(_pUlong64Val) \
{ \
PLARGE_INTEGER _pLargeInt = (PLARGE_INTEGER)_pUlong64Val;\
if (NdisInterlockedIncrement((PLONG)&_pLargeInt->LowPart) == 0) \
{ \
NdisInterlockedIncrement(&_pLargeInt->HighPart); \
} \
}
#define ASSERT_AT_PASSIVE() \
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL)
//
// Simple Mutual Exclusion constructs used in preference to
// using KeXXX calls since we don't have Mutex calls in NDIS.
// These can only be called at passive IRQL.
//
typedef struct _MUX_MUTEX
{
ULONG Counter;
ULONG ModuleAndLine; // useful for debugging
} MUX_MUTEX, *PMUX_MUTEX;
#define MUX_INIT_MUTEX(_pMutex) \
{ \
(_pMutex)->Counter = 0; \
(_pMutex)->ModuleAndLine = 0; \
}
#define MUX_ACQUIRE_MUTEX(_pMutex) \
{ \
while (NdisInterlockedIncrement((PLONG)&((_pMutex)->Counter)) != 1)\
{ \
NdisInterlockedDecrement((PLONG)&((_pMutex)->Counter)); \
NdisMSleep(10000); \
} \
(_pMutex)->ModuleAndLine = (MODULE_NUMBER << 16) | __LINE__;\
}
#define MUX_RELEASE_MUTEX(_pMutex) \
{ \
(_pMutex)->ModuleAndLine = 0; \
NdisInterlockedDecrement((PLONG)&(_pMutex)->Counter); \
}
//
// Global variables
//
extern NDIS_HANDLE ProtHandle, DriverHandle;
extern NDIS_MEDIUM MediumArray[1];
extern NDIS_SPIN_LOCK GlobalLock;
extern MUX_MUTEX GlobalMutex;
extern LIST_ENTRY AdapterList;
extern ULONG NextVElanNumber;
//
// Module numbers for debugging
//
#define MODULE_MUX 'X'
#define MODULE_PROT 'P'
#define MODULE_MINI 'M'
VOID
PtQueueReceivedPacket(
IN PVELAN pVElan,
IN PNDIS_PACKET Packet,
IN BOOLEAN DoIndicate
);
VOID
PtFlushReceiveQueue(
IN PVELAN pVElan
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -