|
|
// 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;
//
// Add checks for #defines that are meant for special purposes and
// should not be turned on for general use
//
#ifdef PKT_LOG
#error
#endif
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
//
// This is a table of the Remote nodes and it is used to keep a track of the number of nodes
// on the bus. To stop overflows, yhis structure is usally accessed by
// NODE_ADDRESS.NA_Node_Number which is a 6 bit entity.
//
typedef struct _NODE_TABLE { PREMOTE_NODE RemoteNode[NIC1394_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;
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;
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;
//
// Generic structure to be used to serialize send and receives, workitems
//
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 pNextDeviceObject; // 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 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 in Bytes
//
ULONG AdapterNameSize;
//
// Ioctl Sent to the Arp module
//
ARP1394_IOCTL_COMMAND ArpIoctl;
//
// Is Arp Started
//
BOOLEAN fIsArpStarted;
//
// Power State - informational use
//
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;
} 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, } 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;
//
// 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
} 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;
//
// The following structure is used to log the cause of a Reference or Dereference.
// It is ignored unless LOG_REMOTE_NODE_REF is not zero
//
typedef enum _REMOTE_NODE_REF_CAUSE {
FindIrmAmongRemoteNodes, InformAllRemoteNodesOfBCM, UpdateNodeTable, FindRemoteNodeFromAdapter, SubmitIrp_Synch, AddRemoteNode, ReassemblyTimer, GetRemoteNodeFromTable, UpdateRemoteNodeCaps, UpdateRemoteNodeTable, UpdateLocalHostSpeed, InitializeReassemblyStructure, FreeAllPendingReassemblyStructures, AsyncWriteSendPackets, FindRemoteNodeFromAdapterFail, RemoveRemoteNode, ReassemblyTimer_Removing, FreeReassembliesOnRemoteNode, FillRemoteNodeInfo, InsertFragmentInReassembly, AsyncSendComplete,
} REMOTE_NODE_REF_CAUSE;
#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
#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); \ 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
#define nicInitQueueStats()
#define nicSetCountInHistogram(_PktsInQueue, _Stats)
#define nicSetMax(_nicMax, _PktsInQueue)
#define nicIncrementRcvTimerCount()
#define nicIncrementSendTimerCount()
//
// 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);
//-----------------------------------------------------------------------------
// 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 REMOTE_NODE_REF_CAUSE Cause );
BOOLEAN nicDereferenceRemoteNode ( IN REMOTE_NODE *pRemoteNode, IN REMOTE_NODE_REF_CAUSE Cause );
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, IN PLONG pRefCount );
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, OUT PLONG pNumber );
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 );
NDIS_STATUS nicScheduleWorkItem ( IN PADAPTERCB pAdapter, IN PNDIS_WORK_ITEM pWorkItem );
//-----------------------------------------------------------------------------
// 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
|