windows-nt/Source/XPSP1/NT/net/1394/nic/sys/priv.h
2020-09-26 16:20:57 +08:00

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