diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxconn.h | 1666 |
1 files changed, 1666 insertions, 0 deletions
diff --git a/private/ntos/tdi/isnp/spx/h/spxconn.h b/private/ntos/tdi/isnp/spx/h/spxconn.h new file mode 100644 index 000000000..bb1173432 --- /dev/null +++ b/private/ntos/tdi/isnp/spx/h/spxconn.h @@ -0,0 +1,1666 @@ +/*++ + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + spxconn.h + +Abstract: + + +Author: + + Nikhil Kamkolkar (nikhilk) 11-November-1993 + +Environment: + + Kernel mode + +Revision History: + + Sanjay Anand (SanjayAn) 5-July-1995 + Bug fixes - tagged [SA] + +--*/ + +// Minimum value for RTT in ms. +// BUGBUG: Have these be a derivate of registry values. +#define SPX_T1_MIN 200 +#define MAX_RETRY_DELAY 5000 // 5 seconds +#define SPX_DEF_RENEG_RETRYCOUNT 1 // All reneg pkts except min sent once + +// Some types +typedef enum +{ + SPX_CALL_RECVLEVEL, + SPX_CALL_TDILEVEL +} SPX_CALL_LEVEL; + +typedef enum +{ + SPX_REQ_DATA, + SPX_REQ_ORDREL, + SPX_REQ_DISC + +} SPX_SENDREQ_TYPE; + +// This structure is pointed to by the FsContext field in the FILE_OBJECT +// for this Connection. + +#define CFREF_CREATE 0 +#define CFREF_VERIFY 1 +#define CFREF_INDICATION 2 +#define CFREF_BYCTX 3 +#define CFREF_BYID 4 +#define CFREF_ADDR 5 +#define CFREF_REQ 6 +#define CFREF_TIMER 7 +#define CFREF_PKTIZE 8 +#define CFREF_RECV 9 +#define CFREF_ABORTPKT 10 +#define CFREF_ERRORSTATE 11 +#define CFREF_FINDROUTE 12 + +// +// New state added to reflect an SPXI connection which is waiting for +// a local disconnect after having indicated a RELEASE to AFD. +// +#define CFREF_DISCWAITSPX 13 + +#define CFREF_TOTAL 14 + +#define CFMAX_STATES 20 + +typedef struct _SPX_CONN_FILE +{ + +#if DBG + ULONG scf_RefTypes[CFREF_TOTAL]; + +#if 0 +// +// Disabled for now - to enable logging of states, move this array *after* the Type/Size; +// a change in their offset can cause problems since we assume the offset to be less than +// the size of an AddressFile structure. (see SpxTdiQueryInformation) +// + ULONG scf_StateBuffer[CFMAX_STATES]; + ULONG scf_NextStatePtr; +#endif + +#endif + + CSHORT scf_Type; + CSHORT scf_Size; + + // number of references to this object. + ULONG scf_RefCount; + + // Linkage in device address file list. The connection can be on the device + // connection list, address inactive/listen/active list. + struct _SPX_CONN_FILE * scf_Next; + struct _SPX_CONN_FILE * scf_AssocNext; + struct _SPX_CONN_FILE * scf_GlobalActiveNext; + + // Queued in a global list, stays here from creation to destroy. + struct _SPX_CONN_FILE * scf_GlobalNext; + struct _SPX_CONN_FILE * scf_PktNext; + struct _SPX_CONN_FILE * scf_ProcessRecvNext; + + // the current state of the connection. One main state and multiple substates. + ULONG scf_Flags; + + // More information + ULONG scf_Flags2; + +#if DBG + // Save the state of flags/flags2 before reinit. Overwritten every reinit. + ULONG scf_GhostFlags; + ULONG scf_GhostFlags2; + ULONG scf_GhostRefCount; + PREQUEST scf_GhostDiscReq; +#endif + + // Connection retry counts, or watchdog timer count when the connection goes + // active + union + { + LONG scf_CRetryCount; + LONG scf_WRetryCount; + }; + LONG scf_RRetryCount; + USHORT scf_RRetrySeqNum; + + union + { + ULONG scf_CTimerId; + ULONG scf_RTimerId; // Only after we turn active + }; + + ULONG scf_WTimerId; // Watchdog timer + ULONG scf_TTimerId; // TDI Connect/Disconnect timer + ULONG scf_ATimerId; // Ack timer id + + // Variables used to manage the Retry timer tick value + // Note our timer subsytem fires at 100ms granularity. + int scf_BaseT1; + int scf_AveT1; + int scf_DevT1; + + // Stored in HOST-ORDER + // LOCAL variables + USHORT scf_LocalConnId; + USHORT scf_SendSeqNum; // Debug dw +9a + USHORT scf_SentAllocNum; // dw +9c + + // REMOTE variables + USHORT scf_RecvSeqNum; // dw +9e + USHORT scf_RecdAckNum; // dw +a0 + USHORT scf_RecdAllocNum; // dw +a2 + + // RETRY sequence number + USHORT scf_RetrySeqNum; + + // Saved ack number to be used in building the reneg ack packet. + // Note that our RecvSeqNum which we normally use is overwritten + // when we receive a renegotiate request. + USHORT scf_RenegAckAckNum; + + // Stored in NETWORK-ORDER. scf_RemAckAddr contains the remote address + // for a data packet that had the ack bit set, buildAck will use this + // address. + BYTE scf_RemAddr[12]; + BYTE scf_RemAckAddr[12]; + USHORT scf_RemConnId; // Debug dw +be + + // Maximum packet size (or size of first) reneg packet. + USHORT scf_RenegMaxPktSize; + + // Local target to use in when sending acks. This is set to received + // data's indicated local target. + IPX_LOCAL_TARGET scf_AckLocalTarget; + + // Maximum packet size to use for this connection + USHORT scf_MaxPktSize; + UCHAR scf_DataType; + + // Local target to use in sends, initialized upon connect indication + // or when find_route completes + IPX_LOCAL_TARGET scf_LocalTarget; + + // Connection lock + CTELock scf_Lock; + + // address to which we are bound + struct _SPX_ADDR_FILE * scf_AddrFile; + + // Connection context + CONNECTION_CONTEXT scf_ConnCtx; + +#ifdef ISN_NT + // easy backlink to file object. + PFILE_OBJECT scf_FileObject; +#endif + + // LIST_ENTRY of disconnect irps waiting for completion. There could be + // multiple disconnect inform irps. + LIST_ENTRY scf_DiscLinkage; + + // LIST_ENTRY of send requests (intially contains connect/listen/accept also) + // on this connection. + LIST_ENTRY scf_ReqLinkage; + + // Queue for completed requests awaiting completion + LIST_ENTRY scf_ReqDoneLinkage; + LIST_ENTRY scf_RecvDoneLinkage; + + // Queue for pending receives + LIST_ENTRY scf_RecvLinkage; + PREQUEST scf_CurRecvReq; + ULONG scf_CurRecvOffset; + ULONG scf_CurRecvSize; + + // Current request packetize info + PREQUEST scf_ReqPkt; + ULONG scf_ReqPktOffset; + ULONG scf_ReqPktSize; + ULONG scf_ReqPktFlags; + SPX_SENDREQ_TYPE scf_ReqPktType; + + // Single linked list of sequenced send/disc packets + PSPX_SEND_RESD scf_SendSeqListHead; + PSPX_SEND_RESD scf_SendSeqListTail; + + // Single linked list of send (unsequenced) packets + PSPX_SEND_RESD scf_SendListHead; + PSPX_SEND_RESD scf_SendListTail; + + // Single linked list of buffered recv packets. + PSPX_RECV_RESD scf_RecvListHead; + PSPX_RECV_RESD scf_RecvListTail; + + // Connect request + PREQUEST scf_ConnectReq; + + // This holds the request used to close this address file, + // for pended completion. We also pend cleanup requests for connections. + PREQUEST scf_CleanupReq; + PREQUEST scf_CloseReq; + +#if DBG + + // Packet being indicated, seq num, flags/flags2 + USHORT scf_PktSeqNum; + ULONG scf_PktFlags; + ULONG scf_PktFlags2; + + ULONG scf_IndBytes; + ULONG scf_IndLine; +#endif + +#if DBG_WDW_CLOSE + + // Keep track of how long the window was closed on this connection. + ULONG scf_WdwCloseAve; + LARGE_INTEGER scf_WdwCloseTime; // Time when wdw was closed +#endif + + // device to which we are attached. + struct _DEVICE * scf_Device; + +} SPX_CONN_FILE, *PSPX_CONN_FILE; + + +// Basic states +// Least significant byte of flags is used. +// Mutually exclusive states are coded as numbers, others are bit flags. +// Only main states are currently in form of numbers. Also, send and receive. +// +// Once we go active, we need SEND/RECEIVE/DISC substates to be mutually +// exclusive with each other. As all three could be active at the same time. + +// Connection MAIN states. These are all mutually exclusive. +#define SPX_CONNFILE_MAINMASK 0x00000007 +#define SPX_CONNFILE_ACTIVE 0x00000001 +#define SPX_CONNFILE_CONNECTING 0x00000002 +#define SPX_CONNFILE_LISTENING 0x00000003 +#define SPX_CONNFILE_DISCONN 0x00000004 + +// Connecting states (VALID when CONNFILE_CONNECTING) +#define SPX_CONNECT_MASK 0x000000F0 +#define SPX_CONNECT_SENTREQ 0x00000010 +#define SPX_CONNECT_NEG 0x00000020 +#define SPX_CONNECT_W_SETUP 0x00000030 + +// Listening states (VALID when CONNFILE_LISTENING) +#define SPX_LISTEN_MASK 0x000000F0 +#define SPX_LISTEN_RECDREQ 0x00000010 +#define SPX_LISTEN_SENTACK 0x00000020 +#define SPX_LISTEN_NEGACK 0x00000030 +#define SPX_LISTEN_SETUP 0x00000040 + +// Connection SUB states +// Send machine states (VALID when CONNFILE_ACTIVE) +#define SPX_SEND_MASK 0x000000F0 +#define SPX_SEND_IDLE 0x00000000 +#define SPX_SEND_PACKETIZE 0x00000010 +#define SPX_SEND_RETRY 0x00000020 +#define SPX_SEND_RETRYWD 0x00000030 +#define SPX_SEND_RENEG 0x00000040 +#define SPX_SEND_RETRY2 0x00000050 +#define SPX_SEND_RETRY3 0x00000060 +#define SPX_SEND_WD 0x00000070 // We dont reneg pkt size on wdog + // Also we change to this state only + // 2nd time wdog fires w/out ack. +#define SPX_SEND_NAK_RECD 0x00000080 + +// Receive machine states (VALID when CONNFILE_ACTIVE) +#define SPX_RECV_MASK 0x00000F00 +#define SPX_RECV_IDLE 0x00000000 +#define SPX_RECV_POSTED 0x00000100 +#define SPX_RECV_PROCESS_PKTS 0x00000200 + +// Disconnect states (VALID when CONNFILE_DISCONN/CONNFILE_ACTIVE) +// These are valid when either ACTIVE/DISCONN is set. We use these when +// active for a orderly release, i.e. we receive pkt from remote, but we +// stay active (setting SPX_DISC_RECV_ORDREL) until our client posts a +// disconnect, which is when we move to disconnecting. +#define SPX_DISC_MASK 0x0000F000 +#define SPX_DISC_IDLE 0x00000000 +#define SPX_DISC_ABORT 0x00001000 +#define SPX_DISC_SENT_IDISC 0x00002000 +#define SPX_DISC_POST_ORDREL 0x00003000 +#define SPX_DISC_SENT_ORDREL 0x00004000 +#define SPX_DISC_ORDREL_ACKED 0x00005000 +#define SPX_DISC_POST_IDISC 0x00006000 + +// [SA] bug #14655 added flag to indicate that SpxConnInactivate already called for +// this disconnecting connection +// +#define SPX_DISC_INACTIVATED 0x00007000 + +// The following are not mutually exclusive. +#define SPX_CONNFILE_RECVQ 0x00010000 // Process completed receives/pkts +#define SPX_CONNFILE_RENEG_SIZE 0x00020000 // Size changed in renegotiate pkt +#define SPX_CONNFILE_ACKQ 0x00040000 // Waiting to piggyback ack queue +#define SPX_CONNFILE_PKTQ 0x00080000 // Waiting to packetize queue + +#define SPX_CONNFILE_ASSOC 0x00100000 // associated +#define SPX_CONNFILE_NEG 0x00200000 // CR had neg set (for delayed accept) +#define SPX_CONNFILE_SPX2 0x00400000 +#define SPX_CONNFILE_STREAM 0x00800000 +#define SPX_CONNFILE_R_TIMER 0x01000000 // Retry timer (only after ACTIVE) +#define SPX_CONNFILE_C_TIMER 0x01000000 // Connect timer +#define SPX_CONNFILE_W_TIMER 0x02000000 // Watchdog timer +#define SPX_CONNFILE_T_TIMER 0x04000000 // tdi connect/disc timer specified +#define SPX_CONNFILE_RENEG_PKT 0x08000000 // Renegotiate changed size, repacketize +#define SPX_CONNFILE_IND_IDISC 0x10000000 // Indicated abortive disc to afd +#define SPX_CONNFILE_IND_ODISC 0x20000000 // Indicated orderly release to afd + +#define SPX_CONNFILE_STOPPING 0x40000000 +#define SPX_CONNFILE_CLOSING 0x80000000 // closing + +#define SPX_CONNFILE2_PKT_NOIND 0x00000001 +#define SPX_CONNFILE2_RENEGRECD 0x00000002 // A renegotiate was received. + // scf_RenegAckAckNum set. +#define SPX_CONNFILE2_PKT 0x00000004 +#define SPX_CONNFILE2_FINDROUTE 0x00000010 // A find route in progress on conn. +#define SPX_CONNFILE2_NOACKWAIT 0x00000020 // Dont delay acks on connection, option +#define SPX_CONNFILE2_IMMED_ACK 0x00000040 // Send an immediate ack,no back traffic +#define SPX_CONNFILE2_IPXHDR 0x00000080 // Pass ipxhdr in receives + +// +// [SA] Saves the IDisc flag passed to AbortiveDisc; this is TRUE only if there was +// a remote disconnect on an SPX connection (in which case, we indicate TDI_DISCONNECT_RELEASE +// else we indicate TDI_DISCONNECT_ABORT) +// +#define SPX_CONNFILE2_IDISC 0x00000100 + +// +// Indicates an SPXI connfile waiting for a local disconnect in response +// to a TDI_DISCONNECT_RELEASE to AFD. +// +#define SPX_CONNFILE2_DISC_WAIT 0x00000200 + +// FindRoute request structure +typedef struct _SPX_FIND_ROUTE_REQUEST +{ + // !!!!This must be the first element in the structure + IPX_FIND_ROUTE_REQUEST fr_FindRouteReq; + PVOID fr_Ctx; + +} SPX_FIND_ROUTE_REQUEST, *PSPX_FIND_ROUTE_REQUEST; + +typedef struct _SPX_CONNFILE_LIST +{ + PSPX_CONN_FILE pcl_Head; + PSPX_CONN_FILE pcl_Tail; + +} SPX_CONNFILE_LIST, *PSPX_CONNFILE_LIST; + +// Exported routines + +NTSTATUS +SpxConnOpen( + IN PDEVICE pDevice, + IN CONNECTION_CONTEXT pConnCtx, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnCleanup( + IN PDEVICE Device, + IN PREQUEST Request); + +NTSTATUS +SpxConnClose( + IN PDEVICE Device, + IN PREQUEST Request); + +NTSTATUS +SpxConnDisAssociate( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +spxConnDisAssoc( + IN PSPX_CONN_FILE pSpxConnFile, + IN CTELockHandle LockHandleConn); + +VOID +SpxConnStop( + IN PSPX_CONN_FILE pSpxConnFile); + +NTSTATUS +SpxConnAssociate( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnConnect( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnListen( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnAccept( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnAction( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnDisconnect( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnSend( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +NTSTATUS +SpxConnRecv( + IN PDEVICE pDevice, + IN PREQUEST pRequest); + +VOID +SpxConnFileRefByCtxLock( + IN PSPX_ADDR_FILE pSpxAddrFile, + IN CONNECTION_CONTEXT Ctx, + OUT PSPX_CONN_FILE * ppSpxConnFile, + OUT NTSTATUS * pStatus); + +NTSTATUS +SpxConnFileVerify ( + IN PSPX_CONN_FILE pConnFile); + +VOID +SpxConnFileDeref( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +SpxConnConnectFindRouteComplete( + IN PSPX_CONN_FILE pSpxConnFile, + IN PSPX_FIND_ROUTE_REQUEST pFrReq, + IN BOOLEAN FoundRoute, + IN CTELockHandle LockHandle); + +VOID +SpxConnActiveFindRouteComplete( + IN PSPX_CONN_FILE pSpxConnFile, + IN PSPX_FIND_ROUTE_REQUEST pFrReq, + IN BOOLEAN FoundRoute, + IN CTELockHandle LockHandle); + +BOOLEAN +SpxConnPacketize( + IN PSPX_CONN_FILE pSpxConnFile, + IN BOOLEAN fNormalState, + IN CTELockHandle LockHandleConn); + +#if DBG +VOID +SpxConnFileRef( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +SpxConnFileLockRef( + IN PSPX_CONN_FILE pSpxConnFile); +#endif + +VOID +SpxConnFileRefByIdLock ( + IN USHORT ConnId, + OUT PSPX_CONN_FILE * ppSpxConnFile, + OUT PNTSTATUS pStatus); + +BOOLEAN +SpxConnDequeuePktLock( + IN PSPX_CONN_FILE pSpxConnFile, + IN PNDIS_PACKET pPkt); + +VOID +SpxConnSendAck( + IN PSPX_CONN_FILE pSpxConnFile, + IN CTELockHandle LockHandleConn); + +VOID +SpxConnSendNack( + IN PSPX_CONN_FILE pSpxConnFile, + IN USHORT NumToSend, + IN CTELockHandle LockHandleConn); + +BOOLEAN +SpxConnProcessAck( + IN PSPX_CONN_FILE pSpxConnFile, + IN PIPXSPX_HDR pAckHdr, + IN CTELockHandle lockHandle); + +VOID +SpxConnProcessRenegReq( + IN PSPX_CONN_FILE pSpxConnFile, + IN PIPXSPX_HDR pIpxSpxHdr, + IN PIPX_LOCAL_TARGET pRemoteAddr, + IN CTELockHandle lockHandle); + +VOID +SpxConnProcessIDisc( + IN PSPX_CONN_FILE pSpxConnFile, + IN CTELockHandle lockHandle); + +VOID +SpxConnProcessOrdRel( + IN PSPX_CONN_FILE pSpxConnFile, + IN CTELockHandle lockHandle); + +BOOLEAN +SpxConnDequeueRecvPktLock( + IN PSPX_CONN_FILE pSpxConnFile, + IN PNDIS_PACKET pPkt); + +BOOLEAN +SpxConnDequeueSendPktLock( + IN PSPX_CONN_FILE pSpxConnFile, + IN PNDIS_PACKET pPkt); + +// LOCAL functions +VOID +spxConnHandleConnReq( + IN PIPXSPX_HDR pIpxSpxHdr, + IN PIPX_LOCAL_TARGET pRemoteAddr); + +VOID +spxConnHandleSessPktFromClient( + IN PIPXSPX_HDR pIpxSpxHdr, + IN PIPX_LOCAL_TARGET pRemoteAddr, + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnHandleSessPktFromSrv( + IN PIPXSPX_HDR pIpxSpxHdr, + IN PIPX_LOCAL_TARGET pRemoteAddr, + IN PSPX_CONN_FILE pSpxConnFile); + +ULONG +spxConnConnectTimer( + IN PVOID Context, + IN BOOLEAN TimerShuttingDown); + +ULONG +spxConnWatchdogTimer( + IN PVOID Context, + IN BOOLEAN TimerShuttingDown); + +ULONG +spxConnRetryTimer( + IN PVOID Context, + IN BOOLEAN TimerShuttingDown); + +ULONG +spxConnAckTimer( + IN PVOID Context, + IN BOOLEAN TimerShuttingDown); + +VOID +spxConnCompletePended( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +SpxConnQWaitAck( + IN PSPX_CONN_FILE pSpxConnFile); + +USHORT +spxConnGetId( + VOID); + +VOID +spxConnInsertIntoActiveList( + IN PSPX_ADDR pSpxAddr, + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnInsertIntoInactiveList( + IN PSPX_ADDR pSpxAddr, + IN PSPX_CONN_FILE pSpxConnFile); + +NTSTATUS +spxConnRemoveFromGlobalList( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnInsertIntoGlobalList( + IN PSPX_CONN_FILE pSpxConnFile); + +NTSTATUS +spxConnRemoveFromGlobalActiveList( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnPushIntoPktList( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnPopFromPktList( + IN PSPX_CONN_FILE * ppSpxConnFile); + +VOID +spxConnPushIntoRecvList( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnPopFromRecvList( + IN PSPX_CONN_FILE * ppSpxConnFile); + +VOID +spxConnInsertIntoGlobalActiveList( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnInsertIntoListenList( + IN PSPX_ADDR pSpxAddr, + IN PSPX_CONN_FILE pSpxConnFile); + +NTSTATUS +spxConnRemoveFromList( + IN PSPX_CONN_FILE * ppConnListHead, + IN PSPX_CONN_FILE pConnRemove); + +NTSTATUS +spxConnRemoveFromAssocList( + IN PSPX_CONN_FILE * ppConnListHead, + IN PSPX_CONN_FILE pConnRemove); + +VOID +spxConnInactivate( + IN PSPX_CONN_FILE pSpxConnFile); + +BOOLEAN +spxConnGetPktByType( + IN PSPX_CONN_FILE pSpxConnFile, + IN ULONG PktType, + IN BOOLEAN fSeqList, + IN PNDIS_PACKET * ppPkt); + +BOOLEAN +spxConnGetPktBySeqNum( + IN PSPX_CONN_FILE pSpxConnFile, + IN USHORT SeqNum, + IN PNDIS_PACKET * ppPkt); + +VOID +spxConnResendPkts( + IN PSPX_CONN_FILE pSpxConnFile, + IN CTELockHandle LockHandleConn); + +BOOLEAN +spxConnCheckNegSize( + IN PUSHORT pNegSize); + +VOID +spxConnSetNegSize( + IN OUT PNDIS_PACKET pPkt, + IN ULONG Size); + +BOOLEAN +spxConnAcceptCr( + IN PSPX_CONN_FILE pSpxConnFile, + IN PSPX_ADDR pSpxAddr, + IN CTELockHandle LockHandleDev, + IN CTELockHandle LockHandleAddr, + IN CTELockHandle LockHandleConn); + +VOID +spxConnAbortConnect( + IN PSPX_CONN_FILE pSpxConnFile, + IN NTSTATUS Status, + IN CTELockHandle LockHandleDev, + IN CTELockHandle LockHandleAddr, + IN CTELockHandle LockHandleConn); + +VOID +spxConnCompleteConnect( + IN PSPX_CONN_FILE pSpxConnFile, + IN CTELockHandle LockHandleDev, + IN CTELockHandle LockHandleAddr, + IN CTELockHandle LockHandleConn); + +VOID +SpxConnQueueRecv( + IN PSPX_CONN_FILE pSpxConnFile, + IN PREQUEST pRequest); + +NTSTATUS +spxConnProcessRecv( + IN PSPX_CONN_FILE pSpxConnFile, + IN PREQUEST pRequest, + IN SPX_CALL_LEVEL CallLevel, + IN CTELockHandle LockHandleConn); + +VOID +spxConnProcessIndData( + IN PSPX_CONN_FILE pSpxConnFile, + IN SPX_CALL_LEVEL CallLevel, + IN CTELockHandle LockHandleConn); + +NTSTATUS +spxConnOrderlyDisc( + IN PSPX_CONN_FILE pSpxConnFile, + IN NTSTATUS Status, + IN PREQUEST pRequest, + IN CTELockHandle LockHandleConn); + +NTSTATUS +spxConnInformedDisc( + IN PSPX_CONN_FILE pSpxConnFile, + IN NTSTATUS Status, + IN PREQUEST pRequest, + IN CTELockHandle LockHandleConn); + +VOID +spxConnAbortiveDisc( + IN PSPX_CONN_FILE pSpxConnFile, + IN NTSTATUS Status, + IN SPX_CALL_LEVEL CallLevel, + IN CTELockHandle LockHandleConn, + IN BOOLEAN Flag); // [SA] Bug #15249 + +VOID +spxConnAbortRecvs( + IN PSPX_CONN_FILE pSpxConnFile, + IN NTSTATUS Status, + IN SPX_CALL_LEVEL CallLevel, + IN CTELockHandle LockHandleConn); + +VOID +spxConnAbortSends( + IN PSPX_CONN_FILE pSpxConnFile, + IN NTSTATUS Status, + IN SPX_CALL_LEVEL CallLevel, + IN CTELockHandle LockHandleConn); + +VOID +spxConnResetSendQueue( + IN PSPX_CONN_FILE pSpxConnFile); + +VOID +spxConnAbortSendPkt( + IN PSPX_CONN_FILE pSpxConnFile, + IN PSPX_SEND_RESD pSendResd, + IN SPX_CALL_LEVEL CallLevel, + IN CTELockHandle LockHandleConn); + +// +// MACROS +// +#define SHIFT100000 16 + +#define SPX_CONVERT100NSTOCENTISEC(Li) \ + RtlExtendedMagicDivide((Li), Magic100000, SHIFT100000) + +#define UNSIGNED_BETWEEN_WITH_WRAP(Low, High, Target) \ + ((Low <= High) ? ((Target >= Low) && (Target <= High)) : \ + ((Target >= Low) || (Target <= High))) + +// This is with the assumption that the window size will never be greater +// than the difference of 0x8000 and 0x1000. If High is < 1000 and Low +// is > 8000 then we can assume a wrap happened. Otherwise, we assume no +// wrap and do a straight compare. +#define MAX_WINDOW_SIZE 0x6000 +#define DEFAULT_WINDOW_SIZE 8 + +#define UNSIGNED_GREATER_WITH_WRAP(High, Low) \ + (((High < 0x1000) && (Low > 0x8000)) ? TRUE : (High > Low)) + +#define SPX_SET_ACKNUM(pSpxConnFile, RecdAckNum, RecdAllocNum) \ + { \ + DBGPRINT(SEND, DBG, \ + ("SPX_SET_ACKNUM: %lx.%lx = %lx.%lx (%s.%d)\n", \ + (RecdAckNum), (RecdAllocNum), \ + ((pSpxConnFile)->scf_RecdAckNum), \ + ((pSpxConnFile)->scf_RecdAllocNum), \ + __FILE__, __LINE__)); \ + \ + if (UNSIGNED_GREATER_WITH_WRAP((RecdAckNum), \ + ((pSpxConnFile)->scf_RecdAckNum))) \ + { \ + (pSpxConnFile)->scf_RecdAckNum = (RecdAckNum); \ + } \ + \ + if (UNSIGNED_GREATER_WITH_WRAP((RecdAllocNum), \ + ((pSpxConnFile)->scf_RecdAllocNum)))\ + { \ + (pSpxConnFile)->scf_RecdAllocNum = (RecdAllocNum); \ + } \ + } + +#define BEGIN_PROCESS_PACKET(pSpxConnFile, seqNum) \ + { \ + SPX_CONN_SETFLAG2(pSpxConnFile, SPX_CONNFILE2_PKT); \ + } + +#define END_PROCESS_PACKET(pSpxConnFile, fBuffered, fSuccess) \ + { \ + SPX_CONN_RESETFLAG2(pSpxConnFile, \ + (SPX_CONNFILE2_PKT |SPX_CONNFILE2_RENEGRECD)); \ + if (fSuccess) \ + { \ + SPX_CONN_RESETFLAG2(pSpxConnFile, SPX_CONNFILE2_PKT_NOIND); \ + SPX_SET_RECVNUM(pSpxConnFile, fBuffered); \ + } \ + } + +#define INCREMENT_WINDOW(pSpxConnFile) \ + ((pSpxConnFile)->scf_SentAllocNum++) + +#define ADD_TO_WINDOW(pSpxConnFile, numPkts) \ + ((pSpxConnFile)->scf_SentAllocNum += (numPkts)) + +#if DBG_WDW_CLOSE +#define SPX_SET_RECVNUM(pSpxConnFile, fBuffered) \ + { \ + (pSpxConnFile)->scf_RecvSeqNum++; \ + if (!fBuffered) \ + (pSpxConnFile)->scf_SentAllocNum++; \ + \ + if (fBuffered && \ + (UNSIGNED_GREATER_WITH_WRAP( \ + (pSpxConnFile)->scf_RecvSeqNum, \ + (pSpxConnFile)->scf_SentAllocNum))) \ + { \ + KeQuerySystemTime( \ + (PLARGE_INTEGER)&pSpxConnFile->scf_WdwCloseTime); \ + } \ + } +#else +#define SPX_SET_RECVNUM(pSpxConnFile, fBuffered) \ + { \ + (pSpxConnFile)->scf_RecvSeqNum++; \ + if (!fBuffered) \ + (pSpxConnFile)->scf_SentAllocNum++; \ + } +#endif + + +#define SPX_CONN_SETNEXT_CUR_RECV(pSpxConnFile, pRequest) \ + { \ + RemoveEntryList(REQUEST_LINKAGE((pRequest))); \ + pSpxConnFile->scf_CurRecvReq = NULL; \ + pSpxConnFile->scf_CurRecvOffset = 0; \ + pSpxConnFile->scf_CurRecvSize = 0; \ + if (!IsListEmpty(&(pSpxConnFile)->scf_RecvLinkage)) \ + { \ + PTDI_REQUEST_KERNEL_RECEIVE _p; \ + DBGPRINT(RECEIVE, DBG, \ + ("spxConnProcessRecv: CURRECV %lx\n", pRequest)); \ + \ + (pSpxConnFile)->scf_CurRecvReq = \ + LIST_ENTRY_TO_REQUEST( \ + (pSpxConnFile)->scf_RecvLinkage.Flink); \ + \ + _p = (PTDI_REQUEST_KERNEL_RECEIVE) \ + REQUEST_PARAMETERS((pSpxConnFile)->scf_CurRecvReq); \ + \ + (pSpxConnFile)->scf_CurRecvOffset = 0; \ + (pSpxConnFile)->scf_CurRecvSize = (_p)->ReceiveLength; \ + } \ + if ((SPX_RECV_STATE(pSpxConnFile) == SPX_RECV_IDLE) || \ + (SPX_RECV_STATE(pSpxConnFile) == SPX_RECV_POSTED)) \ + { \ + SPX_RECV_SETSTATE( \ + pSpxConnFile, \ + (pSpxConnFile->scf_CurRecvReq == NULL) ? \ + SPX_RECV_IDLE : SPX_RECV_POSTED); \ + } \ + } + +#define SPX_INSERT_ADDR_ACTIVE(pSpxAddr, pSpxConnFile) \ + { \ + (pSpxConnFile)->scf_Next = (pSpxAddr)->sa_ActiveConnList; \ + (pSpxAddr)->sa_ActiveConnList = pSpxConnFile; \ + } + +#define SPX_INSERT_ADDR_INACTIVE(pSpxAddr, pSpxConnFile) \ + { \ + (pSpxConnFile)->scf_Next = (pSpxAddr)->sa_InactiveConnList; \ + (pSpxAddr)->sa_InactiveConnList = pSpxConnFile; \ + } + +#define SPX_INSERT_ADDR_LISTEN(pSpxAddr, pSpxConnFile) \ + { \ + (pSpxConnFile)->scf_Next = (pSpxAddr)->sa_ListenConnList; \ + (pSpxAddr)->sa_ListenConnList = pSpxConnFile; \ + } + + +// +// STATE MANIPULATION +// + +#if 0 +// +// Disabled for now +// +#define SPX_STORE_LAST_STATE(pSpxConnFile) \ + (pSpxConnFile)->scf_StateBuffer[(pSpxConnFile)->scf_NextStatePtr++] = \ + (pSpxConnFile)->scf_Flags; \ + (pSpxConnFile)->scf_NextStatePtr %= CFMAX_STATES; +#else + +#define SPX_STORE_LAST_STATE(pSpxConnFile) + +#endif + +#define SPX_MAIN_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags & SPX_CONNFILE_MAINMASK) + +// #define SPX_CONN_IDLE(pSpxConnFile) \ +// ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == 0)) + +#define SPX_CONN_IDLE(pSpxConnFile) \ + ((BOOLEAN)((SPX_MAIN_STATE(pSpxConnFile) == 0) || \ + ((SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_DISCONN) && \ + (SPX_DISC_STATE(pSpxConnFile) == SPX_DISC_INACTIVATED)))) + +#define SPX_CONN_ACTIVE(pSpxConnFile) \ + ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_ACTIVE)) + +#define SPX_CONN_CONNECTING(pSpxConnFile) \ + ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_CONNECTING)) + +#define SPX_CONN_LISTENING(pSpxConnFile) \ + ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_LISTENING)) + +#define SPX_CONN_DISC(pSpxConnFile) \ + ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_DISCONN)) + +#if DBG + +#define SPX_MAIN_SETSTATE(pSpxConnFile, newState) \ + { \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_CONNFILE_MAINMASK) | (newState));\ + } + +#else + +#define SPX_MAIN_SETSTATE(pSpxConnFile, newState) \ + { \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_CONNFILE_MAINMASK) | (newState));\ + } + +#endif + +#define SPX_CONN_FLAG(pSpxConnFile, Flag) \ + ((BOOLEAN)(((pSpxConnFile)->scf_Flags & (Flag)) != 0)) + +#define SPX_CONN_FLAG2(pSpxConnFile, Flag) \ + ((BOOLEAN)(((pSpxConnFile)->scf_Flags2 & (Flag)) != 0)) + +#if DBG + +#define SPX_CONN_SETFLAG(pSpxConnFile, Flag) \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags |= (Flag)) +#else + +#define SPX_CONN_SETFLAG(pSpxConnFile, Flag) \ + ((pSpxConnFile)->scf_Flags |= (Flag)) + +#endif + +#define SPX_CONN_SETFLAG2(pSpxConnFile, Flag) \ + ((pSpxConnFile)->scf_Flags2 |= (Flag)) + +#define SPX_CONN_RESETFLAG(pSpxConnFile, Flag) \ + ((pSpxConnFile)->scf_Flags &= ~(Flag)) + +#define SPX_CONN_RESETFLAG2(pSpxConnFile, Flag) \ + ((pSpxConnFile)->scf_Flags2 &= ~(Flag)) + +#define SPX2_CONN(pSpxConnFile) \ + (SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_SPX2)) + +#define SPX_CONN_STREAM(pSpxConnFile) \ + (SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_STREAM)) + +#define SPX_CONN_MSG(pSpxConnFile) \ + (!SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_STREAM)) + +#define SPX_LISTEN_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags & SPX_LISTEN_MASK) + +#define SPX_CONNECT_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags & SPX_CONNECT_MASK) + +#define SPX_SEND_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags & SPX_SEND_MASK) + +#define SPX_RECV_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags & SPX_RECV_MASK) + +#define SPX_DISC_STATE(pSpxConnFile) \ + ((pSpxConnFile)->scf_Flags & SPX_DISC_MASK) + +#if DBG + +#define SPX_LISTEN_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("LISTEN: %x -> %x\n", \ + SPX_LISTEN_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + pSpxConnFile->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_LISTEN_MASK) | (newState)); \ + } + +#define SPX_CONNECT_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("CONNECT: %x -> %x\n", \ + SPX_CONNECT_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_CONNECT_MASK) | (newState)); \ + } + +#define SPX_SEND_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("SEND: %x -> %x\n", \ + SPX_SEND_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_SEND_MASK) | (newState)); \ + } + +#define SPX_RECV_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("RECV: %x -> %x\n", \ + SPX_RECV_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_RECV_MASK) | (newState)); \ + } + +#define SPX_DISC_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("DISC: %x -> %x\n", \ + SPX_DISC_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + SPX_STORE_LAST_STATE(pSpxConnFile) \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_DISC_MASK) | (newState)); \ + } + +#else + +#define SPX_LISTEN_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("LISTEN: %x -> %x\n", \ + SPX_LISTEN_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + pSpxConnFile->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_LISTEN_MASK) | (newState)); \ + } + +#define SPX_CONNECT_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("CONNECT: %x -> %x\n", \ + SPX_CONNECT_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_CONNECT_MASK) | (newState)); \ + } + +#define SPX_SEND_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("SEND: %x -> %x\n", \ + SPX_SEND_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_SEND_MASK) | (newState)); \ + } + +#define SPX_RECV_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("RECV: %x -> %x\n", \ + SPX_RECV_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_RECV_MASK) | (newState)); \ + } + +#define SPX_DISC_SETSTATE(pSpxConnFile, newState) \ + { \ + DBGPRINT(STATE, INFO, \ + ("DISC: %x -> %x\n", \ + SPX_DISC_STATE(pSpxConnFile), (newState))); \ + DBGPRINT(STATE, INFO, \ + ("FILE: %s - %d\n", __FILE__, __LINE__)); \ + (pSpxConnFile)->scf_Flags = \ + (((pSpxConnFile)->scf_Flags & ~SPX_DISC_MASK) | (newState)); \ + } +#endif //DBG +#define SpxConnQueueSendPktTail(pSpxConnFile, pPkt) \ + { \ + PSPX_SEND_RESD _pSendResd; \ + _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \ + _pSendResd->sr_Next = NULL; \ + if ((pSpxConnFile)->scf_SendListTail != NULL) \ + { \ + (pSpxConnFile)->scf_SendListTail->sr_Next = _pSendResd; \ + (pSpxConnFile)->scf_SendListTail = _pSendResd;\ + } \ + else \ + { \ + (pSpxConnFile)->scf_SendListTail = \ + (pSpxConnFile)->scf_SendListHead = _pSendResd; \ + } \ + } + +#define SpxConnQueueSendPktHead(pSpxConnFile, pPkt) \ + { \ + PSPX_SEND_RESD _pSendResd; \ + _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \ + _pSendResd->sr_Next = NULL; \ + if ((pSpxConnFile)->scf_SendListTail != NULL) \ + { \ + _pSendResd->sr_Next = (pSpxConnFile)->scf_SendListHead; \ + } \ + else \ + { \ + (pSpxConnFile)->scf_SendListTail = _pSendResd; \ + } \ + (pSpxConnFile)->scf_SendListHead = _pSendResd; \ + } + +#define SpxConnQueueSendSeqPktTail(pSpxConnFile, pPkt) \ + { \ + PSPX_SEND_RESD _pSendResd; \ + _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \ + _pSendResd->sr_Next = NULL; \ + if ((pSpxConnFile)->scf_SendSeqListTail != NULL) \ + { \ + (pSpxConnFile)->scf_SendSeqListTail->sr_Next = _pSendResd;\ + (pSpxConnFile)->scf_SendSeqListTail = _pSendResd;\ + } \ + else \ + { \ + (pSpxConnFile)->scf_SendSeqListTail = \ + (pSpxConnFile)->scf_SendSeqListHead = _pSendResd; \ + } \ + } + +#define SpxConnQueueSendSeqPktHead(pSpxConnFile, pPkt) \ + { \ + PSPX_SEND_RESD _pSendResd; \ + _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \ + _pSendResd->sr_Next = NULL; \ + if ((pSpxConnFile)->scf_SendSeqListTail != NULL) \ + { \ + _pSendResd->sr_Next = (pSpxConnFile)->scf_SendSeqListHead;\ + } \ + else \ + { \ + (pSpxConnFile)->scf_SendSeqListTail = _pSendResd; \ + } \ + (pSpxConnFile)->scf_SendSeqListHead = _pSendResd; \ + } + +#define SpxConnQueueRecvPktTail(pSpxConnFile, pPkt) \ + { \ + PSPX_RECV_RESD _pRecvResd; \ + _pRecvResd = (PSPX_RECV_RESD)((pPkt)->ProtocolReserved); \ + _pRecvResd->rr_Next = NULL; \ + if ((pSpxConnFile)->scf_RecvListTail != NULL) \ + { \ + (pSpxConnFile)->scf_RecvListTail->rr_Next = _pRecvResd; \ + (pSpxConnFile)->scf_RecvListTail = _pRecvResd;\ + } \ + else \ + { \ + (pSpxConnFile)->scf_RecvListTail = \ + (pSpxConnFile)->scf_RecvListHead = _pRecvResd; \ + } \ + } + +#define SpxConnQueueRecvPktHead(pSpxConnFile, pPkt) \ + { \ + PSPX_RECV_RESD _pRecvResd; \ + _pRecvResd = (PSPX_RECV_RESD)((pPkt)->ProtocolReserved); \ + _pRecvResd->rr_Next = NULL; \ + if ((pSpxConnFile)->scf_RecvListTail != NULL) \ + { \ + _pRecvResd->rr_Next = (pSpxConnFile)->scf_RecvListHead; \ + } \ + else \ + { \ + (pSpxConnFile)->scf_RecvListTail = _pRecvResd; \ + } \ + (pSpxConnFile)->scf_RecvListHead = _pRecvResd; \ + } + +#if DBG +#define SpxConnFileReference(_ConnFile, _Type) \ + { \ + (VOID)SPX_ADD_ULONG ( \ + &(_ConnFile)->scf_RefTypes[_Type], \ + 1, \ + &SpxGlobalInterlock); \ + SpxConnFileRef (_ConnFile); \ + } + +#define SpxConnFileLockReference(_ConnFile, _Type) \ + { \ + (VOID)SPX_ADD_ULONG ( \ + &(_ConnFile)->scf_RefTypes[_Type], \ + 1, \ + &SpxGlobalInterlock); \ + SpxConnFileLockRef (_ConnFile); \ + } + +#define SpxConnFileDereference(_ConnFile, _Type) \ + { \ + (VOID)SPX_ADD_ULONG ( \ + &(_ConnFile)->scf_RefTypes[_Type], \ + (ULONG)-1, \ + &SpxGlobalInterlock); \ + SpxConnFileDeref (_ConnFile); \ + } + +#define SpxConnFileReferenceByCtx(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \ + { \ + CTELockHandle _lockHandle; \ + CTEGetLock((_pAddrFile)->saf_AddrLock, &(_lockHandle)); \ + SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));\ + CTEFreeLock((_pAddrFile)->saf_AddrLock, (_lockHandle)); \ + } + +#define SpxConnFileReferenceByCtxLock(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \ + SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus)); + +#define SpxConnFileReferenceById(_ConnId, _ppConnFile, _pStatus) \ + { \ + CTELockHandle _l; \ + CTEGetLock(&SpxDevice->dev_Lock, &(_l)); \ + SpxConnFileRefByIdLock(_ConnId, _ppConnFile, _pStatus); \ + CTEFreeLock(&SpxDevice->dev_Lock, _l); \ + } + +#define SpxConnFileTransferReference(_ConnFile, _OldType, _NewType) \ + { \ + (VOID)SPX_ADD_ULONG ( \ + &(_ConnFile)->scf_RefTypes[_NewType], \ + 1, \ + &SpxGlobalInterlock); \ + (VOID)SPX_ADD_ULONG ( \ + &(_ConnFile)->scf_RefTypes[_OldType], \ + (ULONG)-1, \ + &SpxGlobalInterlock); \ + } + +#else // DBG + +#define SpxConnFileReference(_ConnFile, _Type) \ + SPX_ADD_ULONG( \ + &(_ConnFile)->scf_RefCount, \ + 1, \ + &(_ConnFile)->scf_Lock) + +#define SpxConnFileLockReference(_ConnFile, _Type) \ + SPX_ADD_ULONG( \ + &(_ConnFile)->scf_RefCount, \ + 1, \ + &(_ConnFile)->scf_Lock); + +#define SpxConnFileDereference(_ConnFile, _Type) \ + { \ + SpxConnFileDeref(_ConnFile); \ + } + +#define SpxConnFileReferenceByCtx(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \ + { \ + CTELockHandle _lockHandle; \ + CTEGetLock((_pAddrFile)->saf_AddrLock, &(_lockHandle)); \ + SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));\ + CTEFreeLock((_pAddrFile)->saf_AddrLock, (_lockHandle)); \ + } + +#define SpxConnFileReferenceByCtxLock(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \ + SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus)); + +#define SpxConnFileReferenceById(_ConnId, _ppConnFile, _pStatus) \ + { \ + CTELockHandle _lockHandle; \ + CTEGetLock(&SpxDevice->dev_Lock, &(_lockHandle)); \ + SpxConnFileRefByIdLock(_ConnId, _ppConnFile, _pStatus); \ + CTEFreeLock(&SpxDevice->dev_Lock, (_lockHandle)); \ + } + +#define SpxConnFileTransferReference(_ConnFile, _OldType, _NewType) + +#endif // DBG + + +// Set the packet size. If we are spx1 or spx2 and !neg, check if we are different +// nets, set to min then, else use the size indicated by IPX. If we are spx2, just +// set it to our local max. +// +// Also always even out packet size and round down. This solves an issue with +// data size needing to be even for some novell 802.2 clients. +// +// Fix after beta2 for tokring using receive size. Only if spx2 and neg. +#if defined(_PNP_POWER) +#define SPX_MAX_PKT_SIZE(pSpxConnFile, fSpx2Neg, fSpx2, pRemNet) \ + { \ + if (!fSpx2 && PARAM(CONFIG_BACKCOMP_SPX)) { \ + (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \ + } \ + else { \ + IPX_LINE_INFO _i; \ + \ + (VOID)(*IpxQuery)( \ + IPX_QUERY_LINE_INFO, \ + &(pSpxConnFile)->scf_LocalTarget.NicHandle, \ + &(_i), \ + sizeof(IPX_LINE_INFO), \ + NULL); \ + \ + (pSpxConnFile)->scf_MaxPktSize = (_i).MaximumPacketSize; \ + if (!fSpx2Neg) \ + { \ + (pSpxConnFile)->scf_MaxPktSize = (_i).MaximumSendSize; \ + } \ + \ + if ((pSpxConnFile)->scf_MaxPktSize < SPX_MAX_PACKET) \ + { \ + (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \ + } \ + \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \ + (*(UNALIGNED ULONG *)(pRemNet)), \ + *(UNALIGNED ULONG *)SpxDevice->dev_Network, \ + (pSpxConnFile)->scf_MaxPktSize)); \ + DBGPRINT(CONNECT, DBG, \ + ("%s : %d.%d\n", __FILE__, __LINE__, fSpx2Neg)); \ + \ + if ((!fSpx2Neg) && \ + ((*(UNALIGNED ULONG *)(pRemNet)) != 0) && \ + ((*(UNALIGNED ULONG *)SpxDevice->dev_Network) != 0) && \ + ((*(UNALIGNED ULONG *)(pRemNet)) != \ + *(UNALIGNED ULONG *)SpxDevice->dev_Network)) \ + { \ + if (PARAM(CONFIG_ROUTER_MTU) != 0) \ + { \ + DBGPRINT(CONNECT, ERR, \ + ("SPX_MAX_PKT_SIZE: PARAM %lx Max Pkt %lx\n", \ + PARAM(CONFIG_ROUTER_MTU), \ + (pSpxConnFile)->scf_MaxPktSize)); \ + \ + (pSpxConnFile)->scf_MaxPktSize = \ + (USHORT)(MIN(PARAM(CONFIG_ROUTER_MTU), \ + (ULONG)((pSpxConnFile)->scf_MaxPktSize)));\ + } \ + else \ + { \ + (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \ + } \ + \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \ + (*(UNALIGNED ULONG *)(pRemNet)), \ + *(UNALIGNED ULONG *)SpxDevice->dev_Network, \ + (pSpxConnFile)->scf_MaxPktSize)); \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: LineInfo Pkt %d\n", \ + (_i).MaximumSendSize)); \ + } \ + } \ + (pSpxConnFile)->scf_MaxPktSize &= ~((USHORT)1); \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: %lx.%d\n", \ + (pSpxConnFile)->scf_MaxPktSize, \ + (pSpxConnFile)->scf_MaxPktSize)); \ + } +#else +#define SPX_MAX_PKT_SIZE(pSpxConnFile, fSpx2Neg, fSpx2, pRemNet) \ + { \ + if (!fSpx2 && PARAM(CONFIG_BACKCOMP_SPX)) { \ + (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \ + } \ + else { \ + IPX_LINE_INFO _i; \ + \ + (VOID)(*IpxQuery)( \ + IPX_QUERY_LINE_INFO, \ + (pSpxConnFile)->scf_LocalTarget.NicId, \ + &(_i), \ + sizeof(IPX_LINE_INFO), \ + NULL); \ + \ + (pSpxConnFile)->scf_MaxPktSize = (_i).MaximumPacketSize; \ + if (!fSpx2Neg) \ + { \ + (pSpxConnFile)->scf_MaxPktSize = (_i).MaximumSendSize; \ + } \ + \ + if ((pSpxConnFile)->scf_MaxPktSize < SPX_MAX_PACKET) \ + { \ + (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \ + } \ + \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \ + (*(UNALIGNED ULONG *)(pRemNet)), \ + *(UNALIGNED ULONG *)SpxDevice->dev_Network, \ + (pSpxConnFile)->scf_MaxPktSize)); \ + DBGPRINT(CONNECT, DBG, \ + ("%s : %d.%d\n", __FILE__, __LINE__, fSpx2Neg)); \ + \ + if ((!fSpx2Neg) && \ + ((*(UNALIGNED ULONG *)(pRemNet)) != 0) && \ + ((*(UNALIGNED ULONG *)SpxDevice->dev_Network) != 0) && \ + ((*(UNALIGNED ULONG *)(pRemNet)) != \ + *(UNALIGNED ULONG *)SpxDevice->dev_Network)) \ + { \ + if (PARAM(CONFIG_ROUTER_MTU) != 0) \ + { \ + DBGPRINT(CONNECT, ERR, \ + ("SPX_MAX_PKT_SIZE: PARAM %lx Max Pkt %lx\n", \ + PARAM(CONFIG_ROUTER_MTU), \ + (pSpxConnFile)->scf_MaxPktSize)); \ + \ + (pSpxConnFile)->scf_MaxPktSize = \ + (USHORT)(MIN(PARAM(CONFIG_ROUTER_MTU), \ + (ULONG)((pSpxConnFile)->scf_MaxPktSize)));\ + } \ + else \ + { \ + (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \ + } \ + \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \ + (*(UNALIGNED ULONG *)(pRemNet)), \ + *(UNALIGNED ULONG *)SpxDevice->dev_Network, \ + (pSpxConnFile)->scf_MaxPktSize)); \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: LineInfo Pkt %d\n", \ + (_i).MaximumSendSize)); \ + } \ + } \ + (pSpxConnFile)->scf_MaxPktSize &= ~((USHORT)1); \ + DBGPRINT(CONNECT, DBG, \ + ("SPX_MAX_PKT_SIZE: %lx.%d\n", \ + (pSpxConnFile)->scf_MaxPktSize, \ + (pSpxConnFile)->scf_MaxPktSize)); \ + } +#endif _PNP_POWER + +#if DBG +#define SPX_SENDPACKET(pSpxConnFile, pNdisPkt, pSendResd) \ + { \ + NDIS_STATUS _n; \ + \ + ++SpxDevice->dev_Stat.PacketsSent; \ + \ + _n = (*IpxSendPacket)( \ + &(pSpxConnFile)->scf_LocalTarget, \ + (pNdisPkt), \ + (pSendResd)->sr_Len, \ + (pSendResd)->sr_HdrLen); \ + \ + if (_n != NDIS_STATUS_PENDING) \ + { \ + if (_n != NDIS_STATUS_SUCCESS) \ + { \ + DBGPRINT(SEND, ERR, \ + ("SPX_SENDPACKET: Failed with %lx in %s.%lx\n", \ + _n, __FILE__, __LINE__)); \ + } \ + \ + SpxSendComplete( \ + (pNdisPkt), \ + _n); \ + } \ + } + +#define SPX_SENDACK(pSpxConnFile, pNdisPkt, pSendResd) \ + { \ + NDIS_STATUS _n; \ + \ + ++SpxDevice->dev_Stat.PacketsSent; \ + \ + _n = (*IpxSendPacket)( \ + &(pSpxConnFile)->scf_AckLocalTarget, \ + (pNdisPkt), \ + (pSendResd)->sr_Len, \ + (pSendResd)->sr_HdrLen); \ + \ + if (_n != NDIS_STATUS_PENDING) \ + { \ + if (_n != NDIS_STATUS_SUCCESS) \ + { \ + DBGPRINT(SEND, ERR, \ + ("SPX_SENDPACKET: Failed with %lx in %s.%lx\n", \ + _n, __FILE__, __LINE__)); \ + } \ + \ + SpxSendComplete( \ + (pNdisPkt), \ + _n); \ + } \ + } + +#else // DBG +#define SPX_SENDPACKET(pSpxConnFile, pNdisPkt, pSendResd) \ + { \ + NDIS_STATUS _n; \ + \ + ++SpxDevice->dev_Stat.PacketsSent; \ + \ + _n = (*IpxSendPacket)( \ + &(pSpxConnFile)->scf_LocalTarget, \ + (pNdisPkt), \ + (pSendResd)->sr_Len, \ + (pSendResd)->sr_HdrLen); \ + \ + if (_n != NDIS_STATUS_PENDING) \ + { \ + SpxSendComplete( \ + (pNdisPkt), \ + _n); \ + } \ + } +#define SPX_SENDACK(pSpxConnFile, pNdisPkt, pSendResd) \ + { \ + NDIS_STATUS _n; \ + \ + ++SpxDevice->dev_Stat.PacketsSent; \ + \ + _n = (*IpxSendPacket)( \ + &(pSpxConnFile)->scf_AckLocalTarget, \ + (pNdisPkt), \ + (pSendResd)->sr_Len, \ + (pSendResd)->sr_HdrLen); \ + \ + if (_n != NDIS_STATUS_PENDING) \ + { \ + SpxSendComplete( \ + (pNdisPkt), \ + _n); \ + } \ + } + +#endif // DBG + +#define SPX_QUEUE_FOR_RECV_COMPLETION(pSpxConnFile) \ + { \ + if (!SPX_CONN_FLAG( \ + (pSpxConnFile), \ + SPX_CONNFILE_RECVQ)) \ + { \ + SPX_CONN_SETFLAG((pSpxConnFile), SPX_CONNFILE_RECVQ); \ + SpxConnFileLockReference(pSpxConnFile, CFREF_RECV); \ + SPX_QUEUE_TAIL_RECVLIST(pSpxConnFile); \ + } \ + } + +#define SPX_QUEUE_TAIL_PKTLIST(pSpxConnFile) \ + { \ + if (SpxPktConnList.pcl_Tail) \ + { \ + SpxPktConnList.pcl_Tail->scf_PktNext = pSpxConnFile; \ + SpxPktConnList.pcl_Tail = pSpxConnFile; \ + } \ + else \ + { \ + SpxPktConnList.pcl_Tail = \ + SpxPktConnList.pcl_Head = pSpxConnFile; \ + } \ + } + +#define SPX_QUEUE_TAIL_RECVLIST(pSpxConnFile) \ + { \ + if (SpxRecvConnList.pcl_Tail) \ + { \ + SpxRecvConnList.pcl_Tail->scf_ProcessRecvNext = pSpxConnFile; \ + SpxRecvConnList.pcl_Tail = pSpxConnFile; \ + } \ + else \ + { \ + SpxRecvConnList.pcl_Tail = \ + SpxRecvConnList.pcl_Head = pSpxConnFile; \ + } \ + } + + |