3842 lines
96 KiB
C
3842 lines
96 KiB
C
// Copyright (c) 1998-1999, Microsoft Corporation, all rights reserved
|
|
//
|
|
// priv.h
|
|
//
|
|
// IEEE 1394 NDIS mini-port/call-manager driver
|
|
//
|
|
// Main private header
|
|
//
|
|
// 12/28/1998 JosephJ Created (adapted from the l2tp project)
|
|
//
|
|
//
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constants
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
extern ULONG g_IsochTag;
|
|
extern LONG g_ulMedium;
|
|
extern ULONGLONG g_ullOne;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Advance Declarations and simple typedefs
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Forward declarations.
|
|
//
|
|
typedef union _VCCB VCCB;
|
|
typedef struct _ADAPTERCB ADAPTERCB, *PADAPTERCB;
|
|
typedef struct _RECVFIFO_VCCB RECVFIFO_VCCB, *PRECVFIFO_VCCB;
|
|
typedef struct _ETHERNET_VCCB ETHERNET_VCCB, *PETHERNET_VCCB;
|
|
typedef struct _RECV_FIFO_DATA RECV_FIFO_DATA, *PRECV_FIFO_DATA;
|
|
typedef struct _ISOCH_DESCRIPTOR ISOCH_DESCRIPTOR, *PISOCH_DESCRIPTOR, **PPISOCH_DESCRIPTOR;
|
|
typedef struct _TOPOLOGY_MAP TOPOLOGY_MAP, *PTOPOLOGY_MAP, **PPTOPOLOGY_MAP;
|
|
typedef struct _CHANNEL_VCCB CHANNEL_VCCB, *PCHANNEL_VCCB;
|
|
typedef struct _GASP_HEADER GASP_HEADER;
|
|
typedef struct _NDIS1394_FRAGMENT_HEADER NDIS1394_FRAGMENT_HEADER, *PNDIS1394_FRAGMENT_HEADER;
|
|
typedef struct _NDIS1394_REASSEMBLY_STRUCTURE NDIS1394_REASSEMBLY_STRUCTURE, *PNDIS1394_REASSEMBLY_STRUCTURE;
|
|
typedef struct _REMOTE_NODE REMOTE_NODE, *PREMOTE_NODE;
|
|
typedef union _NDIS1394_UNFRAGMENTED_HEADER NDIS1394_UNFRAGMENTED_HEADER, *PNDIS1394_UNFRAGMENTED_HEADER;
|
|
typedef union _NIC_WORK_ITEM NIC_WORK_ITEM, *PNIC_WORK_ITEM;
|
|
|
|
|
|
#define NIC1394_STATUS_INVALID_GENERATION ((NDIS_STATUS)STATUS_INVALID_GENERATION)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Data types
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
typedef struct _NODE_TABLE
|
|
{
|
|
PREMOTE_NODE RemoteNode[MAX_NUMBER_NODES];
|
|
|
|
} NODE_TABLE, *PNODE_TABLE;
|
|
|
|
|
|
|
|
typedef struct _GASP_HEADER
|
|
{
|
|
union
|
|
{
|
|
//
|
|
// Ist Quadlet
|
|
//
|
|
struct
|
|
{
|
|
ULONG GH_Specifier_ID_Hi:16;
|
|
ULONG GH_Source_ID:16;
|
|
|
|
} Bitmap;
|
|
|
|
struct
|
|
{
|
|
USHORT GH_Specifier_ID_Hi;
|
|
USHORT GH_Source_ID;
|
|
|
|
} u;
|
|
|
|
struct
|
|
{
|
|
USHORT GH_Specifier_ID_Hi;
|
|
NODE_ADDRESS GH_NodeAddress;
|
|
} u1;
|
|
|
|
ULONG GaspHeaderHigh;
|
|
|
|
} FirstQuadlet;
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
ULONG GH_Version:24; // Bits 0-23
|
|
ULONG GH_Specifier_ID_Lo:8; //Bits 24-31
|
|
|
|
} Bitmap;
|
|
|
|
ULONG GaspHeaderLow;
|
|
|
|
} SecondQuadlet;
|
|
|
|
} GASP_HEADER, *PGASP_HEADER;
|
|
|
|
|
|
//
|
|
// The Ndis miniport's wrapper around the Packet Pool
|
|
//
|
|
typedef struct _NIC_PACKET_POOL
|
|
{
|
|
ULONG AllocatedPackets;
|
|
|
|
KSPIN_LOCK Lock; // Only in Win9X.
|
|
|
|
NDIS_HANDLE Handle;
|
|
|
|
|
|
} NIC_PACKET_POOL, *PNIC_PACKET_POOL;
|
|
|
|
|
|
//
|
|
// The Ndis miniport's wrapper around the Packet Pool
|
|
//
|
|
typedef struct _NIC_BUFFER_POOL
|
|
{
|
|
ULONG AllocatedBuffers;
|
|
|
|
KSPIN_LOCK Lock; // Only in Win9X.
|
|
|
|
NDIS_HANDLE Handle;
|
|
|
|
|
|
} NIC_BUFFER_POOL, *PNIC_BUFFER_POOL;
|
|
|
|
|
|
|
|
//
|
|
// The structure that defines the lookaside list used by this miniport
|
|
//
|
|
typedef struct _NIC_NPAGED_LOOKASIDE_LIST
|
|
{
|
|
//
|
|
// The lookaside list structure
|
|
//
|
|
NPAGED_LOOKASIDE_LIST List;
|
|
|
|
//
|
|
// The size of an individual buffer
|
|
//
|
|
|
|
ULONG Size;
|
|
|
|
//
|
|
// Outstanding Fragments - Interlocked access only
|
|
//
|
|
ULONG OutstandingPackets;
|
|
|
|
//
|
|
// Lookaside Lists are used for sends. So this is a maximum
|
|
// send packet size that this lookaside list can handle
|
|
//
|
|
ULONG MaxSendSize;
|
|
|
|
} NIC_NPAGED_LOOKASIDE_LIST , *PNIC_NPAGED_LOOKASIDE_LIST ;
|
|
|
|
|
|
|
|
//
|
|
// Structure used for references, Adapted from Ndis
|
|
// The Event will be signalled when the refcount goes down to zero
|
|
// The filed closing signifies that the object that the reference belongs to is
|
|
// closing and it;s refernces will not be incremented anymore
|
|
//
|
|
typedef struct _REF
|
|
{
|
|
// NDIS_SPIN_LOCK SpinLock;
|
|
ULONG ReferenceCount;
|
|
BOOLEAN Closing;
|
|
NDIS_EVENT RefZeroEvent;
|
|
} REF, * PREF;
|
|
|
|
typedef enum _EVENT_CODE
|
|
{
|
|
Nic1394EventCode_InvalidEventCode,
|
|
Nic1394EventCode_NewNodeArrived,
|
|
nic1394EventCode_BusReset,
|
|
nic1394EventCode_FreedAddressRange,
|
|
nic1394EventCode_ReassemblyTimerComplete,
|
|
nic1394EventCode_QueryPowerLowPower
|
|
|
|
|
|
} EVENT_CODE, *PEVENT_CODE;
|
|
|
|
typedef struct _NIC1394_EVENT
|
|
{
|
|
NDIS_EVENT NdisEvent;
|
|
EVENT_CODE EventCode;
|
|
|
|
} NIC1394_EVENT, *PNIC1394_EVENT;
|
|
|
|
|
|
typedef ENetAddr MAC_ADDRESS, *PMAC_ADDRESS;
|
|
|
|
|
|
//
|
|
// nic Spin lock structure. Keeps track of the file and line numer
|
|
// that last touched the lock
|
|
//
|
|
|
|
|
|
#define LOCK_FILE_NAME_LEN 48
|
|
|
|
|
|
typedef struct _NIC_SPIN_LOCK
|
|
{
|
|
#ifdef TRACK_LOCKS
|
|
ULONG IsAcquired; // Internal tracking of lock state
|
|
PKTHREAD OwnerThread; // thread that has the lock
|
|
UCHAR TouchedByFileName[LOCK_FILE_NAME_LEN]; // File name which called Acquire Lock
|
|
ULONG TouchedInLineNumber; // Line Number in the file
|
|
#endif
|
|
|
|
NDIS_SPIN_LOCK NdisLock; // Actual Lock
|
|
|
|
} NIC_SPIN_LOCK, *PNIC_SPIN_LOCK;
|
|
|
|
//
|
|
// Statistics Structure - to be collected on a per adapter basis
|
|
//
|
|
typedef struct _NIC_SEND_RECV_STATS
|
|
{
|
|
ULONG ulSendNicSucess;
|
|
ULONG ulSendBusSuccess;
|
|
ULONG ulSendBusFail;
|
|
ULONG ulSendNicFail;
|
|
ULONG ulRecv;
|
|
|
|
|
|
} NIC_SEND_RECV_STATS;
|
|
|
|
|
|
//
|
|
// These are stats that can be reset
|
|
//
|
|
typedef struct _RESETTABLE_STATS
|
|
{
|
|
ULONG ulNumOutstandingReassemblies;
|
|
ULONG ulMaxOutstandingReassemblies;
|
|
ULONG ulAbortedReassemblies;
|
|
ULONG ulNumResetsIssued ;
|
|
ULONG ulNumSends;
|
|
ULONG ulNumSendsCompleted;
|
|
ULONG ulNumBusSends;
|
|
ULONG ulNumBusSendsCompleted;
|
|
NIC_SEND_RECV_STATS Fifo;
|
|
NIC_SEND_RECV_STATS Channel;
|
|
|
|
|
|
} RESETTABLE_STATS, *PRESETTABLE_STATS;
|
|
|
|
typedef struct _ADAPT_STATS
|
|
{
|
|
ULONG ulXmitOk;
|
|
ULONG ulXmitError ;
|
|
ULONG ulRcvOk ;
|
|
ULONG ulRcvError ;
|
|
ULONG ulNumResetsIssued ;
|
|
ULONG ulNumResetCallbacks ;
|
|
ULONG ulBCMIterations ;
|
|
ULONG ulNumRemoteNodes;
|
|
ULONG ulResetTime;
|
|
RESETTABLE_STATS TempStats;
|
|
|
|
} ADAPT_STATS, *PADAPT_STATS;
|
|
|
|
//
|
|
// Can be used to keep data in buckets of 10
|
|
//
|
|
|
|
|
|
typedef struct _STAT_BUCKET
|
|
{
|
|
|
|
ULONG Bucket[16];
|
|
|
|
|
|
} STAT_BUCKET, *PSTAT_BUCKET;
|
|
|
|
//
|
|
// Wrapper around the Address Fifo structure
|
|
//
|
|
typedef struct _ADDRESS_FIFO_WRAPPER
|
|
{
|
|
ADDRESS_FIFO Fifo;
|
|
ULONG Tag;
|
|
|
|
|
|
}ADDRESS_FIFO_WRAPPER, *PADDRESS_FIFO_WRAPPER;
|
|
|
|
|
|
//
|
|
// To be used on Win9x To serialize send and receives
|
|
//
|
|
|
|
typedef struct _NIC_SERIALIZATION
|
|
{
|
|
UINT PktsInQueue; // Number of packets in queue.
|
|
BOOLEAN bTimerAlreadySet;
|
|
BOOLEAN bInitialized;
|
|
USHORT usPad;
|
|
LIST_ENTRY Queue; // Serialized by adapter lock.
|
|
|
|
union {
|
|
NDIS_MINIPORT_TIMER Timer;
|
|
NDIS_WORK_ITEM WorkItem;
|
|
};
|
|
|
|
NIC1394_EVENT CompleteEvent;
|
|
|
|
} NIC_SERIALIZATION, *PNIC_SERIALIZATION;
|
|
|
|
|
|
|
|
//
|
|
// Each request to allocate and address range
|
|
// returns certain values that need to be stored for the
|
|
// request to free the address range. This structure contains
|
|
// those values
|
|
//
|
|
|
|
typedef struct _ADDRESS_RANGE_CONTEXT
|
|
{
|
|
|
|
//
|
|
// Handle returned by the bus driver
|
|
//
|
|
HANDLE hAddressRange;
|
|
|
|
//
|
|
// Address Range returnded by the bus driver
|
|
//
|
|
ADDRESS_RANGE AddressRange;
|
|
|
|
//
|
|
// Number of Address returned from the call to
|
|
// allocate address range
|
|
//
|
|
ULONG AddressesReturned;
|
|
|
|
//
|
|
// Mdl used in allocate address range . can be NULL
|
|
//
|
|
PMDL pMdl;
|
|
|
|
} ADDRESS_RANGE_CONTEXT, *PADDRESS_RANGE_CONTEXT;
|
|
|
|
|
|
|
|
// This structure is the Per Pdo/ per RecvFIFOVc structure.
|
|
// This will be included in every Pdo Strcuture. And should contain
|
|
// the fields that are related to the recvFifo and the Pdo block
|
|
//
|
|
typedef struct _RECV_FIFO_DATA
|
|
{
|
|
//
|
|
// Indicates whether the address range was allocated regardless of the Make
|
|
// Call State (pending or success)
|
|
//
|
|
BOOLEAN AllocatedAddressRange;
|
|
|
|
//
|
|
// Recv Vc's related data structures
|
|
//
|
|
ADDRESS_RANGE VcAddressRange;
|
|
|
|
// The Bus Driver's Handle to the Address ranges that
|
|
// the Nic was allocated
|
|
//
|
|
HANDLE hAddressRange;
|
|
|
|
// This is the number of address ranges that the bus driver
|
|
// returned. For now, it is expected to be one.
|
|
//
|
|
UINT AddressesReturned;
|
|
|
|
// The Recv Fifo Vc that this structure is associated with
|
|
//
|
|
PRECVFIFO_VCCB pRecvFIFOVc;
|
|
|
|
// The Pdo Associated with this structure
|
|
//
|
|
//DEVICE_OBJECT *pPdo;
|
|
|
|
} RECV_FIFO_DATA, *PRECV_FIFO_DATA;
|
|
|
|
|
|
//
|
|
// Flags for the Broadcast Channel
|
|
//
|
|
#define BCR_LocalHostIsIRM 0x00000001
|
|
#define BCR_ChannelAllocated 0x00000002
|
|
#define BCR_LocalHostBCRUpdated 0x00000004
|
|
#define BCR_MakeCallPending 0x00000008
|
|
#define BCR_Initialized 0x00000010
|
|
#define BCR_BCMFailed 0x00000020 // Informational purposes only . Do not Test or REad
|
|
#define BCR_InformingRemoteNodes 0x00000040
|
|
#define BCR_BCMInProgress 0x00000100
|
|
#define BCR_LastNodeRemoved 0x00000200
|
|
#define BCR_Freed 0x00000400
|
|
#define BCR_BCRNeedsToBeFreed 0x00000800
|
|
#define BCR_NewNodeArrived 0x00001000
|
|
#define BCR_NoNodesPresent 0x00002000
|
|
|
|
//
|
|
// This is information useful in maintaining the BCR
|
|
// Broadcast Channels Register.
|
|
//
|
|
|
|
|
|
typedef struct _BROADCAST_CHANNEL_DATA
|
|
{
|
|
|
|
//
|
|
// Flags
|
|
//
|
|
ULONG Flags;
|
|
|
|
//
|
|
// IRM;s BCR. This is the actual record of the bus's IRM. And is meant to indicate the current state
|
|
//
|
|
NETWORK_CHANNELSR IRM_BCR;
|
|
|
|
|
|
//
|
|
// Broadcast Channels Register for the local host. This is the one a remote node will write to and read from
|
|
// pLocalBcRMdl points to this structure . This is Byteswapped to reppresent the BigEndian 1394 Bus Format
|
|
//
|
|
ULONG LocalHostBCRBigEndian;
|
|
|
|
|
|
//
|
|
// Mdl pointing to Local Host BCR. Other machines will write to this MDL.
|
|
//
|
|
PMDL pLocalBCRMdl;
|
|
|
|
|
|
//
|
|
// Data pointed to by the pRemoteBCRMdl and will copied to IRM_BCR. The data that will be read will
|
|
// be in the BigEndian format Pointed to by RemoteBCRMDl
|
|
//
|
|
ULONG RemoteBCRMdlData;
|
|
|
|
//
|
|
// MDL pointing to Remote Nodes' BCR. This will be used in reading other machine's
|
|
// BCR. This points to the RemoteBCRMdlData
|
|
//
|
|
|
|
PMDL pRemoteBCRMdl;
|
|
|
|
//
|
|
// Make a copy of the BCR that is used in informing other nodes
|
|
// about this node's BCR when the local node is the IRM
|
|
//
|
|
ULONG AsyncWriteBCRBigEndian;
|
|
|
|
PMDL pAsyncWriteBCRMdl;
|
|
|
|
|
|
//
|
|
// Local Node Address. This changes from Reset to Reset
|
|
//
|
|
NODE_ADDRESS LocalNodeAddress;
|
|
|
|
|
|
ULONG LocalNodeNumber;
|
|
|
|
//
|
|
// Address Range Context needed for Broadcast Channels
|
|
// Register
|
|
//
|
|
ADDRESS_RANGE_CONTEXT AddressRangeContext;
|
|
|
|
//
|
|
// Topology Buffer
|
|
//
|
|
PTOPOLOGY_MAP pTopologyMap;
|
|
|
|
//
|
|
// Event that the Make call will pend on for completion of the BCM
|
|
//
|
|
NIC1394_EVENT MakeCallWaitEvent;
|
|
|
|
//
|
|
// BoadcastChannelVc
|
|
//
|
|
PCHANNEL_VCCB pBroadcastChanneVc;
|
|
|
|
//
|
|
// Locally Allocated Channel Num. Is only valid when the
|
|
//
|
|
ULONG LocallyAllocatedChannel;
|
|
|
|
//
|
|
// The Generation at which the IRM was set. This can then be used to check the
|
|
// validity of the IRM
|
|
|
|
ULONG IrmGeneration;
|
|
|
|
//
|
|
// Event To specify that a new node has come in and waiting threads can continue
|
|
//
|
|
NIC1394_EVENT BCRWaitForNewRemoteNode;
|
|
|
|
//
|
|
// Event to synchronize the shutting down of the adapter and freeing the address range
|
|
//
|
|
NIC1394_EVENT BCRFreeAddressRange;
|
|
|
|
} BROADCAST_CHANNEL_DATA, *PBROADCAST_CHANNEL_DATA;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Flags for the PDO Control Block
|
|
//
|
|
#define PDO_NotValid 0x00000001
|
|
#define PDO_Activated 0x00000002
|
|
#define PDO_Removed 0x00000004
|
|
#define PDO_BeingRemoved 0x00000008
|
|
#define PDO_AllocateAddressRangeFailure 0x00000010
|
|
#define PDO_AllocateAddressRangeSucceeded 0x00000020
|
|
#define PDO_AddressRangeFreed 0x00000040
|
|
#define PDO_AllocateAddressRangeFlags 0x000000F0
|
|
#define PDO_ResetRegistered 0x00000100
|
|
#define PDO_NotInsertedInTable 0x00000200 // Informational purposes
|
|
|
|
|
|
typedef struct
|
|
_REMOTE_NODE
|
|
{
|
|
// The Tag should MTAG_REMOTE_NODE
|
|
//
|
|
|
|
ULONG ulTag;
|
|
|
|
//
|
|
// The Vurrent Node Address
|
|
//
|
|
NODE_ADDRESS RemoteAddress;
|
|
|
|
//
|
|
// Ushort Gap
|
|
//
|
|
USHORT Gap;
|
|
|
|
// The PDO itself
|
|
//
|
|
|
|
PDEVICE_OBJECT pPdo;
|
|
|
|
// This is the pointer to the next field in the PDO
|
|
//
|
|
LIST_ENTRY linkPdo;
|
|
|
|
// 64 bit Unique Id associated with a 1394 Node
|
|
//
|
|
UINT64 UniqueId;
|
|
|
|
//
|
|
// Enum1394 handle for the node
|
|
//
|
|
PVOID Enum1394NodeHandle;
|
|
|
|
|
|
// flags can be one of the following. Essentially marks the PDO as
|
|
// good or bad
|
|
//
|
|
ULONG ulFlags;
|
|
|
|
// Back link to the Adapter that PDO hangs off
|
|
//
|
|
PADAPTERCB pAdapter;
|
|
|
|
// The refcount associated with the Pdo
|
|
//
|
|
REF Ref;
|
|
|
|
// This is the linked list of VCs, that are using the Pdo to preform
|
|
//
|
|
LIST_ENTRY VcList;
|
|
|
|
// All the fields that are related to the Recv Fifo are present in this
|
|
// structure
|
|
//
|
|
RECV_FIFO_DATA RecvFIFOData;
|
|
|
|
//
|
|
// Lock to synchronize all the reassembly operations in the Node
|
|
//
|
|
NIC_SPIN_LOCK ReassemblyLock;
|
|
|
|
//
|
|
// Linked list of Reassembly Structure
|
|
//
|
|
LIST_ENTRY ReassemblyList;
|
|
|
|
// This structure maintains cached information about the remote node.
|
|
//
|
|
struct
|
|
{
|
|
UINT SpeedTo; // From GetMaxSpeedBetweenNodes.
|
|
UINT MaxRec; // From the node's config ROM.
|
|
UINT EffectiveMaxBufferSize; // Computed from the SpeedTo, MaxRec,
|
|
// and local speed.
|
|
|
|
} CachedCaps;
|
|
|
|
//
|
|
// Ethernet Address - to be used by the bridge to recognize packets
|
|
// originating from this node. An MD5 Signature of the Euid
|
|
//
|
|
ENetAddr ENetAddress;
|
|
}
|
|
REMOTE_NODE, *PREMOTE_NODE, **PPREMOTE_NODE;
|
|
|
|
//
|
|
// These flags are common to the Adapter
|
|
//
|
|
|
|
//
|
|
//fADAPTER_IndicatedMediaDisonnect - indicateds that the miniport has already
|
|
// called NdisMIndicateStatus
|
|
//
|
|
|
|
#define fADAPTER_Halting 0x00000001
|
|
#define fADAPTER_RegisteredWithEnumerator 0x00000002
|
|
#define fADAPTER_FailedRegisteration 0x00000004
|
|
#define fADAPTER_IndicatedMediaDisonnect 0x00000008
|
|
#define fADAPTER_InvalidGenerationCount 0x00000010
|
|
//#define fADAPTER_BCMWorkItem 0x00000020
|
|
#define fADAPTER_RegisteredAF 0x00000040
|
|
#define fADAPTER_Reset10Sec 0x00000080
|
|
#define fADAPTER_FailedInit 0x00000100
|
|
#define fADAPTER_VDOInactive 0x00000200
|
|
#define fADAPTER_FreedRcvTimers 0x00001000 // debugging purposes
|
|
#define fADAPTER_FreedTimers 0x00002000 // debugging purposes
|
|
#define fADAPTER_DeletedLookasideLists 0x00004000 // debugging purposes
|
|
#define fADAPTER_UpdateNodeTable 0x00008000 // set if no remote node for reassembly
|
|
#define fADAPTER_DoStatusIndications 0x00010000 // if set, call NdisMIndicateStatus
|
|
#define fADAPTER_DeletedWorkItems 0x00100000 // debugging purposes
|
|
#define fADAPTER_NoMoreReassembly 0x00200000
|
|
#define fADAPTER_RemoteNodeInThisBoot 0x00400000 //was a remote node in this boot
|
|
#define fADAPTER_BridgeMode 0x00800000 // is the Adapter in bridge mode
|
|
#define fADAPTER_LowPowerState 0x01000000 // adapter is in low power state
|
|
|
|
// Adapter control block defining the state of a single L2TP mini-port
|
|
// adapter. An adapter commonly supports multiple VPN devices. Adapter
|
|
// blocks are allocated in MiniportInitialize and deallocated in MiniportHalt.
|
|
//
|
|
typedef struct
|
|
_ADAPTERCB
|
|
{
|
|
// Set to MTAG_ADAPTERCB for easy identification in memory dumps and use
|
|
// in assertions.
|
|
//
|
|
ULONG ulTag;
|
|
|
|
// Next/prev adapter control block.
|
|
LIST_ENTRY linkAdapter;
|
|
|
|
|
|
// ACBF_* bit flags indicating various options. Access restrictions are
|
|
// indicated for each individual flag. Many of these flags are set
|
|
// permanently at initialization and so have no access limitation.
|
|
//
|
|
//
|
|
ULONG ulFlags;
|
|
|
|
//
|
|
// List of PDO control blocks, each representing a remote
|
|
// device.
|
|
//
|
|
LIST_ENTRY PDOList;
|
|
|
|
//
|
|
// Reference count on this control block. The reference pairs are:
|
|
//
|
|
//
|
|
// Access is via ReferenceAdapter and DereferenceAdapter only.
|
|
// Serialization is via interlocked operations.
|
|
//
|
|
LONG lRef;
|
|
|
|
|
|
//
|
|
// This is the adapter-wide lock, serializing access to everything except
|
|
// to the contents of VCs, which are serialized by their own lock.
|
|
//
|
|
NDIS_SPIN_LOCK lock;
|
|
|
|
//
|
|
// Generation Count of the physical Bus 1394
|
|
//
|
|
UINT Generation;
|
|
|
|
|
|
//
|
|
// NDIS's handle for this mini-port adapter passed to us in
|
|
// MiniportInitialize. This is passed back to various NdisXxx calls.
|
|
//
|
|
NDIS_HANDLE MiniportAdapterHandle;
|
|
|
|
//
|
|
// unique ID for the local host controller this adapter is representing
|
|
//
|
|
UINT64 UniqueId;
|
|
|
|
//
|
|
// List of address-family control blocks, each representing
|
|
// an open address family binding.
|
|
//
|
|
LIST_ENTRY AFList;
|
|
|
|
|
|
//
|
|
// List of Recv-FIFO control blocks, each representing one
|
|
// local receive FIFO.
|
|
//
|
|
PRECVFIFO_VCCB pRecvFIFOVc;
|
|
|
|
//
|
|
// This event is used to wake up the work Item that will complete
|
|
// the RecvFIFO make call
|
|
//
|
|
NDIS_EVENT RecvFIFOEvent;
|
|
|
|
//
|
|
// The is the LocalHost information that is used in identifying
|
|
// the local host. This contains the PDO and the Unique ID
|
|
// for the Host and is a per Adapter quantity
|
|
//
|
|
PDEVICE_OBJECT pNdisDeviceObject;
|
|
|
|
PREMOTE_NODE pLocalHost;
|
|
|
|
|
|
// Information about the broadcast channel.
|
|
//
|
|
struct
|
|
{
|
|
ULONG ulFlags;
|
|
ULONG ulChannel;
|
|
|
|
LIST_ENTRY VcList;
|
|
} BroadcastChannel;
|
|
|
|
|
|
// Stores information about the Hardware Status of the NIc
|
|
//
|
|
NDIS_HARDWARE_STATUS HardwareStatus;
|
|
|
|
// Store the MediaConnectStatus that Ndis requests
|
|
//
|
|
|
|
NDIS_MEDIA_STATE MediaConnectStatus;
|
|
|
|
// NodeAddress of the physical bus
|
|
//
|
|
NODE_ADDRESS NodeAddress;
|
|
|
|
//
|
|
// enum1394 handle for the adapter
|
|
//
|
|
PVOID EnumAdapterHandle;
|
|
|
|
//
|
|
// BCR Related Information is stored here
|
|
//
|
|
BROADCAST_CHANNEL_DATA BCRData;
|
|
|
|
//
|
|
// Bitmap Channnels allocated by this adapter
|
|
//
|
|
ULONGLONG ChannelsAllocatedByLocalHost;
|
|
|
|
//
|
|
// Speed - of the local network
|
|
//
|
|
ULONG SpeedMbps;
|
|
|
|
//
|
|
// Speed according to the 1394 speed codes
|
|
//
|
|
ULONG Speed;
|
|
|
|
|
|
//
|
|
// Gasp header that will bew inserted before every Broadcast write
|
|
//
|
|
|
|
GASP_HEADER GaspHeader;
|
|
|
|
//
|
|
// Lookaside lists for Large sends
|
|
//
|
|
NIC_NPAGED_LOOKASIDE_LIST SendLookasideList8K;
|
|
|
|
//
|
|
// Lookaside List to handle packets of 2k
|
|
//
|
|
|
|
NIC_NPAGED_LOOKASIDE_LIST SendLookasideList2K;
|
|
|
|
//
|
|
// Small Lookaside list for packets less than 100 bytes
|
|
//
|
|
NIC_NPAGED_LOOKASIDE_LIST SendLookasideList100;
|
|
|
|
//
|
|
// Datagram Label Number - used in fragmentation
|
|
//
|
|
ULONG dgl;
|
|
|
|
USHORT MaxRec;
|
|
USHORT Gap;
|
|
//
|
|
// Node Table - Mapping of Node Address with RemoteNodes
|
|
//
|
|
NODE_TABLE NodeTable;
|
|
|
|
//
|
|
// Number of remote nodes present
|
|
//
|
|
ULONG NumRemoteNodes;
|
|
//
|
|
// Timer used for reassembly invalidation
|
|
//
|
|
NDIS_MINIPORT_TIMER ReassemblyTimer;
|
|
|
|
//
|
|
// Packet pool for loopback packets.
|
|
//
|
|
NIC_PACKET_POOL LoopbackPool;
|
|
|
|
//
|
|
// Buffer pool for loopback packets.
|
|
//
|
|
NDIS_HANDLE LoopbackBufferPool;
|
|
|
|
|
|
//
|
|
// Handle for the config rom that was added to the bus driver
|
|
//
|
|
HANDLE hCromData;
|
|
|
|
//
|
|
// WaitForRemoteNode - threads which need to wait for
|
|
// the arrival of a remote node use this event
|
|
//
|
|
NIC1394_EVENT WaitForRemoteNode;
|
|
|
|
|
|
//
|
|
// Config Rom Mdl that points to the config rom string
|
|
//
|
|
PMDL pConfigRomMdl;
|
|
|
|
PREMOTE_NODE pLastRemoteNode;
|
|
|
|
//
|
|
// Packet Log (used only for tracking packets).
|
|
//
|
|
PNIC1394_PKTLOG pPktLog;
|
|
|
|
//
|
|
// Per adapter stats
|
|
//
|
|
ADAPT_STATS AdaptStats;
|
|
//
|
|
// Read/WriteCapabilities
|
|
//
|
|
GET_LOCAL_HOST_INFO2 ReadWriteCaps;
|
|
|
|
//
|
|
// SCode - speed of the bus
|
|
//
|
|
ULONG SCode;
|
|
|
|
//
|
|
// Max packet size that this adapter can read
|
|
//
|
|
ULONG MaxSendBufferSize;
|
|
ULONG MaxRecvBufferSize;
|
|
ULONG CurrentLookahead;
|
|
|
|
//
|
|
// PacketFilter - Ethernet structs
|
|
//
|
|
|
|
PETHERNET_VCCB pEthernetVc;
|
|
ULONG CurPacketFilter ;
|
|
ULONG ProtocolOptions;
|
|
MAC_ADDRESS McastAddrs[MCAST_LIST_SIZE];
|
|
ULONG McastAddrCount;
|
|
ULONG CurLookAhead ;
|
|
MAC_ADDRESS MacAddressEth;
|
|
|
|
|
|
//
|
|
// ReceivePacket Serialization
|
|
//
|
|
NIC_SERIALIZATION SerRcv;
|
|
|
|
NIC_SERIALIZATION SerSend;
|
|
|
|
NIC_SERIALIZATION Status;
|
|
|
|
NIC_SERIALIZATION Reassembly;
|
|
|
|
NIC_SERIALIZATION LoadArp;
|
|
|
|
//
|
|
// Outstanding work Items
|
|
ULONG OutstandingWorkItems;
|
|
|
|
//
|
|
// Outstanding Reassemblies
|
|
//
|
|
ULONG OutstandingReassemblies;
|
|
|
|
//
|
|
// Miniport Name
|
|
//
|
|
WCHAR AdapterName[ADAPTER_NAME_SIZE];
|
|
|
|
//
|
|
// Size of Name
|
|
//
|
|
ULONG AdapterNameSize;
|
|
|
|
//
|
|
// Ioctl Sent to the Arp module
|
|
//
|
|
|
|
ARP1394_IOCTL_COMMAND ArpIoctl;
|
|
|
|
//
|
|
// Is Arp Started
|
|
//
|
|
|
|
BOOLEAN fIsArpStarted;
|
|
|
|
//
|
|
// Power State
|
|
//
|
|
NET_DEVICE_POWER_STATE PowerState;
|
|
} ADAPTERCB, *PADAPTERCB;
|
|
|
|
|
|
//
|
|
// Address Family Flags
|
|
//
|
|
|
|
#define ACBF_Allocated 0x00000001
|
|
#define ACBF_Initialized 0x00000002
|
|
#define ACBF_ClosePending 0x00000100
|
|
#define ACBF_CloseComplete 0x00000200
|
|
|
|
|
|
// Address family control block, describing the state of an ndis address family.
|
|
// Each block may have zero or more VCs associated with it.
|
|
//
|
|
typedef struct
|
|
_AFCB
|
|
{
|
|
// Set to MTAG_AFCB for easy identification in memory dumps and use in
|
|
// assertions.
|
|
//
|
|
ULONG ulTag;
|
|
|
|
// ACBF_* bit flags indicating various options. Access restrictions are
|
|
// indicated for each individual flag. Many of these flags are set
|
|
// permanently at initialization and so have no access limitation.
|
|
//
|
|
//
|
|
ULONG ulFlags;
|
|
|
|
|
|
// Reference count on this control block. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when this block is linked to the adapter's
|
|
// list of af blocks, and removed when it is unlinked.
|
|
//
|
|
// (a) A reference is added when a call on a VCCB is created
|
|
// removed when it is deleted.
|
|
//
|
|
// Access is via ReferenceTunnel and DereferenceTunnel only which use
|
|
// 'ADAPTERCB.lockTunnels' for protection.
|
|
//
|
|
LONG lRef;
|
|
|
|
// Links to the prev/next AFCB in the owning adapter's AF list.
|
|
// Access to the list links is protected by 'ADAPTERCB.lock'.
|
|
//
|
|
LIST_ENTRY linkAFCB;
|
|
|
|
|
|
// List of all VCs associated with this address family.
|
|
// Access is protected by the adapter lock.
|
|
//
|
|
LIST_ENTRY AFVCList;
|
|
|
|
// Back pointer to owning adapter's control block.
|
|
//
|
|
PADAPTERCB pAdapter;
|
|
|
|
// NDIS's handle for our Address Family as passed to our CmOpenAfHandler
|
|
// or NULL if none.
|
|
//
|
|
NDIS_HANDLE NdisAfHandle;
|
|
|
|
|
|
}
|
|
AFCB, *PAFCB;
|
|
|
|
|
|
|
|
|
|
// Call statistics block.
|
|
//
|
|
typedef struct
|
|
_CALLSTATS
|
|
{
|
|
// System time call reached established state. When the block is being
|
|
// used for cumulative statistics of multiple calls, this is the number of
|
|
// calls instead.
|
|
//
|
|
LONGLONG llCallUp;
|
|
|
|
// Duration in seconds of now idle call.
|
|
//
|
|
ULONG ulSeconds;
|
|
|
|
// Total data bytes received and sent.
|
|
//
|
|
ULONG ulDataBytesRecd;
|
|
ULONG ulDataBytesSent;
|
|
|
|
// Number of received packets indicated up.
|
|
//
|
|
ULONG ulRecdDataPackets;
|
|
|
|
// TODO: add more stats if required.
|
|
|
|
ULONG ulSentPkts;
|
|
|
|
//
|
|
// NDis Packet failures
|
|
//
|
|
ULONG ulSendFailures;
|
|
|
|
//
|
|
// Bus AsyncWrite or Stream failires
|
|
//
|
|
|
|
ULONG ulBusSendFailures;
|
|
|
|
ULONG ulBusSendSuccess;
|
|
|
|
}
|
|
CALLSTATS;
|
|
|
|
typedef
|
|
NDIS_STATUS
|
|
(*PFN_INITVCHANDLER) (
|
|
VCCB *pVc
|
|
);
|
|
|
|
|
|
|
|
|
|
typedef
|
|
NDIS_STATUS
|
|
(*PFN_SENDPACKETHANDLER) (
|
|
VCCB *pVc,
|
|
NDIS_PACKET * pPacket
|
|
);
|
|
|
|
typedef
|
|
NDIS_STATUS
|
|
(*PFN_CLOSECALLHANDLER) (
|
|
VCCB *pVc
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*PFN_RETURNHANDLER) (
|
|
VCCB *pVc,
|
|
PNDIS_PACKET *pPacket
|
|
);
|
|
|
|
// Table of vc-type-specific handler functions.
|
|
//
|
|
typedef struct _VC_HANDLERS
|
|
{
|
|
PFN_INITVCHANDLER MakeCallHandler;
|
|
PFN_CLOSECALLHANDLER CloseCallHandler;
|
|
PFN_SENDPACKETHANDLER SendPackets;
|
|
|
|
} VC_HANDLERS;
|
|
|
|
|
|
typedef enum _NIC1394_VC_TYPE
|
|
{
|
|
NIC1394_Invalid_Type,
|
|
NIC1394_SendRecvChannel,
|
|
NIC1394_RecvFIFO,
|
|
NIC1394_SendFIFO,
|
|
NIC1394_MultiChannel,
|
|
NIC1394_Ethernet,
|
|
NIC1394_SendChannel,
|
|
NIC1394_RecvChannel,
|
|
Nic1394_NoMoreVcTypes
|
|
|
|
} NIC1394_VC_TYPE, *PNIC1394_VC_TYPE;
|
|
|
|
|
|
|
|
// Virtual circuit control block header defining the state of a single VC that
|
|
// is common to all the different types of VCs.
|
|
//
|
|
typedef struct
|
|
_VCHDR
|
|
{
|
|
// Set to MTAG_VCCB_* for easy identification in memory dumps and use in
|
|
// assertions.
|
|
//
|
|
ULONG ulTag;
|
|
|
|
|
|
|
|
// The Pdo Block that will be used to perform all the operations for this Vc
|
|
//
|
|
//
|
|
|
|
PREMOTE_NODE pRemoteNode;
|
|
|
|
//
|
|
// pLocalHostVdo - local host's VDO that will be used for all channel and
|
|
// recv fifo allocations
|
|
//
|
|
PDEVICE_OBJECT pLocalHostVDO;
|
|
|
|
// Links to the prev/next VCCB in the owning AF's control block.
|
|
// Access is protected by 'ADAPTERCB.lock'.
|
|
//
|
|
LIST_ENTRY linkAFVcs;
|
|
|
|
// The VCType and Destination of the call that has been set up on the VC
|
|
// The VCType can be either Isoch or Async, Sends or Recieve. Each type
|
|
// of VC has an address associated with it
|
|
|
|
NIC1394_VC_TYPE VcType;
|
|
|
|
|
|
// This stores the generation of the physical adapter. And should match the value
|
|
// kept in the adapter block
|
|
PUINT pGeneration;
|
|
|
|
|
|
// VCBF_* bit flags indicating various options and states. Access is via
|
|
// the interlocked ReadFlags/SetFlags/ClearFlags routines.
|
|
//
|
|
// VCBF_IndicateReceivedTime: Set if MakeCall caller sets the
|
|
// MediaParameters.Flags RECEIVE_TIME_INDICATION flag requesting the
|
|
// TimeReceived field of the NDIS packet be filled with a timestamp.
|
|
//
|
|
// VCBF_CallClosableByClient: Set when a call is in a state where
|
|
// NicCmCloseCall requests to initiate clean-up should be accepted.
|
|
// This may be set when VCBF_CallClosableByPeer is not, which means we
|
|
// have indicated an incoming close to client and are waiting for him
|
|
// to do a client close in response (in that weird CoNDIS way). The
|
|
// flag is protected by 'lockV'.
|
|
//
|
|
// VCBF_VcCreated: Set when the VC has been created successfully. This is
|
|
// the "creation" that occurs with the client, not the mini-port.
|
|
// VCBF_VcActivated: Set when the VC has been activated successfully.
|
|
// VCBM_VcState: Bit mask including each of the above 3 NDIS state flags.
|
|
//
|
|
// VCBF_VcDeleted: Set when the DeleteVC handler has been called on this
|
|
// VC. This guards against NDPROXY double-deleting VCs which it has
|
|
// been known to do.
|
|
//
|
|
// The pending bits below are mutually exclusive (except ClientClose which
|
|
// may occur after but simultaneous with ClientOpen), and so require lock
|
|
// protection by 'lockV':
|
|
//
|
|
// VCBF_ClientOpenPending: Set when client attempts to establish a call,
|
|
// and the result is not yet known.
|
|
// VCBF_ClientClosePending: Set when client attempts to close an
|
|
// established call and the result is not yet known. Access is
|
|
// protected by 'lockV'.
|
|
// VCBM_Pending: Bit mask that includes each of the 4 pending flags.
|
|
//
|
|
// VCBF_ClientCloseCompletion: Set when client close completion is in
|
|
// progress.
|
|
//
|
|
// VCBF_WaitCloseCall: Set when the client is expected to call our call
|
|
// manager's CloseCall handler. This is strictly a debug aid.
|
|
//
|
|
// VCBF_FreedResources - VC This is a channel VC and because the last
|
|
// node in the network was being removed, its resources have been freed
|
|
|
|
ULONG ulFlags;
|
|
#define VCBF_IndicateTimeReceived 0x00000001
|
|
#define VCBF_CallClosableByClient 0x00000002
|
|
#define VCBF_VcCreated 0x00000100
|
|
#define VCBF_VcActivated 0x00000200
|
|
#define VCBF_VcDispatchedCloseCall 0x00000400
|
|
#define VCBF_MakeCallPending 0x00002000
|
|
#define VCBF_CloseCallPending 0x00008000
|
|
#define VCBF_VcDeleted 0x00010000
|
|
#define VCBF_MakeCallFailed 0x00020000
|
|
#define VCBF_CloseCallCompleted 0x00040000
|
|
#define VCBF_WaitCloseCall 0x00200000
|
|
#define VCBF_NewPdoIsActivatingFifo 0x01000000
|
|
#define VCBF_PdoIsBeingRemoved 0x02000000
|
|
#define VCBF_NeedsToAllocateChannel 0x04000000
|
|
#define VCBF_GenerationWorkItem 0x10000000
|
|
#define VCBF_AllocatedChannel 0x20000000
|
|
#define VCBF_BroadcastVc 0x40000000
|
|
#define VCBF_FreedResources 0x80000000
|
|
|
|
#define VCBM_VcState 0x00000700
|
|
#define VCBM_Pending 0x0000F000
|
|
#define VCBM_NoActiveCall 0x000F0000
|
|
#define VCBM_PdoFlags 0x0F000000
|
|
|
|
|
|
// Back pointer to owning address family control block.
|
|
//
|
|
AFCB* pAF;
|
|
|
|
|
|
// Reference count on the active call.
|
|
// References may only be added
|
|
// when the VCCB_VcActivated flag is set, and this is enforced by
|
|
// ReferenceCall. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when a VC is activated and removed when it is
|
|
// de-activated.
|
|
//
|
|
// (b) A reference is added when the send handler accepts a packet.
|
|
//
|
|
// The field is accessed only by the ReferenceCall and DereferenceCall
|
|
// routines, which protect the field with 'lock'.
|
|
//
|
|
REF CallRef;
|
|
|
|
// Reference count on this VC control block. The reference pairs are:
|
|
//
|
|
// (a) NicCoCreateVc adds a reference that is removed by NicCoDeleteVc.
|
|
// This covers all clients that learn of the VCCB via NDIS.
|
|
//
|
|
// The field is accessed only by the ReferenceVc and DereferenceVc
|
|
// routines, which protect with Interlocked routines.
|
|
//
|
|
LONG lRef;
|
|
|
|
|
|
//
|
|
// This is a copy the parameters that are passed to the VC in
|
|
// a Make Call. Each VC needs to keep a copy. This is stored here
|
|
//
|
|
|
|
NIC1394_MEDIA_PARAMETERS Nic1394MediaParams;
|
|
|
|
|
|
// NDIS BOOKKEEPING ------------------------------------------------------
|
|
|
|
// NDIS's handle for this VC passed to us in MiniportCoCreateVcHandler.
|
|
// This is passed back to NDIS in various NdisXxx calls.
|
|
//
|
|
NDIS_HANDLE NdisVcHandle;
|
|
|
|
// This linked list is used to designate all the VCs that are using a single PdoCb
|
|
// The head of this list resides in a REMOTE_NODE. So that when a Pdo goes away, we can go and
|
|
// close all the Vcs that are dependent on it. No RecvFIFO included
|
|
|
|
LIST_ENTRY SinglePdoVcLink;
|
|
|
|
// CALL SETUP ------------------------------------------------------------
|
|
|
|
// Address of the call parameters passed down in CmMakeCall. This field
|
|
// will only be valid until the NdisMCmMakeCallComplete notification for
|
|
// the associated call is made, at which time it is reset to NULL. Access
|
|
// is via Interlocked routines.
|
|
//
|
|
PCO_CALL_PARAMETERS pCallParameters;
|
|
|
|
UINT MTU;
|
|
|
|
// This is the initialize handler used to initialize the Vc
|
|
// Each Vc has its own specific initialize handler so that all the
|
|
// data structures that specific to it, can be filled
|
|
//
|
|
VC_HANDLERS VcHandlers;
|
|
|
|
|
|
// STATISTICS ------------------------------------------------------------
|
|
|
|
// Statistics for the current call. Access is protected by 'lock'.
|
|
//
|
|
CALLSTATS stats;
|
|
|
|
// This is a pointer to the lock in the adapater
|
|
// structure.
|
|
PNDIS_SPIN_LOCK plock;
|
|
|
|
//
|
|
// MaxPayload that this VC will send in a single IRP
|
|
// To be used in Lookaside lists
|
|
//
|
|
ULONG MaxPayload;
|
|
|
|
}
|
|
VCHDR;
|
|
|
|
//
|
|
// Virtual circuit control block defining the state of a single SendFIFO VC.
|
|
//
|
|
typedef struct
|
|
_SENDFIFO_VCCB
|
|
{
|
|
// Common header for all types of VCs
|
|
//
|
|
VCHDR Hdr;
|
|
|
|
|
|
// Prev/next in the list of SendFIFO VCs for a particular destination
|
|
// PDO
|
|
//
|
|
LIST_ENTRY SendFIFOLink;
|
|
|
|
// SendFIFO-specific VC Info
|
|
//
|
|
NIC1394_FIFO_ADDRESS FifoAddress;
|
|
|
|
// Shortcuts to the Values we were passed in the Make call
|
|
// that activated the VC
|
|
//
|
|
// UINT MaxSendBlockSize;
|
|
UINT MaxSendSpeed;
|
|
|
|
|
|
} SENDFIFO_VCCB, *PSENDFIFO_VCCB;
|
|
|
|
|
|
// Virtual circuit control block defining the state of a single RecvFIFO VC.
|
|
//
|
|
typedef struct
|
|
_RECVFIFO_VCCB
|
|
{
|
|
// Common header for all types of VCs
|
|
//
|
|
VCHDR Hdr;
|
|
|
|
// Prev/next in the list of RecvFIFO VCs for a particular Recv FIFO
|
|
// address.
|
|
//
|
|
LIST_ENTRY RecvFIFOLink;
|
|
|
|
// Packet Pool Handle
|
|
//
|
|
NIC_PACKET_POOL PacketPool;
|
|
|
|
//NDIS_HANDLE PacketPoolHandle;
|
|
|
|
// Slist Header. All buffers are posted here, using Interlocked routines
|
|
//
|
|
|
|
SLIST_HEADER FifoSListHead;
|
|
|
|
// Slist Spin lock that protects the Slist
|
|
//
|
|
KSPIN_LOCK FifoSListSpinLock;
|
|
|
|
//
|
|
// Num Fifo Elements allocated
|
|
//
|
|
ULONG NumAllocatedFifos;
|
|
|
|
// Num of Fifo that have been indicated to the miniport
|
|
// Count of Fifo that the Nic has not returned to the bus driver
|
|
//
|
|
ULONG NumIndicatedFifos;
|
|
|
|
// This is the address range that is returned in the allocate
|
|
// address irb. Will be changed to a pointer or an array
|
|
//
|
|
|
|
ADDRESS_RANGE VcAddressRange;
|
|
|
|
// This is the number of address ranges that the bus driver
|
|
// returned. For now, it is expected to be one.
|
|
//
|
|
UINT AddressesReturned;
|
|
|
|
|
|
//
|
|
// Handle to the address range
|
|
//
|
|
HANDLE hAddressRange;
|
|
|
|
//
|
|
// Buffer pool
|
|
//
|
|
NIC_BUFFER_POOL BufferPool;
|
|
|
|
//NIC_WORK_ITEM FifoWorkItem;
|
|
|
|
BOOLEAN FifoWorkItemInProgress ;
|
|
|
|
UINT NumOfFifosInSlistInCloseCall;
|
|
|
|
#if FIFO_WRAPPER
|
|
|
|
PADDRESS_FIFO pFifoTable[NUM_RECV_FIFO_BUFFERS];
|
|
|
|
#endif
|
|
|
|
} RECVFIFO_VCCB, *PRECVFIFO_VCCB;
|
|
|
|
|
|
// Virtual circuit control block defining the state of a single CHANNEL VC.
|
|
//
|
|
typedef struct
|
|
_CHANNEL_VCCB
|
|
{
|
|
// Common header for all types of VCs
|
|
//
|
|
VCHDR Hdr;
|
|
|
|
// Prev/next in the list of channel VCs for a particular destination
|
|
// channel
|
|
//
|
|
LIST_ENTRY ChannelLink;
|
|
|
|
|
|
// Channel-specific VC Info
|
|
//
|
|
UINT Channel;
|
|
|
|
// The speed at which this Channel will stream data
|
|
//
|
|
UINT Speed;
|
|
|
|
// Indicates the Sy field in packets that will indicated up
|
|
//
|
|
ULONG ulSynch;
|
|
|
|
// the Tag used in submitting asyncstream irps
|
|
//
|
|
ULONG ulTag;
|
|
|
|
// MaxBytesPerFrameRequested and available
|
|
//
|
|
ULONG MaxBytesPerFrameRequested;
|
|
ULONG BytesPerFrameAvailable;
|
|
|
|
// Handle to the Resources allocated
|
|
//
|
|
HANDLE hResource;
|
|
|
|
// Speeds Requested and speed returned
|
|
//
|
|
ULONG SpeedRequested;
|
|
ULONG SpeedSelected;
|
|
|
|
// Maximum Buffer Size
|
|
//
|
|
ULONG MaxBufferSize;
|
|
|
|
// Num of descriptors that were attached to the resources
|
|
//
|
|
ULONG NumDescriptors;
|
|
|
|
// Pointer to an array of isochDescriptors used in AttachBuffers
|
|
//
|
|
PISOCH_DESCRIPTOR pIsochDescriptor;
|
|
|
|
// PacketPool Handle
|
|
//
|
|
NIC_PACKET_POOL PacketPool;
|
|
|
|
//NDIS_HANDLE hPacketPoolHandle;
|
|
//
|
|
// Temporary
|
|
//
|
|
UINT PacketLength;
|
|
|
|
//
|
|
// Number of Isoch Descriptors that the Bus driver has indicated to the miniport
|
|
//
|
|
ULONG NumIndicatedIsochDesc;
|
|
|
|
|
|
//
|
|
// Event to signal that the last of the Isoch descriptors have
|
|
// been returned to the bus driver. Only set when Vc is closing (after IsochStop)
|
|
//
|
|
NDIS_EVENT LastDescReturned;
|
|
|
|
//
|
|
// Channel Map used in Multichannel Vcs
|
|
//
|
|
ULARGE_INTEGER uliChannelMap;
|
|
|
|
|
|
} CHANNEL_VCCB, *PCHANNEL_VCCB;
|
|
|
|
|
|
typedef struct
|
|
_ETHERNET_VCCB
|
|
{
|
|
// Common header for all types of VCs
|
|
//
|
|
VCHDR Hdr;
|
|
|
|
|
|
NIC_PACKET_POOL PacketPool;
|
|
|
|
} ETHERNET_VCCB, *PETHERNET_VCCB;
|
|
|
|
|
|
|
|
|
|
|
|
// The following union has enough space to hold any of the type-specific
|
|
// VC control blocks.
|
|
//
|
|
typedef union _VCCB
|
|
{
|
|
VCHDR Hdr;
|
|
CHANNEL_VCCB ChannelVc;
|
|
SENDFIFO_VCCB SendFIFOVc;
|
|
RECVFIFO_VCCB RecvFIFOVc;
|
|
ETHERNET_VCCB EthernetVc;
|
|
|
|
} VCCB, *PVCCB;
|
|
|
|
// The next structure is used when sending a packet, to store context
|
|
// information in an NdisPacket. These are pointers to the Vc and the Irb
|
|
// and are stored in the MiniportWrapperReserved field of the NdisPacket
|
|
// and has a limit of 2 PVOIDs
|
|
//
|
|
typedef union _PKT_CONTEXT
|
|
{
|
|
struct
|
|
{
|
|
PVCCB pVc;
|
|
PVOID pLookasideListBuffer;
|
|
|
|
} AsyncWrite;
|
|
|
|
struct
|
|
{
|
|
PVCCB pVc;
|
|
PVOID pLookasideListBuffer;
|
|
|
|
} AsyncStream;
|
|
|
|
//
|
|
// For receives make sure the first element is the Vc or we will break;
|
|
//
|
|
struct
|
|
{
|
|
PRECVFIFO_VCCB pRecvFIFOVc;
|
|
PADDRESS_FIFO pIndicatedFifo;
|
|
|
|
} AllocateAddressRange;
|
|
|
|
struct
|
|
{
|
|
PCHANNEL_VCCB pChannelVc;
|
|
PISOCH_DESCRIPTOR pIsochDescriptor;
|
|
|
|
} IsochListen;
|
|
|
|
struct
|
|
{
|
|
//
|
|
// First DWORD is the Vc
|
|
//
|
|
PVCCB pVc;
|
|
|
|
//
|
|
// Second is the isoch descriptor or Fifo
|
|
//
|
|
union
|
|
{
|
|
PISOCH_DESCRIPTOR pIsochDescriptor; // channels use isoch desc
|
|
|
|
PADDRESS_FIFO pIndicatedFifo; // fifo use AddressFifo
|
|
|
|
PVOID pCommon; // to be used in the common code path
|
|
|
|
} IndicatedStruct;
|
|
|
|
} Receive;
|
|
|
|
struct
|
|
{
|
|
|
|
PNDIS_PACKET pOrigPacket;
|
|
|
|
} EthernetSend;
|
|
|
|
|
|
|
|
} PKT_CONTEXT,*PPKT_CONTEXT,**PPPKT_CONTEXT;
|
|
|
|
|
|
typedef struct _NDIS1394_FRAGMENT_HEADER
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
ULONG FH_fragment_offset:12;
|
|
ULONG FH_rsv_0:4;
|
|
ULONG FH_buffersize:12;
|
|
ULONG FH_rsv_1:2;
|
|
ULONG FH_lf:2;
|
|
|
|
} FirstQuadlet;
|
|
|
|
struct
|
|
{
|
|
ULONG FH_EtherType:16;
|
|
ULONG FH_buffersize:12;
|
|
ULONG FH_rsv_1:2;
|
|
ULONG FH_lf:2;
|
|
|
|
|
|
} FirstQuadlet_FirstFragment;
|
|
|
|
ULONG FH_High;
|
|
} u;
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
|
|
ULONG FH_rsv:16;
|
|
ULONG FH_dgl:16;
|
|
|
|
} SecondQuadlet;
|
|
|
|
ULONG FH_Low;
|
|
} u1;
|
|
|
|
} NDIS1394_FRAGMENT_HEADER, *PNDIS1394_FRAGMENT_HEADER;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define LOOKASIDE_HEADER_No_More_Framgents 1
|
|
#define LOOKASIDE_HEADER_SendPacketFrees 2
|
|
#define LOOKASIDE_HEADER_SendCompleteFrees 4
|
|
|
|
|
|
//
|
|
// This structure is used with the above flags to maintain state within the lookaside buffer
|
|
//
|
|
|
|
|
|
typedef union _LOOKASIDE_BUFFER_STATE
|
|
{
|
|
struct
|
|
{
|
|
USHORT Refcount;
|
|
USHORT Flags;
|
|
} u;
|
|
|
|
LONG FlagRefcount;
|
|
|
|
} LOOKASIDE_BUFFER_STATE, *PLOOKASIDE_BUFFER_STATE;
|
|
|
|
|
|
typedef enum _BUS_OPERATION
|
|
{
|
|
InvalidOperation,
|
|
AsyncWrite,
|
|
AsyncStream,
|
|
AddressRange,
|
|
IsochReceive
|
|
|
|
|
|
} BUS_OPERATION, *PBUS_OPERATION;
|
|
|
|
|
|
//
|
|
// This will be used as a local variable
|
|
// during a send operation and will
|
|
// keep all the state information
|
|
// regarding fragmentation
|
|
//
|
|
typedef struct _FRAGMENTATION_STRUCTURE
|
|
{
|
|
//
|
|
// Start of the buffer that will be used in the send.
|
|
// Usually from a lookaside list
|
|
//
|
|
PVOID pLookasideListBuffer;
|
|
|
|
|
|
//
|
|
// Fragment Length
|
|
//
|
|
ULONG FragmentLength ;
|
|
|
|
//
|
|
// Start of the this fragment to be used
|
|
//
|
|
PVOID pStartFragment;
|
|
|
|
//
|
|
// Specified if an async write or an asyncstream operation is occurring
|
|
//
|
|
BUS_OPERATION AsyncOp;
|
|
|
|
//
|
|
// LookasideBuffer associated with the fragmentation
|
|
//
|
|
PVOID pLookasideBuffer;
|
|
|
|
|
|
//
|
|
// Start of the next fragment
|
|
//
|
|
// PVOID pStartNextFragment;
|
|
//
|
|
// Length of each fragment
|
|
//
|
|
ULONG MaxFragmentLength;
|
|
|
|
//
|
|
// NumFragments that will be generated
|
|
//
|
|
ULONG NumFragmentsNeeded ;
|
|
|
|
//
|
|
// Current NdisBuffer which is being fragmented
|
|
//
|
|
PNDIS_BUFFER pCurrNdisBuffer;
|
|
|
|
//
|
|
// Length that needs to be copied in CurrNdisBuffer
|
|
//
|
|
ULONG NdisBufferLengthRemaining;
|
|
|
|
//
|
|
// Point to which copying has occurred in the pCurrNdisBuffer
|
|
//
|
|
PVOID pSourceAddressInNdisBuffer;
|
|
|
|
//
|
|
// UnFragment Header from this NdisPacket
|
|
//
|
|
|
|
NDIS1394_UNFRAGMENTED_HEADER UnfragmentedHeader;
|
|
|
|
//
|
|
// Fragmented Header to be used by all the fragments
|
|
// generated by this NdisPackets
|
|
//
|
|
|
|
|
|
NDIS1394_FRAGMENT_HEADER FragmentationHeader;
|
|
|
|
|
|
//
|
|
// Status of the lf field in the fragment header. Also serves as an
|
|
// implicit flag about the state of the fragmentation
|
|
//
|
|
NDIS1394_FRAGMENT_LF lf;
|
|
|
|
//
|
|
// Length of the Ip Datagram, to be used as the buffersize in fragment header
|
|
//
|
|
USHORT IPDatagramLength;
|
|
|
|
//
|
|
// An AsyncStream will have a gasp header as well . So the starting
|
|
// offset can either be either 8 or 16. Only applicable for fragmentation code path
|
|
//
|
|
ULONG TxHeaderSize;
|
|
|
|
//
|
|
// Pointer to the lookaside list that this buffer was allocated from
|
|
//
|
|
PNIC_NPAGED_LOOKASIDE_LIST pLookasideList;
|
|
|
|
//
|
|
// Adapter - local host
|
|
//
|
|
PADAPTERCB pAdapter;
|
|
|
|
//
|
|
// Pointer to the IRB to be used in the current fragment
|
|
//
|
|
PIRB pCurrentIrb;
|
|
|
|
//
|
|
// Current Fragment Number
|
|
//
|
|
ULONG CurrFragmentNum;
|
|
|
|
PVOID pStartOfFirstFragment;
|
|
|
|
}FRAGMENTATION_STRUCTURE, *PFRAGMENTATION_STRUCTURE;
|
|
|
|
|
|
|
|
typedef struct _LOOKASIDE_BUFFER_HEADER
|
|
{
|
|
|
|
//
|
|
// Refcount
|
|
//
|
|
ULONG OutstandingFragments;
|
|
|
|
//
|
|
// NumOfFragments generated by the NdisPacket So Far
|
|
//
|
|
ULONG FragmentsGenerated;
|
|
|
|
//
|
|
// Will this Buffer contain fragments
|
|
//
|
|
BOOLEAN IsFragmented;
|
|
|
|
//
|
|
// Pointer to the NdisPacket whose data is being transmitted
|
|
// by the lookaside buffer
|
|
//
|
|
PNDIS_PACKET pNdisPacket;
|
|
|
|
//
|
|
// pVc Pointer to the Vc on which the packet was indicated
|
|
// Used to complete the packet
|
|
//
|
|
PVCCB pVc;
|
|
|
|
//
|
|
// Pointer to the lookaside list that this buffer was allocated from
|
|
//
|
|
PNIC_NPAGED_LOOKASIDE_LIST pLookasideList;
|
|
|
|
//
|
|
// Bus Op AsyncStream or AsyncWrite.
|
|
// AsyncWrite reference the RemoteNode. AsuncWrite does not
|
|
//
|
|
BUS_OPERATION AsyncOp;
|
|
|
|
//
|
|
// Start of Data
|
|
//
|
|
PVOID pStartOfData;
|
|
|
|
|
|
} LOOKASIDE_BUFFER_HEADER, *PLOOKASIDE_BUFFER_HEADER;
|
|
|
|
typedef enum _ENUM_LOOKASIDE_LIST
|
|
{
|
|
NoLookasideList,
|
|
SendLookasideList100,
|
|
SendLookasideList2K,
|
|
SendLookasideList8K
|
|
|
|
} ENUM_LOOKASIDE_LIST, *PENUM_LOOKASIDE_LIST;
|
|
|
|
|
|
//
|
|
// Unfragmented Buffer
|
|
//
|
|
typedef struct _UNFRAGMENTED_BUFFER
|
|
{
|
|
LOOKASIDE_BUFFER_HEADER Header;
|
|
|
|
IRB Irb;
|
|
|
|
UCHAR Data [1];
|
|
|
|
} UNFRAGMENTED_BUFFER, *PUNFRAGMENTED_BUFFER;
|
|
|
|
|
|
|
|
#define PAYLOAD_100 100
|
|
|
|
//
|
|
// A simple packet with no fragmentation . This will primarily be used for the IP Acks and ARP req
|
|
//
|
|
typedef struct _PAYLOAD_100_LOOKASIDE_BUFFER
|
|
{
|
|
|
|
LOOKASIDE_BUFFER_HEADER Header;
|
|
|
|
IRB Irb;
|
|
|
|
UCHAR Data [PAYLOAD_100 + sizeof (GASP_HEADER)];
|
|
|
|
} PAYLOAD_100_LOOKASIDE_BUFFER;
|
|
|
|
//
|
|
// This lookaside will handle packets upto 2K.
|
|
//
|
|
// Calculate the theoretical maximum number of fragments that can occur for a
|
|
// a 2K Packet
|
|
//
|
|
#define PAYLOAD_2K ASYNC_PAYLOAD_400_RATE
|
|
|
|
#define NUM_FRAGMENT_2K ((PAYLOAD_2K/ASYNC_PAYLOAD_100_RATE) +1)
|
|
|
|
typedef struct _PAYLOAD_2K_LOOKASIDE_BUFFER
|
|
{
|
|
|
|
LOOKASIDE_BUFFER_HEADER Header;
|
|
|
|
//
|
|
// There can be a maximum of 2048 bytes in 1 Async Packet fragment
|
|
// on ASYNC_PAYLOAD_400 so this will cater to
|
|
// that, but it will be prepared for the worst
|
|
//
|
|
//
|
|
IRB Irb[NUM_FRAGMENT_2K];
|
|
|
|
//
|
|
// We get a data size large enough to handle 2048 bytes of data chopped up
|
|
// into the max num of fragments and leave room for header (fragmentation and Gasp)
|
|
// To access we'll just use simple pointer arithmetic
|
|
//
|
|
|
|
UCHAR Data[PAYLOAD_2K+ (NUM_FRAGMENT_2K *(sizeof (GASP_HEADER)+sizeof (NDIS1394_FRAGMENT_HEADER)))];
|
|
|
|
} PAYLOAD_2K_LOOKASIDE_BUFFER, *PPAYLOAD_2K_LOOKASIDE_BUFFER;
|
|
|
|
|
|
//
|
|
// This is to handle large packets > 2K .For now I have chosen an arbitrary large amount
|
|
// of 8K
|
|
//
|
|
#define PAYLOAD_8K ASYNC_PAYLOAD_400_RATE *4
|
|
|
|
#define NUM_FRAGMENT_8K (PAYLOAD_8K /ASYNC_PAYLOAD_100_RATE +1)
|
|
|
|
typedef struct _PAYLOAD_8K_LOOKASIDE_BUFFER
|
|
{
|
|
//
|
|
// The same comments as the 2K_Lookaside Header apply here
|
|
//
|
|
LOOKASIDE_BUFFER_HEADER Header;
|
|
|
|
IRB Irb[NUM_FRAGMENT_8K ];
|
|
|
|
|
|
UCHAR Data[PAYLOAD_8K + (NUM_FRAGMENT_8K*(sizeof (GASP_HEADER)+sizeof (NDIS1394_FRAGMENT_HEADER)))];
|
|
|
|
|
|
|
|
}PAYLOAD_8K_LOOKASIDE_BUFFER, *PPAYLOAD_8K_LOOKASIDE_BUFFER;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// The 1394 fragment that is passed down can have a gasp header, fragmentation header,
|
|
// unfragmented header. Define Types to format these headers so that we can make
|
|
// compiler do the pointer arithmetic for us.
|
|
//
|
|
typedef union _PACKET_FORMAT
|
|
{
|
|
|
|
|
|
struct
|
|
{
|
|
GASP_HEADER GaspHeader;
|
|
|
|
NDIS1394_FRAGMENT_HEADER FragmentHeader;
|
|
|
|
UCHAR Data[1];
|
|
|
|
} AsyncStreamFragmented;
|
|
|
|
struct
|
|
{
|
|
GASP_HEADER GaspHeader;
|
|
|
|
NDIS1394_UNFRAGMENTED_HEADER NonFragmentedHeader;
|
|
|
|
UCHAR Data[1];
|
|
|
|
} AsyncStreamNonFragmented;
|
|
|
|
struct
|
|
{
|
|
NDIS1394_FRAGMENT_HEADER FragmentHeader;
|
|
|
|
UCHAR Data[1];
|
|
|
|
} AsyncWriteFragmented;
|
|
|
|
|
|
struct
|
|
{
|
|
NDIS1394_UNFRAGMENTED_HEADER NonFragmentedHeader;
|
|
|
|
UCHAR Data[1];
|
|
|
|
}AsyncWriteNonFragmented;
|
|
|
|
|
|
struct
|
|
{
|
|
//
|
|
// Isoch receive header has a prefix, isoch header, gasp header
|
|
//
|
|
ULONG Prefix;
|
|
|
|
ISOCH_HEADER IsochHeader;
|
|
|
|
GASP_HEADER GaspHeader;
|
|
|
|
NDIS1394_UNFRAGMENTED_HEADER NonFragmentedHeader;
|
|
|
|
UCHAR Data[1];
|
|
|
|
|
|
} IsochReceiveNonFragmented;
|
|
|
|
|
|
struct
|
|
{
|
|
//
|
|
// Isoch receive header has a prefix, isoch header, gasp header
|
|
//
|
|
|
|
ULONG Prefix;
|
|
|
|
ISOCH_HEADER IsochHeader;
|
|
|
|
GASP_HEADER GaspHeader;
|
|
|
|
NDIS1394_FRAGMENT_HEADER FragmentHeader;
|
|
|
|
UCHAR Data[1];
|
|
|
|
|
|
}IsochReceiveFragmented;
|
|
|
|
}PACKET_FORMAT, DATA_FORMAT, *PPACKET_FORMAT, *PDATA_FORMAT;
|
|
|
|
|
|
//
|
|
// Used as an Info Struct for Out of Order Reassembly
|
|
//
|
|
|
|
typedef struct _REASSEMBLY_CURRENT_INFO
|
|
{
|
|
PMDL pCurrMdl;
|
|
PNDIS_BUFFER pCurrNdisBuffer;
|
|
PADDRESS_FIFO pCurrFifo;
|
|
PISOCH_DESCRIPTOR pCurrIsoch;
|
|
|
|
} REASSEMBLY_CURRENT_INFO, *PREASSEMBLY_CURRENT_INFO ;
|
|
|
|
typedef enum _REASSEMBLY_INSERT_TYPE
|
|
{
|
|
Unacceptable,
|
|
InsertAsFirst,
|
|
InsertInMiddle,
|
|
InsertAtEnd
|
|
|
|
}REASSEMBLY_INSERT_TYPE, *PREASSEMBLY_INSERT_TYPE;
|
|
|
|
//
|
|
// This is used as a descriptor for indicated fragments that are waiting for reassembly
|
|
//
|
|
|
|
typedef struct _FRAGMENT_DESCRIPTOR
|
|
{
|
|
ULONG Offset; // Offset of the incoming fragment
|
|
ULONG IPLength; // Length of the fragment
|
|
PNDIS_BUFFER pNdisBuffer; // NdisBufferpointing to actual data
|
|
PMDL pMdl; // Mdl that belongs to the bus
|
|
NDIS1394_FRAGMENT_HEADER FragHeader; // Fragment header of the Descriptor
|
|
|
|
union
|
|
{
|
|
PADDRESS_FIFO pFifo;
|
|
PISOCH_DESCRIPTOR pIsoch;
|
|
PVOID pCommon;
|
|
PSINGLE_LIST_ENTRY pListEntry;
|
|
|
|
}IndicatedStructure;
|
|
|
|
|
|
} FRAGMENT_DESCRIPTOR, *PFRAGMENT_DESCRIPTOR;
|
|
|
|
//
|
|
// Reassembly structure : An instance of the reassembly is created for
|
|
// every packet that is being reassembled. It contains all the relevant
|
|
// bookkeeping information
|
|
//
|
|
// This needs to be allocated from a lookaside list
|
|
// Each PDO will contain a list of all outstanding packets that are being reassembled/
|
|
//
|
|
|
|
//
|
|
// REASSEMBLY_NOT_TOUCHED - Each reassembly structure will be marked as Not touched
|
|
// in the timer routine. If the flag is not cleared by the next
|
|
// invocation of the timer, this structure will be freed
|
|
// REASSMEBLY_FREED - The structure is about to be thrown away.
|
|
#define REASSEMBLY_NOT_TOUCHED 1
|
|
#define REASSEMBLY_FREED 2
|
|
#define REASSEMBLY_ABORTED 4
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct _NDIS1394_REASSEMBLY_STRUCTURE
|
|
{
|
|
|
|
//
|
|
// Reference Count - Interlocked access only
|
|
//
|
|
ULONG Ref;
|
|
|
|
//
|
|
// Next Reassembly Structure
|
|
//
|
|
LIST_ENTRY ReassemblyListEntry;
|
|
|
|
//
|
|
// Tag - used for memory validatation
|
|
//
|
|
ULONG Tag;
|
|
//
|
|
// Receive Operation
|
|
//
|
|
BUS_OPERATION ReceiveOp;
|
|
|
|
|
|
//
|
|
// Dgl - Datagram label. Unique for every reassembly structure gernerated by this local host
|
|
//
|
|
USHORT Dgl;
|
|
|
|
//
|
|
// Ether type of the reassembled packet . Populated in the first fragment
|
|
//
|
|
USHORT EtherType;
|
|
//
|
|
// pRemoteNode -> RemoteNode + Dgl are unique for each reassembly structure
|
|
//
|
|
PREMOTE_NODE pRemoteNode;
|
|
|
|
//
|
|
// Flags pertaining to the reassembly
|
|
//
|
|
ULONG Flags;
|
|
|
|
//
|
|
// ExpectedFragmentOffset is computed by the LAST Fragment's Offset +
|
|
// length of fragment. Does not account for gaps in the reassembled packet.
|
|
//
|
|
ULONG ExpectedFragmentOffset; // Last is based on offset, not time of indication
|
|
|
|
//
|
|
// Buffer Size - total length of the datagram being reassembled
|
|
//
|
|
ULONG BufferSize;
|
|
|
|
//
|
|
// Bytes Received So far
|
|
//
|
|
ULONG BytesRecvSoFar;
|
|
|
|
//
|
|
// Head NdisBuffer
|
|
//
|
|
PNDIS_BUFFER pHeadNdisBuffer;
|
|
|
|
//
|
|
// LastNdisBuffer that was appended to the packet
|
|
//
|
|
PNDIS_BUFFER pTailNdisBuffer;
|
|
|
|
//
|
|
// Mdl chain Head - pointing to the actual indicated fragment
|
|
//
|
|
PMDL pHeadMdl;
|
|
|
|
//
|
|
//Mdl Chain Tail - pointing to the last Mdl in the list
|
|
//
|
|
PMDL pTailMdl ;
|
|
//
|
|
// Packet that is being reassembled
|
|
//
|
|
PNDIS_PACKET pNdisPacket;
|
|
|
|
//
|
|
// NumOfFragmentsSoFar;
|
|
//
|
|
ULONG NumOfFragmentsSoFar;
|
|
|
|
//
|
|
// Pointer to the head of the MDL chain that the 1394 bus
|
|
// driver is indicating up. Will be used to return the buffers to
|
|
// the BusDriver
|
|
//
|
|
union
|
|
{
|
|
PADDRESS_FIFO pAddressFifo;
|
|
PISOCH_DESCRIPTOR pIsochDescriptor;
|
|
PVOID pCommon;
|
|
} Head;
|
|
|
|
//
|
|
// Last - Last Mdl that was appended to this packet in the reassembly structure
|
|
//
|
|
|
|
union
|
|
{
|
|
PADDRESS_FIFO pAddressFifo;
|
|
PISOCH_DESCRIPTOR pIsochDescriptor;
|
|
PVOID pCommon;
|
|
|
|
} Tail;
|
|
|
|
//
|
|
// Flag to signal if any out of order fragments were received. Default FALSE
|
|
//
|
|
BOOLEAN OutOfOrder;
|
|
|
|
//
|
|
// Flag to indicate if all fragments are completed . Default False
|
|
//
|
|
BOOLEAN fReassemblyComplete;
|
|
|
|
//
|
|
// Vc that this packet is being assembled for
|
|
//
|
|
PVCCB pVc;
|
|
|
|
//
|
|
// MaxIndex in the Fragment Table.
|
|
// At all times, MaxOffset points to an first empty element in the array
|
|
//
|
|
ULONG MaxOffsetTableIndex;
|
|
|
|
//
|
|
// FragmentOffset Table
|
|
//
|
|
FRAGMENT_DESCRIPTOR FragTable[MAX_ALLOWED_FRAGMENTS];
|
|
|
|
|
|
} NDIS1394_REASSEMBLY_STRUCTURE, *PDIS1394_REASSEMBLY_STRUCTURE, *PPDIS1394_REASSEMBLY_STRUCTURE;
|
|
|
|
|
|
//
|
|
// This structure is local to each Isoch descriptor or fifo that is indicated up
|
|
// to the nic1394 miniport. It stores all the local information extracted
|
|
// from the GASP header and Isoch Header
|
|
//
|
|
|
|
typedef struct
|
|
{
|
|
BUS_OPERATION RecvOp; // Fifo or Isoch Receive
|
|
PDATA_FORMAT p1394Data; // Start of 1394 pkt
|
|
ULONG Length1394; // Length of the 1394 data
|
|
PVOID pEncapHeader; // Points to start of frag/defrag encap header
|
|
ULONG DataLength; // length of the packet, from the EncapHeader
|
|
BOOLEAN fGasp; // Has GASP header
|
|
NDIS1394_UNFRAGMENTED_HEADER UnfragHeader; // Unfragmented header
|
|
NDIS1394_FRAGMENT_HEADER FragmentHeader; // Fragment Header
|
|
PGASP_HEADER pGaspHeader; // Gasp Header
|
|
PVOID pIndicatedData; // Data indicated up, includes the isoch header, unfrag headers
|
|
PMDL pMdl;
|
|
//
|
|
// Following information from the fragmented/unfragmented header...
|
|
//
|
|
BOOLEAN fFragmented; // Is fragmented
|
|
BOOLEAN fFirstFragment; // Is the First fragment
|
|
ULONG BufferSize;
|
|
ULONG FragmentOffset;
|
|
USHORT Dgl; // Dgl
|
|
ULONG lf; // Lf - Fragmented or not
|
|
ULONG EtherType; // Ethertype
|
|
PNDIS_BUFFER pNdisBuffer; // Ndis buffer - used to indicate data up.
|
|
PVOID pNdisBufferData; // Points to the start of the data that the Ndis Buffer points to
|
|
|
|
//
|
|
// Sender specific information here
|
|
//
|
|
USHORT SourceID;
|
|
PREMOTE_NODE pRemoteNode;
|
|
|
|
//
|
|
// Vc Specific Information here
|
|
//
|
|
PVCCB pVc;
|
|
PNIC_PACKET_POOL pPacketPool;
|
|
|
|
//
|
|
// Indication data
|
|
//
|
|
union
|
|
{
|
|
PADDRESS_FIFO pFifoContext;
|
|
PISOCH_DESCRIPTOR pIsochContext;
|
|
PVOID pCommon; // to be used in the common code path
|
|
|
|
}NdisPktContext;
|
|
|
|
} NIC_RECV_DATA_INFO, *PNIC_RECV_DATA_INFO;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Fragment Header as defined in the IP/1394 spec. Each packet greater than the MaxPayload
|
|
// will be split up into fragments and this header will be attached.
|
|
//
|
|
|
|
#define FRAGMENT_HEADER_LF_UNFRAGMENTED 0
|
|
#define FRAGMENT_HEADER_LF_FIRST_FRAGMENT 1
|
|
#define FRAGMENT_HEADER_LF_LAST_FRAGMENT 2
|
|
#define FRAGMENT_HEADER_LF_INTERIOR_FRAGMENT 3
|
|
|
|
|
|
typedef struct _INDICATE_RSVD
|
|
{
|
|
PNDIS_PACKET pPacket;
|
|
PVCCB pVc;
|
|
PADAPTERCB pAdapter;
|
|
LIST_ENTRY Link;
|
|
ULONG Tag;
|
|
|
|
} INDICATE_RSVD, *PINDICATE_RSVD;
|
|
|
|
|
|
|
|
typedef struct _RSVD
|
|
{
|
|
|
|
UCHAR Mandatory[PROTOCOL_RESERVED_SIZE_IN_PACKET]; // mandatory ndis requirement
|
|
INDICATE_RSVD IndicateRsvd; // to be used as extra context
|
|
|
|
#ifdef USE_RECV_TIMER
|
|
|
|
NDIS_MINIPORT_TIMER RcvIndicateTimer; // Used as a timer for win9x. All rcv Indicates are done here
|
|
|
|
#endif
|
|
|
|
} RSVD, *PRSVD;
|
|
|
|
|
|
|
|
//
|
|
// Used only in Win9x as a context for the send timer routine
|
|
//
|
|
typedef struct _NDIS_SEND_CONTEXT
|
|
{
|
|
LIST_ENTRY Link;
|
|
PVCCB pVc;
|
|
|
|
|
|
}NDIS_SEND_CONTEXT, *PNDIS_SEND_CONTEXT;
|
|
|
|
|
|
typedef struct _NDIS_STATUS_CONTEXT
|
|
{
|
|
LIST_ENTRY Link;
|
|
IN NDIS_STATUS GeneralStatus;
|
|
IN PVOID StatusBuffer;
|
|
IN UINT StatusBufferSize;
|
|
|
|
|
|
}NDIS_STATUS_CONTEXT, *PNDIS_STATUS_CONTEXT;
|
|
|
|
|
|
|
|
//
|
|
// This is the Irb structure used by the Bus Driver.
|
|
// There is extra room allocated at the end for the miniport's Context
|
|
//
|
|
|
|
typedef struct _NDIS1394_IRB
|
|
{
|
|
//
|
|
// Original Irb used by the bus driver
|
|
//
|
|
IRB Irb;
|
|
|
|
//
|
|
// Adapter - local host -optional
|
|
//
|
|
PADAPTERCB pAdapter;
|
|
|
|
//
|
|
// remote node to which the Irp was sent - optional
|
|
//
|
|
PREMOTE_NODE pRemoteNode;
|
|
|
|
//
|
|
// VC for which the Irp was sent. - optional
|
|
//
|
|
PVCCB pVc;
|
|
|
|
//
|
|
// Context if any - optinal
|
|
//
|
|
PVOID Context;
|
|
|
|
|
|
}NDIS1394_IRB, *PNDIS1394_IRB;
|
|
|
|
|
|
|
|
|
|
#pragma pack (push, 1)
|
|
|
|
|
|
typedef ULONG IP_ADDRESS;
|
|
|
|
//* Structure of an Ethernet header (taken from ip\arpdef.h).
|
|
typedef struct ENetHeader {
|
|
ENetAddr eh_daddr;
|
|
ENetAddr eh_saddr;
|
|
USHORT eh_type;
|
|
} ENetHeader;
|
|
|
|
|
|
|
|
// Structure of an Ethernet ARP packet.
|
|
//
|
|
typedef struct {
|
|
ENetHeader header;
|
|
USHORT hardware_type;
|
|
USHORT protocol_type;
|
|
UCHAR hw_addr_len;
|
|
UCHAR IP_addr_len;
|
|
USHORT opcode; // Opcode.
|
|
ENetAddr sender_hw_address;
|
|
IP_ADDRESS sender_IP_address;
|
|
ENetAddr target_hw_address;
|
|
IP_ADDRESS target_IP_address;
|
|
|
|
} ETH_ARP_PKT, *PETH_ARP_PKT;
|
|
|
|
|
|
|
|
#pragma pack (pop)
|
|
|
|
// These are ethernet arp specific constants
|
|
//
|
|
#define ARP_ETH_ETYPE_IP 0x800
|
|
#define ARP_ETH_ETYPE_ARP 0x806
|
|
#define ARP_ETH_REQUEST 1
|
|
#define ARP_ETH_RESPONSE 2
|
|
#define ARP_ETH_HW_ENET 1
|
|
#define ARP_ETH_HW_802 6
|
|
|
|
typedef enum _ARP_ACTION {
|
|
|
|
LoadArp = 1,
|
|
UnloadArp ,
|
|
UnloadArpNoRequest,
|
|
BindArp
|
|
}ARP_ACTION , *PARP_ACTION;
|
|
|
|
|
|
typedef struct _ARP_INFO{
|
|
//
|
|
// List entry to handle serialization of requests to ARP
|
|
//
|
|
|
|
LIST_ENTRY Link;
|
|
|
|
//
|
|
// Action to be done by the Arp module
|
|
//
|
|
ARP_ACTION Action;
|
|
|
|
//
|
|
// Request to be compeleted - optional
|
|
//
|
|
PNDIS_REQUEST pRequest;
|
|
|
|
} ARP_INFO, *PARP_INFO;
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Macros/inlines
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// These basics are not in the DDK headers for some reason.
|
|
//
|
|
#define min( a, b ) (((a) < (b)) ? (a) : (b))
|
|
#define max( a, b ) (((a) > (b)) ? (a) : (b))
|
|
|
|
#define InsertBefore( pNewL, pL ) \
|
|
{ \
|
|
(pNewL)->Flink = (pL); \
|
|
(pNewL)->Blink = (pL)->Blink; \
|
|
(pNewL)->Flink->Blink = (pNewL); \
|
|
(pNewL)->Blink->Flink = (pNewL); \
|
|
}
|
|
|
|
#define InsertAfter( pNewL, pL ) \
|
|
{ \
|
|
(pNewL)->Flink = (pL)->Flink; \
|
|
(pNewL)->Blink = (pL); \
|
|
(pNewL)->Flink->Blink = (pNewL); \
|
|
(pNewL)->Blink->Flink = (pNewL); \
|
|
}
|
|
|
|
|
|
// Winsock-ish host/network byte order converters for short and long integers.
|
|
//
|
|
#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
|
|
#define htons(x) _byteswap_ushort((USHORT)(x))
|
|
#define htonl(x) _byteswap_ulong((ULONG)(x))
|
|
#else
|
|
#define htons( a ) ((((a) & 0xFF00) >> 8) |\
|
|
(((a) & 0x00FF) << 8))
|
|
#define htonl( a ) ((((a) & 0xFF000000) >> 24) | \
|
|
(((a) & 0x00FF0000) >> 8) | \
|
|
(((a) & 0x0000FF00) << 8) | \
|
|
(((a) & 0x000000FF) << 24))
|
|
#endif
|
|
#define ntohs( a ) htons(a)
|
|
#define ntohl( a ) htonl(a)
|
|
|
|
// Place in a TRACE argument list to correspond with a format of "%d.%d.%d.%d"
|
|
// to print network byte-ordered IP address 'x' in human readable form.
|
|
//
|
|
#define IPADDRTRACE( x ) ((x) & 0x000000FF), \
|
|
(((x) >> 8) & 0x000000FF), \
|
|
(((x) >> 16) & 0x000000FF), \
|
|
(((x) >> 24) & 0x000000FF)
|
|
|
|
// Place in a TRACE argument list to correspond with a format of "%d" to print
|
|
// a percentage of two integers, or an average of two integers, or those
|
|
// values rounded.
|
|
//
|
|
#define PCTTRACE( n, d ) ((d) ? (((n) * 100) / (d)) : 0)
|
|
#define AVGTRACE( t, c ) ((c) ? ((t) / (c)) : 0)
|
|
#define PCTRNDTRACE( n, d ) ((d) ? (((((n) * 1000) / (d)) + 5) / 10) : 0)
|
|
#define AVGRNDTRACE( t, c ) ((c) ? (((((t) * 10) / (c)) + 5) / 10) : 0)
|
|
|
|
// All memory allocations and frees are done with these ALLOC_*/FREE_*
|
|
// macros/inlines to allow memory management scheme changes without global
|
|
// editing. For example, might choose to lump several lookaside lists of
|
|
// nearly equal sized items into a single list for efficiency.
|
|
//
|
|
// NdisFreeMemory requires the length of the allocation as an argument. NT
|
|
// currently doesn't use this for non-paged memory, but according to JameelH,
|
|
// Windows95 does. These inlines stash the length at the beginning of the
|
|
// allocation, providing the traditional malloc/free interface. The
|
|
// stash-area is a ULONGLONG so that all allocated blocks remain ULONGLONG
|
|
// aligned as they would be otherwise, preventing problems on Alphas.
|
|
//
|
|
__inline
|
|
VOID*
|
|
ALLOC_NONPAGED(
|
|
IN ULONG ulBufLength,
|
|
IN ULONG ulTag )
|
|
{
|
|
CHAR* pBuf;
|
|
|
|
NdisAllocateMemoryWithTag(
|
|
&pBuf, (UINT )(ulBufLength + MEMORY_ALLOCATION_ALIGNMENT), ulTag );
|
|
if (!pBuf)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
((ULONG* )pBuf)[ 0 ] = ulBufLength;
|
|
((ULONG* )pBuf)[ 1 ] = ulTag;
|
|
return (pBuf + MEMORY_ALLOCATION_ALIGNMENT);
|
|
}
|
|
|
|
__inline
|
|
VOID
|
|
FREE_NONPAGED(
|
|
IN VOID* pBuf )
|
|
{
|
|
ULONG ulBufLen;
|
|
|
|
ulBufLen = *((ULONG* )(((CHAR* )pBuf) - MEMORY_ALLOCATION_ALIGNMENT));
|
|
NdisFreeMemory(
|
|
((CHAR* )pBuf) - MEMORY_ALLOCATION_ALIGNMENT,
|
|
(UINT )(ulBufLen + MEMORY_ALLOCATION_ALIGNMENT),
|
|
0 );
|
|
}
|
|
|
|
#define ALLOC_NDIS_WORK_ITEM( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistWorkItems )
|
|
#define FREE_NDIS_WORK_ITEM( pA, pNwi ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistWorkItems, (pNwi) )
|
|
|
|
#define ALLOC_TIMERQITEM( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistTimerQItems )
|
|
#define FREE_TIMERQITEM( pA, pTqi ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistTimerQItems, (pTqi) )
|
|
|
|
#define ALLOC_TUNNELCB( pA ) \
|
|
ALLOC_NONPAGED( sizeof(TUNNELCB), MTAG_TUNNELCB )
|
|
#define FREE_TUNNELCB( pA, pT ) \
|
|
FREE_NONPAGED( pT )
|
|
|
|
#define ALLOC_VCCB( pA ) \
|
|
ALLOC_NONPAGED( sizeof(VCCB), MTAG_VCCB )
|
|
#define FREE_VCCB( pA, pV ) \
|
|
FREE_NONPAGED( pV )
|
|
|
|
#define ALLOC_TIMERQ( pA ) \
|
|
ALLOC_NONPAGED( sizeof(TIMERQ), MTAG_TIMERQ )
|
|
#define FREE_TIMERQ( pA, pTq ) \
|
|
FREE_NONPAGED( pTq )
|
|
|
|
//
|
|
// Log packet macro
|
|
//
|
|
#ifdef PKT_LOG
|
|
|
|
#define NIC1394_ALLOC_PKTLOG(_pAdapter) \
|
|
nic1394AllocPktLog(_pAdapter)
|
|
|
|
#define NIC1394_DEALLOC_PKTLOG(_pAdapter) \
|
|
Nic1394DeallocPktLog(_pAdapter)
|
|
|
|
#define NIC1394_LOG_PKT(_pAdapter, _Flags, _SourceID, _DestID, _pvData, _cbData)\
|
|
(((_pAdapter)->pPktLog) ? \
|
|
Nic1394LogPkt( \
|
|
(_pAdapter)->pPktLog, \
|
|
(_Flags), \
|
|
(_SourceID), \
|
|
(_DestID), \
|
|
(_pvData), \
|
|
(_cbData) \
|
|
) \
|
|
: 0)
|
|
#else
|
|
|
|
#define NIC1394_ALLOC_PKTLOG(_pAdapter)
|
|
#define NIC1394_DEALLOC_PKTLOG(_pAdapter)
|
|
#define NIC1394_LOG_PKT(_pAdapter, _Flags, _SourceID, _DestID, _pvData, _cbData)
|
|
|
|
#endif
|
|
|
|
#define NIC1394_LOGFLAGS_RECV_CHANNEL 0x00000001
|
|
#define NIC1394_LOGFLAGS_SEND_FIFO 0x00000010
|
|
#define NIC1394_LOGFLAGS_SEND_CHANNEL 0x00000011
|
|
#define NIC1394_LOGFLAGS_RECV_FIFO 0x00000100
|
|
#define NIC1394_LOGFLAGS_BCM_FAILED 0x00001000
|
|
#define NIC1394_LOGFLAGS_BCM_IS_IRM_TIMEOUT 0x00002000
|
|
#define NIC1394_LOGFLAGS_BCM_NOT_IRM_TIMEOUT 0x00004000
|
|
#define NIC1394_LOGFLAGS_BCM_IRM_NOT_FOUND 0x00008000
|
|
|
|
#if 0
|
|
//
|
|
// To get the MaxRec we extract the 0xf000 nibble
|
|
//
|
|
#define GET_MAXREC_FROM_BUSCAPS(_pBus, _pMaxRec) \
|
|
{ \
|
|
ULONG _LitEnd = SWAPBYTES_ULONG(_pBus); \
|
|
_LitEnd = _LitEnd & 0xf000; \
|
|
_LitEnd = _LitEnd >> 12; \
|
|
*(_pBusRec) = _LitEnd; \
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// To get the MaxRec we extract the 0xf000 nibble
|
|
//
|
|
#define GET_MAXREC_FROM_BUSCAPS(_Bus) (((_Bus) & 0xf00000) >> 20);
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// F L A G S & L O C K S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//
|
|
// These macros are just present to make accessing the VC's flags easier
|
|
// and concentrate the implementations at one place
|
|
//
|
|
#define VC_TEST_FLAG(_V, _F) ((nicReadFlags(&(_V)->Hdr.ulFlags) & (_F))!= 0)
|
|
#define VC_SET_FLAG(_V, _F) (nicSetFlags(&(_V)->Hdr.ulFlags, (_F)))
|
|
#define VC_CLEAR_FLAGS(_V, _F) (nicClearFlags(&(_V)->Hdr.ulFlags , (_F)))
|
|
#define VC_TEST_FLAGS(_V, _F) ((nicReadFlags(&(_V)->Hdr.ulFlags) & (_F)) == (_F))
|
|
#define VC_READ_FLAGS(_V) ((nicReadFlags(&(_V)->Hdr.ulFlags)
|
|
#define VC_ACTIVE(_V) (((_V)->Hdr.ulFlags & (VCBF_CloseCallPending | VCBF_VcDeleted | VCBF_VcActivated |VCBF_MakeCallPending )) == VCBF_VcActivated)
|
|
|
|
|
|
|
|
#define REMOTE_NODE_TEST_FLAG(_P, _F ) ((nicReadFlags(&(_P)->ulFlags) & (_F))!= 0)
|
|
#define REMOTE_NODE_SET_FLAG(_P, _F) (nicSetFlags(&(_P)->ulFlags, (_F)))
|
|
#define REMOTE_NODE_CLEAR_FLAGS(_P, _F) (nicClearFlags(&(_P)->ulFlags , (_F)))
|
|
#define REMOTE_NODE_TEST_FLAGS(_P, _F) ((nicReadFlags(&(_P)->ulFlags) & (_F)) == (_F))
|
|
#define REMOTE_NODE_READ_FLAGS(_P) ((nicReadFlags(&(_P)->ulFlags)
|
|
#define REMOTE_NODE_ACTIVE(_P) (((_P)->ulFlags & (PDO_Activated | PDO_BeingRemoved)) == PDO_Activated)
|
|
|
|
#define ADAPTER_TEST_FLAG(_A, _F) ((nicReadFlags(&(_A)->ulFlags) & (_F))!= 0)
|
|
#define ADAPTER_SET_FLAG(_A, _F) (nicSetFlags(&(_A)->ulFlags, (_F)))
|
|
#define ADAPTER_CLEAR_FLAG(_A, _F) (nicClearFlags(&(_A)->ulFlags , (_F)))
|
|
#define ADAPTER_TEST_FLAGS(_A, _F) ((nicReadFlags(&(_A)->ulFlags) & (_F)) == (_F))
|
|
#define ADAPTER_READ_FLAGS(_A) ((nicReadFlags(&(_A)->ulFlags)
|
|
#define ADAPTER_ACTIVE(_A) ((((_A)->ulFlags) & fADAPTER_VDOInactive) != fADAPTER_VDOInactive)
|
|
|
|
#define BCR_TEST_FLAG(_A, _F) ((nicReadFlags(&(_A)->BCRData.Flags) & (_F))!= 0)
|
|
#define BCR_SET_FLAG(_A, _F) (nicSetFlags(&(_A)->BCRData.Flags, (_F)))
|
|
#define BCR_CLEAR_FLAG(_A, _F) (nicClearFlags(&(_A)->BCRData.Flags , (_F)))
|
|
#define BCR_CLEAR_ALL_FLAGS(_A) ((_A)->BCRData.Flags = 0)
|
|
#define BCR_TEST_FLAGS(_A, _F) ((nicReadFlags(&(_A)->BCRData.Flags) & (_F)) != 0)
|
|
#define BCR_READ_FLAGS(_A) ((nicReadFlags(&(_A)->BCRData.Flags)
|
|
#define BCR_IS_VALID(_B) ((_B)->NC_One == 1 && (_B)->NC_Valid ==1)
|
|
#define IS_A_BCR(_B) ((_B)->NC_One == 1 )
|
|
|
|
#define LOOKASIDE_HEADER_SET_FLAG(_H, _F) (nicSetFlags(&(_H)->State.u.Flags, (_F)))
|
|
#define LOOKASIDE_HEADER_TEST_FLAG(_H, _F) ((nicReadFlags(&(_H)->State.u.Flags) & (_F))!= 0)
|
|
|
|
#define REASSEMBLY_ACTIVE(_R) (((_R)->Flags & (REASSEMBLY_ABORTED | REASSEMBLY_FREED)) == 0)
|
|
#define REASSEMBLY_TEST_FLAG(_R,_F) ((nicReadFlags(&(_R)->Flags) & (_F))!= 0)
|
|
#define REASSEMBLY_SET_FLAG(_R,_F) (nicSetFlags(&(_R)->Flags, (_F)))
|
|
#define REASSEMBLY_CLEAR_FLAG(_R,_F) (nicClearFlags(&(_R)->Flags , (_F)))
|
|
|
|
|
|
#define NIC_GET_SYSTEM_ADDRESS_FOR_MDL(_M) MmGetSystemAddressForMdl(_M)
|
|
#define NIC_GET_BYTE_COUNT_FOR_MDL(_M) MmGetMdlByteCount(_M)
|
|
|
|
#define nicNdisBufferVirtualAddress(_N) NdisBufferVirtualAddress(_N)
|
|
#define nicNdisBufferLength(_N) NdisBufferLength(_N)
|
|
|
|
//
|
|
// These macros are used to assert that the IRQL level remains the same
|
|
// at the beginning and end of a function
|
|
//
|
|
#if DBG
|
|
|
|
#define STORE_CURRENT_IRQL UCHAR OldIrql = KeGetCurrentIrql();
|
|
#define MATCH_IRQL ASSERT (OldIrql == KeGetCurrentIrql() );
|
|
|
|
#else
|
|
|
|
#define STORE_CURRENT_IRQL
|
|
#define MATCH_IRQL
|
|
#endif // if DBG
|
|
|
|
//
|
|
// Macros used to access the Reference Structure (not used yet)
|
|
//
|
|
#define NIC_INCREMENT_REF (_R) nicReferenceRef (_R);
|
|
#define NIC_DEREFERENCE_REF (_R) nicDereferenceRef (_R)
|
|
|
|
|
|
#define nicInitializeCallRef(_pV) nicInitializeRef (&(_pV)->Hdr.CallRef);
|
|
#define nicCloseCallRef(_pV) nicCloseRef (&(_pV)->Hdr.CallRef);
|
|
|
|
|
|
|
|
//
|
|
// Macros used to acquire and release lock by the data structures (Vc, AF, Adapter)
|
|
// Right now, they all point to the same lock (i.e.) the lock in the Adapter structure
|
|
//
|
|
|
|
#define VC_ACQUIRE_LOCK(_pVc) NdisAcquireSpinLock (_pVc->Hdr.plock);
|
|
#define VC_RELEASE_LOCK(_pVc) NdisReleaseSpinLock (_pVc->Hdr.plock);
|
|
|
|
#define AF_ACQUIRE_LOCK(_pAF) NdisAcquireSpinLock (&_pAF->pAdapter->lock);
|
|
#define AF_RELEASE_LOCK(_pAF) NdisReleaseSpinLock (&_pAF->pAdapter->lock);
|
|
|
|
#define ADAPTER_ACQUIRE_LOCK(_pA) NdisAcquireSpinLock (&_pA->lock);
|
|
#define ADAPTER_RELEASE_LOCK(_pA) NdisReleaseSpinLock (&_pA->lock);
|
|
|
|
#define REMOTE_NODE_ACQUIRE_LOCK(_pP) NdisAcquireSpinLock (&_pP->pAdapter->lock);
|
|
#define REMOTE_NODE_RELEASE_LOCK(_pP) NdisReleaseSpinLock (&_pP->pAdapter->lock);
|
|
|
|
#define REASSEMBLY_ACQUIRE_LOCK(_R) REMOTE_NODE_REASSEMBLY_ACQUIRE_LOCK(_R->pRemoteNode);
|
|
#define REASSEMBLY_RELEASE_LOCK(_R) REMOTE_NODE_REASSEMBLY_RELEASE_LOCK(_R->pRemoteNode);
|
|
|
|
#ifdef TRACK_LOCKS
|
|
|
|
|
|
#define REMOTE_NODE_REASSEMBLY_ACQUIRE_LOCK(_Remote) \
|
|
nicAcquireSpinLock (&_Remote->ReassemblyLock , __FILE__ , __LINE__);
|
|
|
|
|
|
#define REMOTE_NODE_REASSEMBLY_RELEASE_LOCK(_Remote) \
|
|
nicReleaseSpinLock (&_Remote->ReassemblyLock , __FILE__ , __LINE__);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define REMOTE_NODE_REASSEMBLY_ACQUIRE_LOCK(_Remote) NdisAcquireSpinLock (&_Remote->ReassemblyLock.NdisLock);
|
|
#define REMOTE_NODE_REASSEMBLY_RELEASE_LOCK(_Remote) NdisReleaseSpinLock (&_Remote->ReassemblyLock.NdisLock);
|
|
|
|
#endif
|
|
|
|
|
|
#define REASSEMBLY_APPEND_FRAG_DESC(_pR, _Off, _Len) \
|
|
_pR->FragTable[_pR->MaxOffsetTableIndex].Offset =_Off; \
|
|
_pR->FragTable[_pR->MaxOffsetTableIndex].IPLength = _Len; \
|
|
_pR->MaxOffsetTableIndex++;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// S T A T S & F A I L U R E M A C R O S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
// Used to distinguish stats collected that are collected in the various code paths
|
|
|
|
typedef enum
|
|
{
|
|
ChannelCodePath,
|
|
FifoCodePath,
|
|
ReceiveCodePath,
|
|
NoMoreCodePaths
|
|
};
|
|
|
|
|
|
#if TRACK_FAILURE
|
|
|
|
extern ULONG BusFailure;
|
|
extern ULONG MallocFailure;
|
|
extern ULONG IsochOverwrite;
|
|
extern ULONG MaxIndicatedFifos;
|
|
|
|
#define nicInitTrackFailure() BusFailure = 0;MallocFailure= 0;
|
|
|
|
#define nicIncrementBusFailure() NdisInterlockedIncrement(&BusFailure);
|
|
#define nicIncrementMallocFailure() NdisInterlockedIncrement(&MallocFailure);
|
|
#define nicIsochOverwritten() NdisInterlockedIncrement(&IsochOverwrite);
|
|
|
|
#define nicStatsRecordNumIndicatedFifos(_Num) \
|
|
{ \
|
|
ULONG _N_ = (_Num); \
|
|
ASSERT((_N_) <= 100); \
|
|
MaxIndicatedFifos = max((_N_), MaxIndicatedFifos); \
|
|
}
|
|
|
|
#define nicIncChannelSendMdl() NdisInterlockedIncrement(&MdlsAllocated[ChannelCodePath]);
|
|
#define nicIncFifoSendMdl() NdisInterlockedIncrement(&MdlsAllocated[FifoCodePath]);
|
|
|
|
#define nicDecChannelSendMdl() NdisInterlockedIncrement(&MdlsFreed[ChannelCodePath]);
|
|
#define nicDecFifoSendMdl() NdisInterlockedIncrement(&MdlsFreed[FifoCodePath]);
|
|
|
|
#define nicIncChannelRecvBuffer() NdisInterlockedIncrement(&NdisBufferAllocated[ChannelCodePath]);
|
|
#define nicIncFifoRecvBuffer() NdisInterlockedIncrement(&NdisBufferAllocated[FifoCodePath]);
|
|
|
|
#define nicDecChannelRecvBuffer() NdisInterlockedIncrement(&NdisBufferFreed[ChannelCodePath]);
|
|
#define nicDecFifoRecvBuffer() NdisInterlockedIncrement(&NdisBufferFreed[FifoCodePath]);
|
|
|
|
|
|
#define nicIncRecvBuffer(_bisFifo) \
|
|
{ \
|
|
if (_bisFifo) \
|
|
{ nicIncFifoRecvBuffer(); } \
|
|
else \
|
|
{ nicIncChannelRecvBuffer();} \
|
|
}
|
|
|
|
#define nicDecRecvBuffer(_bisFifo) \
|
|
{ \
|
|
if (_bisFifo) \
|
|
{ nicDecFifoRecvBuffer(); } \
|
|
else \
|
|
{ nicDecChannelRecvBuffer(); }\
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
#define nicInitTrackFailure()
|
|
#define nicIncrementBusFailure()
|
|
#define nicIncrementMallocFailure()
|
|
#define nicIsochOverwritten()
|
|
#define nicStatsRecordNumIndicatedFifos(_Num)
|
|
#define nicIncChannelSendMdl()
|
|
#define nicIncFifoSendMdl()
|
|
#define nicDecChannelSendMdl()
|
|
#define nicDecFifoSendMdl()
|
|
#define nicFreeMdlRecordStat()
|
|
|
|
#endif
|
|
|
|
|
|
#if QUEUED_PACKETS_STATS
|
|
|
|
|
|
extern ULONG RcvTimerCount;
|
|
extern ULONG SendTimerCount;
|
|
|
|
#define nicInitQueueStats() \
|
|
NdisZeroMemory (&SendStats, sizeof(SendStats) ); \
|
|
NdisZeroMemory (&RcvStats, sizeof(RcvStats) ); \
|
|
nicMaxRcv = 0; \
|
|
nicMaxSend = 0;
|
|
|
|
|
|
#define nicSetCountInHistogram(_PktsInQueue, _Stats) NdisInterlockedIncrement (&(_Stats.Bucket [ (_PktsInQueue/10) ] ) );
|
|
#define nicIncrementRcvTimerCount() NdisInterlockedIncrement(&RcvTimerCount);
|
|
#define nicIncrementSendTimerCount() NdisInterlockedIncrement(&SendTimerCount);
|
|
#define nicSetMax(_nicMax, _PktsInQueue) _nicMax = max(_nicMax, _PktsInQueue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define nicInitQueueStats()
|
|
#define nicSetCountInHistogram(_PktsInQueue, _Stats)
|
|
#define nicSetMax(_nicMax, _PktsInQueue)
|
|
#define nicIncrementRcvTimerCount()
|
|
#define nicIncrementSendTimerCount()
|
|
|
|
#endif
|
|
//
|
|
// Isoch descriptor macros - Used in the send/recv code path
|
|
//
|
|
typedef enum
|
|
{
|
|
IsochNext,
|
|
IsochTag,
|
|
IsochChannelVc,
|
|
MaxIsochContextIndex
|
|
|
|
} IsochContextIndex;
|
|
|
|
//
|
|
// The following structure is used to add more contexts to a work item.
|
|
// NOTE: the Adapter is passed in as the context always.
|
|
//
|
|
typedef union _NIC_WORK_ITEM
|
|
{
|
|
NDIS_WORK_ITEM NdisWorkItem;
|
|
|
|
struct{
|
|
NDIS_WORK_ITEM NdisWorkItem;
|
|
PNDIS_REQUEST pNdisRequest;
|
|
VCCB* pVc;
|
|
} RequestInfo;
|
|
|
|
struct{
|
|
NDIS_WORK_ITEM NdisWorkItem;
|
|
ULONG Start;
|
|
PNDIS_REQUEST pNdisRequest;
|
|
} StartArpInfo;
|
|
|
|
|
|
struct {
|
|
NDIS_WORK_ITEM NdisWorkItem;
|
|
} Fifo;
|
|
|
|
} NIC_WORK_ITEM, *PNIC_WORK_ITEM;
|
|
|
|
#define STORE_CHANNELVC_IN_DESCRIPTOR(_pI,_pVc) (_pI)->DeviceReserved[IsochChannelVc] =(ULONG_PTR) _pVc
|
|
#define GET_CHANNELVC_FROM_DESCRIPTOR(_pI) (_pI)->DeviceReserved[IsochChannelVc]
|
|
|
|
#define MARK_ISOCH_DESCRIPTOR_INDICATED(_pI) \
|
|
(_pI)->DeviceReserved[IsochTag] = (ULONG)NIC1394_TAG_INDICATED; \
|
|
(_pI)->DeviceReserved[IsochNext] = 0;
|
|
|
|
|
|
#define MARK_ISOCH_DESCRIPTOR_IN_REASSEMBLY(_pI) \
|
|
(_pI)->DeviceReserved[IsochTag] = (ULONG)NIC1394_TAG_REASSEMBLY;
|
|
|
|
#define CLEAR_DESCRIPTOR_OF_NDIS_TAG(_pI) \
|
|
(_pI)->DeviceReserved[IsochTag] = 0;
|
|
|
|
|
|
#define APPEND_ISOCH_DESCRIPTOR(_Old, _New) \
|
|
(_Old)->DeviceReserved[IsochNext] = (ULONG_PTR)&((_New)->DeviceReserved[IsochNext]);
|
|
|
|
|
|
#define NEXT_ISOCH_DESCRIPTOR(_pI) (_pI)->DeviceReserved[IsochNext]
|
|
|
|
|
|
#define CLEAR_DESCRIPTOR_NEXT(_pI) (_pI)->DeviceReserved[IsochNext] = 0;
|
|
|
|
#define GET_MDL_FROM_IRB(_pM, _pI, _Op) \
|
|
if (_Op==AsyncWrite) \
|
|
{ \
|
|
_pM = _pI->u.AsyncWrite.Mdl; \
|
|
} \
|
|
else \
|
|
{ \
|
|
ASSERT (_Op == AsyncStream); \
|
|
_pM = _pI->u.AsyncStream.Mdl ; \
|
|
}
|
|
|
|
//
|
|
// Macros used to walk a doubly linked list. Only macros that are not defined in ndis.h
|
|
// The List Next macro will work on Single and Doubly linked list as Flink is a common
|
|
// field name in both
|
|
//
|
|
|
|
/*
|
|
PLIST_ENTRY
|
|
ListNext (
|
|
IN PLIST_ENTRY
|
|
);
|
|
|
|
PSINGLE_LIST_ENTRY
|
|
ListNext (
|
|
IN PSINGLE_LIST_ENTRY
|
|
);
|
|
*/
|
|
#define ListNext(_pL) (_pL)->Flink
|
|
|
|
/*
|
|
PLIST_ENTRY
|
|
ListPrev (
|
|
IN LIST_ENTRY *
|
|
);
|
|
*/
|
|
#define ListPrev(_pL) (_pL)->Blink
|
|
|
|
#define OnlyElementInList(_pL) (_pL->Flink == _pL->Blink ? TRUE : FALSE)
|
|
|
|
#define BREAK(_TM_Mode, _String) \
|
|
{ \
|
|
TRACE( TL_A, _TM_Mode, ( _String ) ); \
|
|
break; \
|
|
}
|
|
|
|
|
|
|
|
// USHORT
|
|
// SWAPBYTES_USHORT(USHORT Val )
|
|
//
|
|
#define SWAPBYTES_USHORT(Val) \
|
|
((((Val) & 0xff) << 8) | (((Val) & 0xff00) >> 8))
|
|
|
|
|
|
// ULONG
|
|
// SWAPBYTES_ULONG(ULONG Val )
|
|
//
|
|
|
|
#define SWAPBYTES_ULONG(Val) \
|
|
((((Val) & 0x000000ff) << 24) | \
|
|
(((Val) & 0x0000ff00) << 8) | \
|
|
(((Val) & 0x00ff0000) >> 8) | \
|
|
(((Val) & 0xff000000) >> 24) )
|
|
|
|
|
|
|
|
//
|
|
// nicRemoveEntry List
|
|
// Just add a check to make sure that we are actually pointing to a valid next
|
|
//
|
|
#define nicRemoveEntryList(_L) \
|
|
{ \
|
|
ASSERT ((_L)->Flink != (_L)); \
|
|
RemoveEntryList (_L); \
|
|
}
|
|
//#define nicFreeToNPagedLookasideList(_L, _E) NdisFreeToNPagedLookasideList(_L, _E)
|
|
//#define nicDeleteLookasideList(_L) NdisDeleteNPagedLookasideList(_L)
|
|
|
|
//
|
|
// Timing Query Routines
|
|
//
|
|
#define nicQueryTickCount() \
|
|
LARGE_INTEGER TickStart; \
|
|
KeQueryTickCount(&TickStart);
|
|
|
|
#define nicPrintElapsedTicks(_s) \
|
|
{ \
|
|
LARGE_INTEGER TickEnd, TickDiff; \
|
|
ULONG Increment = KeQueryTimeIncrement() ; \
|
|
KeQueryTickCount(&TickEnd); \
|
|
TickDiff.QuadPart = TickEnd.QuadPart - TickStart.QuadPart; \
|
|
TickDiff.QuadPart = (TickDiff.QuadPart * Increment); \
|
|
DbgPrint (_s); \
|
|
DbgPrint(" TickStart %x %x, Time End %x %x Time Diff %x %x Increment %x\n",TickStart.HighPart , TickStart.LowPart , TickEnd.HighPart, TickEnd.LowPart, TickDiff.HighPart, TickDiff.LowPart, Increment); \
|
|
}
|
|
|
|
|
|
#define nicEntryTimeStamp() \
|
|
UINT EntryMilliSec; \
|
|
EntryMilliSec= nicGetSystemTimeMilliSeconds();
|
|
|
|
|
|
|
|
|
|
#if DO_TIMESTAMPS
|
|
|
|
void
|
|
nicTimeStamp(
|
|
char *szFormatString,
|
|
UINT Val
|
|
);
|
|
|
|
#define TIMESTAMP(_FormatString) nicTimeStamp("TIMESTAMP %lu:%lu.%lu nic1394 " _FormatString "\n" , 0)
|
|
#define TIMESTAMP1(_FormatString, _Val) nicTimeStamp( "TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n" , (_Val))
|
|
|
|
|
|
|
|
#else // !DO_TIMESTAMPS
|
|
|
|
|
|
#define TIMESTAMP(_FormatString)
|
|
#define TIMESTAMP1(_FormatString, _Val)
|
|
|
|
#endif // !DO_TIMESTAMPS
|
|
|
|
|
|
#if ENTRY_EXIT_TIME
|
|
|
|
#define TIMESTAMP_ENTRY(_String) TIMESTAMP(_String)
|
|
#define TIMESTAMP_EXIT(_String) TIMESTAMP(_String)
|
|
|
|
#else
|
|
|
|
#define TIMESTAMP_ENTRY(s);
|
|
#define TIMESTAMP_EXIT(s);
|
|
|
|
#endif
|
|
|
|
|
|
#if INIT_HALT_TIME
|
|
|
|
#define TIMESTAMP_INITIALIZE() TIMESTAMP("==>InitializeHandler");
|
|
#define TIMESTAMP_HALT() TIMESTAMP("<==Halt");
|
|
|
|
#else
|
|
|
|
#define TIMESTAMP_INITIALIZE()
|
|
#define TIMESTAMP_HALT()
|
|
|
|
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// S T A T I S T I C M A C R O S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
|
// Reasembly counts
|
|
//
|
|
#define nicReassemblyStarted(_pAdapter) \
|
|
{ \
|
|
NdisInterlockedIncrement( &(_pAdapter->AdaptStats.TempStats.ulNumOutstandingReassemblies)); \
|
|
NdisInterlockedIncrement ( &(_pAdapter->Reassembly.PktsInQueue)); \
|
|
NdisInterlockedIncrement ( &(_pAdapter->OutstandingReassemblies));\
|
|
}
|
|
|
|
|
|
#define nicReassemblyCompleted(_A) \
|
|
{ \
|
|
NdisInterlockedDecrement(&(_A->AdaptStats.TempStats.ulNumOutstandingReassemblies));\
|
|
NdisInterlockedDecrement(&(_A->Reassembly.PktsInQueue));\
|
|
NdisInterlockedDecrement ( &(_A->OutstandingReassemblies));\
|
|
}
|
|
|
|
|
|
#define nicReassemblyAborted(_A) \
|
|
{ \
|
|
NdisInterlockedDecrement ( &(_A->OutstandingReassemblies)); \
|
|
NdisInterlockedIncrement (&(_A->AdaptStats.TempStats.ulAbortedReassemblies)); \
|
|
}
|
|
|
|
|
|
//
|
|
// Top level stat collection macros
|
|
//
|
|
|
|
#define nicIncrementRcvVcPktCount(_Vc, _Pkt) \
|
|
{ \
|
|
if ((_Vc)->Hdr.VcType == NIC1394_RecvFIFO) \
|
|
{ \
|
|
nicIncrementFifoRcvPktCount(_Vc, _Pkt); \
|
|
} \
|
|
else \
|
|
{ \
|
|
nicIncrementChannelRcvPktCount(_Vc, _Pkt); \
|
|
} \
|
|
}
|
|
|
|
#define nicIncrementVcSendPktCount(_Vc, _Pkt) \
|
|
{ \
|
|
if ((_Vc)->Hdr.VcType == NIC1394_SendFIFO) \
|
|
{ \
|
|
nicIncrementFifoSendPktCount(_Vc, _Pkt); \
|
|
} \
|
|
else \
|
|
{ \
|
|
nicIncrementChannelSendPktCount(_Vc, _Pkt); \
|
|
} \
|
|
}
|
|
|
|
|
|
#define nicIncrementVcSendFailures(_Vc, _Pkt) \
|
|
{ \
|
|
if ((_Vc)->Hdr.VcType == NIC1394_SendFIFO) \
|
|
{ \
|
|
nicIncrementFifoSendFailures(_Vc, _Pkt); \
|
|
} \
|
|
else \
|
|
{ \
|
|
nicIncrementChannelSendFailures(_Vc, _Pkt); \
|
|
} \
|
|
}
|
|
|
|
|
|
#define nicIncrementVcBusSendFailures(_Vc, _Pkt) \
|
|
{ \
|
|
if ((_Vc)->Hdr.VcType == NIC1394_SendFIFO) \
|
|
{ \
|
|
nicIncrementFifoBusSendFailures(_Vc, _Pkt); \
|
|
} \
|
|
else \
|
|
{ \
|
|
nicIncrementChannelBusSendFailures(_Vc, _Pkt); \
|
|
} \
|
|
}
|
|
|
|
#define nicIncrementVcBusSendSucess(_Vc, _Pkt) \
|
|
{ \
|
|
if ((_Vc)->Hdr.VcType == NIC1394_SendFIFO) \
|
|
{ \
|
|
nicIncrementFifoBusSendSucess(_Vc, _Pkt); \
|
|
} \
|
|
else \
|
|
{ \
|
|
nicIncrementChannelBusSendSucess(_Vc, _Pkt); \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Fifo counts
|
|
//
|
|
#define nicIncrementFifoSendPktCount(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Fifo.ulSendNicSucess));
|
|
#define nicIncrementFifoSendFailures(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Fifo.ulSendNicFail));
|
|
#define nicIncrementFifoBusSendFailures(_Vc,_Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Fifo.ulSendBusFail));
|
|
#define nicIncrementFifoBusSendSucess(_Vc,_Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Fifo.ulSendBusSuccess));
|
|
#define nicIncrementFifoRcvPktCount(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Fifo.ulRecv));
|
|
|
|
//
|
|
// Channel Counts
|
|
//
|
|
#define nicIncrementChannelSendPktCount(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Channel.ulSendNicSucess));
|
|
#define nicIncrementChannelSendFailures(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Channel.ulSendNicFail));
|
|
#define nicIncrementChannelBusSendFailures(_Vc,_Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Channel.ulSendBusFail));
|
|
#define nicIncrementChannelBusSendSucess(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Channel.ulSendBusSuccess));
|
|
#define nicIncrementChannelRcvPktCount(_Vc, _Pkt) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.Channel.ulRecv));
|
|
|
|
|
|
|
|
//
|
|
// Generic counts
|
|
//
|
|
|
|
#define nicIncrementSendCompletes(_Vc) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.ulNumSendsCompleted )); \
|
|
NdisInterlockedIncrement(&NicSendCompletes);
|
|
|
|
#define nicIncrementSends(_Vc) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.ulNumSends)); \
|
|
NdisInterlockedIncrement (&NicSends);
|
|
|
|
|
|
#define nicIncrementBusSends(_Vc) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.ulNumBusSends)); \
|
|
NdisInterlockedIncrement (&BusSends);
|
|
|
|
|
|
#define nicIncrementBusSendCompletes(_Vc) NdisInterlockedIncrement(&((_Vc)->Hdr.pAF->pAdapter->AdaptStats.TempStats.ulNumBusSendsCompleted )); \
|
|
NdisInterlockedIncrement(&BusSendCompletes);
|
|
|
|
|
|
#if FIFO_WRAPPER
|
|
|
|
#define nicSetTagInFifoWrapper(_pF, _Tag) \
|
|
{ \
|
|
((PADDRESS_FIFO_WRAPPER)(_pF))->Tag = _Tag; \
|
|
\
|
|
}
|
|
#else
|
|
|
|
#define nicSetTagInFifoWrapper(_pF, _Tag)
|
|
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// N I C E R R O R C O D E S
|
|
//-----------------------------------------------------------------------------
|
|
#define NIC_ERROR_CODE_INVALID_UNIQUE_ID_0 0xbad0000
|
|
#define NIC_ERROR_CODE_INVALID_UNIQUE_ID_FF 0xbadffff
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// R E M O T E N O D E F U N C T I O N S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#if 0
|
|
VOID
|
|
NicMpNotifyHandler(
|
|
IN PDEVICE_OBJECT RemoteNodePhysicalDeviceObject,
|
|
IN PDEVICE_OBJECT LocalHostPhysicalDeviceObject,
|
|
IN ULONG UniqueId0,
|
|
IN ULONG UniqueId1,
|
|
IN NDIS1394ENUM_NOTIFY_CODE NotificationCode
|
|
);
|
|
#endif
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
NicInitializeRemoteNode(
|
|
OUT REMOTE_NODE **ppRemoteNode,
|
|
IN PDEVICE_OBJECT p1394DeviceObject,
|
|
IN UINT64 UniqueId
|
|
);
|
|
|
|
NTSTATUS
|
|
nicAddRemoteNode(
|
|
IN PVOID Nic1394AdapterContext, // Nic1394 handle for the local host adapter
|
|
IN PVOID Enum1394NodeHandle, // Enum1394 handle for the remote node
|
|
IN PDEVICE_OBJECT RemoteNodePhysicalDeviceObject, // physical device object for the remote node
|
|
IN ULONG UniqueId0, // unique ID Low for the remote node
|
|
IN ULONG UniqueId1, // unique ID High for the remote node
|
|
OUT PVOID * pNic1394NodeContext // Nic1394 context for the remote node
|
|
);
|
|
|
|
NTSTATUS
|
|
nicRemoveRemoteNode(
|
|
IN PVOID Nic1394NodeContext // Nic1394 context for the remote node
|
|
);
|
|
|
|
|
|
NDIS_STATUS
|
|
nicFindRemoteNodeFromAdapter(
|
|
IN PADAPTERCB pAdapter,
|
|
IN PDEVICE_OBJECT pRemotePdo,
|
|
IN UINT64 UniqueId,
|
|
IN OUT REMOTE_NODE ** ppRemoteNode
|
|
);
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetLocalHostPdoBlock (
|
|
IN PVCCB pVc,
|
|
IN OUT REMOTE_NODE **ppRemoteNode
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicRemoteNodeRemoveVcCleanUp (
|
|
IN PREMOTE_NODE pRemoteNode
|
|
);
|
|
|
|
|
|
UINT
|
|
nicNumOfActiveRemoteNodes(
|
|
IN PADAPTERCB pAdapter
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
nicReferenceRemoteNode (
|
|
IN REMOTE_NODE *pRemoteNode,
|
|
IN PCHAR pDebugPrint
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
nicDereferenceRemoteNode (
|
|
IN REMOTE_NODE *pRemoteNode,
|
|
IN CHAR DebugPrint[50]
|
|
);
|
|
|
|
|
|
VOID
|
|
nicInitalizeRefRemoteNode(
|
|
IN REMOTE_NODE *pRemoteNode
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
nicCloseRefRemoteNode(
|
|
IN REMOTE_NODE *pRemoteNode
|
|
);
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// U T I L I T Y F U N C T I O N S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
nicCallCleanUp(
|
|
IN VCCB* pVc
|
|
);
|
|
|
|
|
|
VOID
|
|
nicClearFlags(
|
|
IN OUT ULONG* pulFlags,
|
|
IN ULONG ulMask
|
|
);
|
|
|
|
BOOLEAN
|
|
nicCloseRef(
|
|
IN PREF RefP
|
|
);
|
|
|
|
|
|
VOID
|
|
nicReferenceAdapter(
|
|
IN ADAPTERCB* pAdapter ,
|
|
IN PCHAR pDebugPrint
|
|
);
|
|
|
|
BOOLEAN
|
|
nicDereferenceCall(
|
|
IN VCCB* pVc,
|
|
IN PCHAR pDebugPrint
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
nicDereferenceRef(
|
|
IN PREF RefP
|
|
);
|
|
|
|
VOID
|
|
nicDereferenceAdapter(
|
|
IN PADAPTERCB pAdapter,
|
|
IN PCHAR pDebugPrint
|
|
);
|
|
|
|
|
|
|
|
VOID
|
|
nicDereferenceVc(
|
|
IN VCCB* pVc
|
|
);
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicExecuteWork(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN NDIS_PROC pProc,
|
|
IN PVOID pContext,
|
|
IN ULONG ulArg1,
|
|
IN ULONG ulArg2,
|
|
IN ULONG ulArg3,
|
|
IN ULONG ulArg4
|
|
);
|
|
|
|
|
|
VOID
|
|
nicInitializeRef(
|
|
IN PREF RefP
|
|
);
|
|
|
|
|
|
ULONG
|
|
nicReadFlags(
|
|
IN ULONG* pulFlags
|
|
);
|
|
|
|
|
|
VOID
|
|
nicReferenceAdapter(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN PCHAR pDebugPrint
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
nicReferenceCall(
|
|
IN VCCB* pVc,
|
|
IN PCHAR pDebugPrint
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
nicReferenceRef(
|
|
IN PREF RefP
|
|
);
|
|
|
|
VOID
|
|
nicReferenceVc(
|
|
IN VCCB* pVc
|
|
);
|
|
|
|
NDIS_STATUS
|
|
nicScheduleWork(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN NDIS_PROC pProc,
|
|
IN PVOID pContext
|
|
);
|
|
|
|
|
|
VOID
|
|
nicSetFlags(
|
|
IN OUT ULONG* pulFlags,
|
|
IN ULONG ulMask
|
|
);
|
|
|
|
CHAR*
|
|
nicStrDup(
|
|
IN CHAR* psz
|
|
);
|
|
|
|
CHAR*
|
|
nicStrDupNdisString(
|
|
IN NDIS_STRING* pNdisString
|
|
);
|
|
|
|
CHAR*
|
|
nicStrDupSized(
|
|
IN CHAR* psz,
|
|
IN ULONG ulLength,
|
|
IN ULONG ulExtra
|
|
);
|
|
|
|
VOID
|
|
nicUpdateGlobalCallStats(
|
|
IN VCCB *pVc
|
|
);
|
|
|
|
NDIS_STATUS
|
|
NtStatusToNdisStatus (
|
|
NTSTATUS NtStatus
|
|
);
|
|
|
|
|
|
VOID
|
|
PrintNdisPacket (
|
|
ULONG TM_Comp,
|
|
PNDIS_PACKET pMyPacket
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
nicAllocatePacket(
|
|
OUT PNDIS_STATUS pNdisStatus,
|
|
OUT PNDIS_PACKET *ppNdisPacket,
|
|
IN PNIC_PACKET_POOL pPacketPool
|
|
);
|
|
|
|
|
|
VOID
|
|
nicFreePacket(
|
|
IN PNDIS_PACKET pNdisPacket,
|
|
IN PNIC_PACKET_POOL pPacketPool
|
|
);
|
|
|
|
VOID
|
|
nicFreePacketPool (
|
|
IN PNIC_PACKET_POOL pPacketPool
|
|
);
|
|
|
|
|
|
VOID
|
|
nicAcquireSpinLock (
|
|
IN PNIC_SPIN_LOCK pNicSpinLock,
|
|
IN PUCHAR FileName,
|
|
IN UINT LineNumber
|
|
);
|
|
|
|
|
|
VOID
|
|
nicReleaseSpinLock (
|
|
IN PNIC_SPIN_LOCK pNicSpinLock,
|
|
IN PUCHAR FileName,
|
|
IN UINT LineNumber
|
|
);
|
|
|
|
VOID
|
|
nicInitializeNicSpinLock (
|
|
IN PNIC_SPIN_LOCK pNicSpinLock
|
|
);
|
|
|
|
|
|
VOID
|
|
nicFreeNicSpinLock (
|
|
IN PNIC_SPIN_LOCK pNicSpinLock
|
|
);
|
|
|
|
|
|
VOID
|
|
nic1394DeallocPktLog(
|
|
IN ADAPTERCB* pAdapter
|
|
);
|
|
|
|
|
|
VOID
|
|
nic1394AllocPktLog(
|
|
IN ADAPTERCB* pAdapter
|
|
);
|
|
|
|
VOID
|
|
Nic1394LogPkt (
|
|
PNIC1394_PKTLOG pPktLog,
|
|
ULONG Flags,
|
|
ULONG SourceID,
|
|
ULONG DestID,
|
|
PVOID pvData,
|
|
ULONG cbData
|
|
);
|
|
|
|
VOID
|
|
Nic1394InitPktLog(
|
|
PNIC1394_PKTLOG pPktLog
|
|
);
|
|
|
|
|
|
|
|
ULONG
|
|
SwapBytesUlong(
|
|
IN ULONG Val
|
|
);
|
|
|
|
VOID
|
|
nicUpdatePacketState (
|
|
IN PNDIS_PACKET pPacket,
|
|
IN ULONG Tag
|
|
);
|
|
|
|
UINT
|
|
nicGetSystemTime(
|
|
VOID
|
|
);
|
|
|
|
UINT
|
|
nicGetSystemTimeMilliSeconds(
|
|
VOID
|
|
);
|
|
|
|
|
|
VOID
|
|
nicGetFakeMacAddress(
|
|
UINT64 *Euid,
|
|
MAC_ADDRESS *MacAddr
|
|
);
|
|
|
|
VOID
|
|
nicWriteErrorLog (
|
|
IN PADAPTERCB pAdapter,
|
|
IN NDIS_ERROR_CODE ErrorCode,
|
|
IN ULONG ErrorValue
|
|
);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// S E R I A L I Z E S E N D / R E C E I V E F U N C T I O N S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
NDIS_STATUS
|
|
nicInitSerializedReceiveStruct(
|
|
PADAPTERCB pAdapter
|
|
);
|
|
|
|
VOID
|
|
nicDeInitSerializedReceiveStruct(
|
|
PADAPTERCB pAdapter
|
|
);
|
|
|
|
|
|
NDIS_STATUS
|
|
nicQueueReceivedPacket(
|
|
PNDIS_PACKET pPacket,
|
|
PVCCB pVc,
|
|
PADAPTERCB pAdapter
|
|
);
|
|
|
|
|
|
NDIS_STATUS
|
|
nicInitSerializedSendStruct(
|
|
PADAPTERCB pAdapter
|
|
);
|
|
|
|
VOID
|
|
nicDeInitSerializedSendStruct(
|
|
PADAPTERCB pAdapter
|
|
);
|
|
|
|
NDIS_STATUS
|
|
nicQueueSendPacket(
|
|
PNDIS_PACKET pPacket,
|
|
PVCCB pVc
|
|
);
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// G L O B A L V A R I A B L E S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
UINT NumChannels;
|
|
//-----------------------------------------------------------------------------
|
|
// E N U M E R A T O R F U N C T I O N S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
extern ENUM1394_REGISTER_DRIVER_HANDLER NdisEnum1394RegisterDriver;
|
|
extern ENUM1394_DEREGISTER_DRIVER_HANDLER NdisEnum1394DeregisterDriver;
|
|
extern ENUM1394_REGISTER_ADAPTER_HANDLER NdisEnum1394RegisterAdapter;
|
|
extern ENUM1394_DEREGISTER_ADAPTER_HANDLER NdisEnum1394DeregisterAdapter;
|
|
|
|
extern NIC1394_CHARACTERISTICS Nic1394Characteristics;
|
|
|
|
|
|
NTSTATUS
|
|
NicRegisterEnum1394(
|
|
IN PNDISENUM1394_CHARACTERISTICS NdisEnum1394Characteristcis
|
|
);
|
|
|
|
VOID
|
|
NicDeregisterEnum1394(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
Nic1394Callback(
|
|
PVOID CallBackContext,
|
|
PVOID Source,
|
|
PVOID Characteristics
|
|
);
|
|
|
|
VOID
|
|
Nic1394RegisterAdapters(
|
|
VOID
|
|
);
|
|
|
|
NTSTATUS
|
|
Nic1394BusRequest(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRB Irb
|
|
);
|
|
|
|
NTSTATUS
|
|
Nic1394PassIrpDownTheStack(
|
|
IN PIRP pIrp,
|
|
IN PDEVICE_OBJECT pNextDeviceObject
|
|
);
|
|
|
|
NTSTATUS
|
|
Nic1394IrpCompletion(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
nicDumpMdl (
|
|
IN PMDL pMdl,
|
|
IN ULONG LengthToPrint,
|
|
IN CHAR *str
|
|
);
|
|
|
|
VOID
|
|
nicDumpPkt (
|
|
IN PNDIS_PACKET pPacket,
|
|
CHAR * str
|
|
);
|
|
|
|
VOID
|
|
nicCheckForEthArps (
|
|
IN PNDIS_PACKET pPkt
|
|
);
|
|
|
|
VOID
|
|
nicGetMacAddressFromEuid (
|
|
UINT64 *pEuid,
|
|
MAC_ADDRESS *pMacAddr
|
|
);
|
|
|
|
|
|
|
|
VOID
|
|
nicInitializeLoadArpStruct(
|
|
PADAPTERCB pAdapter
|
|
);
|
|
|
|
extern PCALLBACK_OBJECT Nic1394CallbackObject;
|
|
extern PVOID Nic1394CallbackRegisterationHandle;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// S T A T I S T I C B U C K E T S
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
extern STAT_BUCKET SendStats;
|
|
extern STAT_BUCKET RcvStats;
|
|
extern ULONG nicMaxRcv;
|
|
extern ULONG nicMaxSend;
|
|
extern ULONG SendTimer; // In ms
|
|
extern ULONG RcvTimer; // In ms
|
|
|