/*++ 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. // 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); BOOLEAN CheckSentPacket( PNDIS_PACKET npkt, UINT hlen, UINT len); // // 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 = (USHORT) (_i).MaximumPacketSize; \ if (!fSpx2Neg) \ { \ (pSpxConnFile)->scf_MaxPktSize = (USHORT) (_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; \ } \ }