1326 lines
35 KiB
C
1326 lines
35 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
llcapi.h
|
||
|
||
Abstract:
|
||
|
||
This module defined the kernel API of data link driver.
|
||
All function prototypes and typedefs of the interface
|
||
have been defined here.
|
||
|
||
Author:
|
||
|
||
Antti Saarenheimo (o-anttis) 17-MAY-1991
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#ifndef _LLC_API_
|
||
#define _LLC_API_
|
||
|
||
#include "llcmem.h"
|
||
|
||
//
|
||
// The debug switches
|
||
//
|
||
|
||
//
|
||
// LLC_DBG:
|
||
//
|
||
// 0 => No debug code is generated
|
||
// 1 => Enables the memory allocation accounting, state machine tracing,
|
||
// procedure call tracing and internal consistency checks
|
||
// 2 => Enables memory block overflow checking
|
||
//
|
||
//
|
||
|
||
#define LLC_DBG 0
|
||
#define DBG_MP 0 // enables the MP safe versions of the accounting macros
|
||
|
||
#define DLC_TRACE_ENABLED 1 // Procedure call tracing, debug only.
|
||
|
||
extern NDIS_SPIN_LOCK DlcDriverLock;
|
||
|
||
//
|
||
// ANY_IRQL: pseudo value used in ASSUME_IRQL to mean routine is not IRQL sensitive.
|
||
// Use this value with ASSUME_IRQL instead of omitting ASSUME_IRQL from a routine
|
||
// (shows that we didn't forget this routine)
|
||
//
|
||
|
||
#define ANY_IRQL ((ULONG)-1)
|
||
|
||
#if defined(LOCK_CHECK)
|
||
|
||
extern LONG DlcDriverLockLevel;
|
||
extern ULONG __line;
|
||
extern PCHAR __file;
|
||
extern LONG __last;
|
||
extern HANDLE __process;
|
||
extern HANDLE __thread;
|
||
|
||
//
|
||
// _strip - quick functionette to strip out the path garbage from __FILE__
|
||
//
|
||
|
||
__inline char* _strip(char* s) {
|
||
|
||
char* e = s + strlen(s) - 1;
|
||
|
||
while (e != s) {
|
||
if (*e == '\\') {
|
||
return e + 1;
|
||
}
|
||
--e;
|
||
}
|
||
return s;
|
||
}
|
||
|
||
#define $$_PLACE "%s!%d"
|
||
#define $$_FILE_AND_LINE _strip(__FILE__), __LINE__
|
||
|
||
//
|
||
// ACQUIRE_DRIVER_LOCK - acquires the global DLC driver Spin Lock, using
|
||
// NdisAcquireSpinLock(). We also check for re-entrancy and incorrect ordering
|
||
// of spin lock calls
|
||
//
|
||
|
||
#define ACQUIRE_DRIVER_LOCK() \
|
||
{ \
|
||
KIRQL currentIrql; \
|
||
HANDLE hprocess; \
|
||
HANDLE hthread; \
|
||
\
|
||
currentIrql = KeGetCurrentIrql(); \
|
||
if (currentIrql == PASSIVE_LEVEL) { \
|
||
\
|
||
PETHREAD pthread; \
|
||
\
|
||
pthread = PsGetCurrentThread(); \
|
||
hprocess = pthread->Cid.UniqueProcess; \
|
||
hthread = pthread->Cid.UniqueThread; \
|
||
} else { \
|
||
hprocess = (HANDLE)-1; \
|
||
hthread = (HANDLE)-1; \
|
||
} \
|
||
NdisAcquireSpinLock(&DlcDriverLock); \
|
||
if (++DlcDriverLockLevel != 1) { \
|
||
__last = DlcDriverLockLevel; \
|
||
DbgPrint("%d.%d:" $$_PLACE ": ACQUIRE_DRIVER_LOCK: level = %d. Last = %d.%d:" $$_PLACE "\n", \
|
||
hprocess, \
|
||
hthread, \
|
||
$$_FILE_AND_LINE, \
|
||
DlcDriverLockLevel, \
|
||
__process, \
|
||
__thread, \
|
||
__file, \
|
||
__line \
|
||
); \
|
||
DbgBreakPoint(); \
|
||
} \
|
||
__file = _strip(__FILE__); \
|
||
__line = __LINE__; \
|
||
__process = hprocess; \
|
||
__thread = hthread; \
|
||
ASSUME_IRQL(DISPATCH_LEVEL); \
|
||
}
|
||
|
||
//
|
||
// RELEASE_DRIVER_LOCK - releases the global DLC driver Spin Lock, using
|
||
// NdisReleaseSpinLock(). We also check for re-entrancy and incorrect ordering
|
||
// of spin lock calls
|
||
//
|
||
|
||
#define RELEASE_DRIVER_LOCK() \
|
||
if (DlcDriverLockLevel != 1) { \
|
||
DbgPrint($$_PLACE ": RELEASE_DRIVER_LOCK: level = %d. Last = %d.%d:" $$_PLACE "\n", \
|
||
$$_FILE_AND_LINE, \
|
||
DlcDriverLockLevel, \
|
||
__process, \
|
||
__thread, \
|
||
__file, \
|
||
__line \
|
||
); \
|
||
DbgBreakPoint(); \
|
||
} \
|
||
--DlcDriverLockLevel; \
|
||
__file = _strip(__FILE__); \
|
||
__line = __LINE__; \
|
||
NdisReleaseSpinLock(&DlcDriverLock);
|
||
|
||
//
|
||
// ASSUME_IRQL - used to check that a routine is being called at the IRQL we
|
||
// expect. Due to the design of DLC, most functions are called at raised IRQL
|
||
// (DISPATCH_LEVEL). Used mainly to assure that IRQL is at PASSIVE_LEVEL when
|
||
// we do something which may incur a page fault e.g.
|
||
//
|
||
|
||
#define ASSUME_IRQL(level) \
|
||
if (((level) != ANY_IRQL) && (KeGetCurrentIrql() != (level))) { \
|
||
DbgPrint($$_PLACE ": ASSUME_IRQL(%d): Actual is %d\n", \
|
||
$$_FILE_AND_LINE, \
|
||
level, \
|
||
KeGetCurrentIrql() \
|
||
); \
|
||
DbgBreakPoint(); \
|
||
}
|
||
|
||
//
|
||
// MY_ASSERT - since ASSERT only expands to something meaningful in the checked
|
||
// build, we use this when we want an assertion check in a free build
|
||
//
|
||
|
||
#define MY_ASSERT(x) \
|
||
if (!(x)) { \
|
||
DbgPrint($$_PLACE ": Assertion Failed: " # x "\n", \
|
||
$$_FILE_AND_LINE \
|
||
); \
|
||
DbgBreakPoint(); \
|
||
}
|
||
|
||
//
|
||
// IF_LOCK_CHECK - conditional compilation made cleaner
|
||
//
|
||
|
||
#define IF_LOCK_CHECK \
|
||
if (TRUE)
|
||
|
||
#else
|
||
|
||
#define ACQUIRE_DRIVER_LOCK() NdisAcquireSpinLock(&DlcDriverLock)
|
||
#define RELEASE_DRIVER_LOCK() NdisReleaseSpinLock(&DlcDriverLock)
|
||
#define ASSUME_IRQL(level) /* NOTHING */
|
||
#define MY_ASSERT(x) /* NOTHING */
|
||
#define IF_LOCK_CHECK if (FALSE)
|
||
|
||
#endif
|
||
|
||
//
|
||
// in the Unilock DLC, we do not need the LLC spin-lock
|
||
//
|
||
|
||
#if defined(DLC_UNILOCK)
|
||
|
||
#define ACQUIRE_LLC_LOCK(i)
|
||
#define RELEASE_LLC_LOCK(i)
|
||
|
||
#define ACQUIRE_SPIN_LOCK(p)
|
||
#define RELEASE_SPIN_LOCK(p)
|
||
|
||
#define ALLOCATE_SPIN_LOCK(p)
|
||
#define DEALLOCATE_SPIN_LOCK(p)
|
||
|
||
#else
|
||
|
||
#define ACQUIRE_LLC_LOCK(i) KeAcquireSpinLock(&LlcSpinLock, (i))
|
||
#define RELEASE_LLC_LOCK(i) KeReleaseSpinLock(&LlcSpinLock, (i))
|
||
|
||
#define ACQUIRE_SPIN_LOCK(p) NdisAcquireSpinLock((p))
|
||
#define RELEASE_SPIN_LOCK(p) NdisReleaseSpinLock((p))
|
||
|
||
#define ALLOCATE_SPIN_LOCK(p) KeInitializeSpinLock(&(p)->SpinLock)
|
||
#define DEALLOCATE_SPIN_LOCK(p)
|
||
|
||
#endif
|
||
|
||
//
|
||
// IS_SNA_DIX_FRAME - TRUE if the frame just received & therefore described in
|
||
// the ADAPTER_CONTEXT (p) has DIX framing (SNA)
|
||
//
|
||
|
||
#define IS_SNA_DIX_FRAME(p) \
|
||
(((PADAPTER_CONTEXT)(p))->IsSnaDixFrame)
|
||
|
||
//
|
||
// IS_AUTO_BINDING - TRUE if the BINDING_CONTEXT was created with
|
||
// LLC_ETHERNET_TYPE_AUTO
|
||
//
|
||
|
||
#define IS_AUTO_BINDING(p) \
|
||
(((PBINDING_CONTEXT)(p))->EthernetType == LLC_ETHERNET_TYPE_AUTO)
|
||
|
||
#define FRAME_MASK_LLC_LOCAL_DEST 0x0001
|
||
#define FRAME_MASK_NON_LLC_LOCAL_DEST 0x0002
|
||
#define FRAME_MASK_NON_LOCAL_DEST 0x0004
|
||
#define FRAME_MASK_ALL_FRAMES 0x0007
|
||
|
||
#define LLC_EXCLUSIVE_ACCESS 0x0001
|
||
#define LLC_HANDLE_XID_COMMANDS 0x0002
|
||
|
||
//
|
||
// Direct station receive flags (bits 0 and 1 are inverted from dlcapi!!!)
|
||
//
|
||
|
||
#define DLC_RCV_SPECIFIC_DIX 0
|
||
#define DLC_RCV_MAC_FRAMES 1
|
||
#define DLC_RCV_8022_FRAMES 2
|
||
#define DLC_RCV_DIX_FRAMES 4
|
||
#define LLC_VALID_RCV_MASK 7
|
||
#define DLC_RCV_OTHER_DESTINATION 8
|
||
|
||
#define MAX_LLC_FRAME_TYPES 10
|
||
|
||
//
|
||
// The DLC link states reported by DLC API
|
||
//
|
||
|
||
enum _DATA_LINK_STATES {
|
||
|
||
//
|
||
// Primary states
|
||
//
|
||
|
||
LLC_LINK_CLOSED = 0x80,
|
||
LLC_DISCONNECTED = 0x40,
|
||
LLC_DISCONNECTING = 0x20,
|
||
LLC_LINK_OPENING = 0x10,
|
||
LLC_RESETTING = 0x08,
|
||
LLC_FRMR_SENT = 0x04,
|
||
LLC_FRMR_RECEIVED = 0x02,
|
||
LLC_LINK_OPENED = 0x01,
|
||
|
||
//
|
||
// Secondary states (when primary state is LLC_LINK_OPENED)
|
||
//
|
||
|
||
LLC_CHECKPOINTING = 0x80,
|
||
LLC_LOCAL_BUSY_USER_SET = 0x40,
|
||
LLC_LOCAL_BUSY_BUFFER_SET = 0x20,
|
||
LLC_REMOTE_BUSY = 0x10,
|
||
LLC_REJECTING = 0x08,
|
||
LLC_CLEARING = 0x04,
|
||
LLC_DYNMIC_WIN_ALG_RUNNIG = 0x02,
|
||
LLC_NO_SECONDARY_STATE = 0
|
||
};
|
||
|
||
//
|
||
// LAN802_ADDRESS - 8 bytes of frame address. Typically 6 bytes LAN address
|
||
// plus 1 byte destination SAP, plus 1 byte source SAP
|
||
//
|
||
|
||
typedef union {
|
||
|
||
struct {
|
||
UCHAR DestSap;
|
||
UCHAR SrcSap;
|
||
USHORT usHigh;
|
||
ULONG ulLow;
|
||
} Address;
|
||
|
||
struct {
|
||
ULONG High;
|
||
ULONG Low;
|
||
} ul;
|
||
|
||
struct {
|
||
USHORT Raw[4];
|
||
} aus;
|
||
|
||
struct {
|
||
UCHAR DestSap;
|
||
UCHAR SrcSap;
|
||
UCHAR auchAddress[6];
|
||
} Node;
|
||
|
||
UCHAR auchRawAddress[8];
|
||
|
||
} LAN802_ADDRESS, *PLAN802_ADDRESS;
|
||
|
||
//
|
||
// Structure is used by DlcNdisRequest function
|
||
//
|
||
|
||
typedef struct {
|
||
NDIS_STATUS AsyncStatus;
|
||
KEVENT SyncEvent;
|
||
NDIS_REQUEST Ndis;
|
||
} LLC_NDIS_REQUEST, *PLLC_NDIS_REQUEST;
|
||
|
||
#define NDIS_INFO_BUF_SIZE 20
|
||
|
||
#define DLC_ANY_STATION (-1)
|
||
|
||
//
|
||
// Internal event flags used by Timer, DlcConnect
|
||
// and DlcClose commands.
|
||
//
|
||
|
||
#define DLC_REPEATED_FLAGS 0x0700
|
||
#define LLC_TIMER_TICK_EVENT 0x0100
|
||
#define LLC_STATUS_CHANGE_ON_SAP 0x0800
|
||
|
||
//
|
||
// These enum types are used also as the index of a mapping table!
|
||
//
|
||
|
||
enum _LLC_OBJECT_TYPES {
|
||
LLC_DIRECT_OBJECT,
|
||
LLC_SAP_OBJECT,
|
||
LLC_GROUP_SAP_OBJECT,
|
||
LLC_LINK_OBJECT,
|
||
LLC_DIX_OBJECT
|
||
};
|
||
|
||
//
|
||
// We moved these defines here because the macro is used by data link
|
||
//
|
||
|
||
#define MIN_DLC_BUFFER_SEGMENT 256
|
||
////#define MAX_DLC_BUFFER_SEGMENT 4096
|
||
//#define MAX_DLC_BUFFER_SEGMENT 8192
|
||
#define MAX_DLC_BUFFER_SEGMENT PAGE_SIZE
|
||
|
||
#define BufGetPacketSize( PacketSize ) \
|
||
(((PacketSize) + 2 * MIN_DLC_BUFFER_SEGMENT - 1) & \
|
||
-MIN_DLC_BUFFER_SEGMENT)
|
||
|
||
//
|
||
// READ Event flags:
|
||
//
|
||
|
||
#define DLC_READ_FLAGS 0x007f
|
||
#define LLC_SYSTEM_ACTION 0x0040
|
||
#define LLC_NETWORK_STATUS 0x0020
|
||
#define LLC_CRITICAL_EXCEPTION 0x0010
|
||
#define LLC_STATUS_CHANGE 0x0008
|
||
#define LLC_RECEIVE_DATA 0x0004
|
||
#define LLC_TRANSMIT_COMPLETION 0x0002
|
||
#define DLC_COMMAND_COMPLETION 0x0001
|
||
|
||
#define ALL_DLC_EVENTS -1
|
||
|
||
//
|
||
// LLC_STATUS_CHANGE indications:
|
||
//
|
||
|
||
#define INDICATE_LINK_LOST 0x8000
|
||
#define INDICATE_DM_DISC_RECEIVED 0x4000
|
||
#define INDICATE_FRMR_RECEIVED 0x2000
|
||
#define INDICATE_FRMR_SENT 0x1000
|
||
#define INDICATE_RESET 0x0800
|
||
#define INDICATE_CONNECT_REQUEST 0x0400
|
||
#define INDICATE_REMOTE_BUSY 0x0200
|
||
#define INDICATE_REMOTE_READY 0x0100
|
||
#define INDICATE_TI_TIMER_EXPIRED 0x0080
|
||
#define INDICATE_DLC_COUNTER_OVERFLOW 0x0040
|
||
#define INDICATE_ACCESS_PRTY_LOWERED 0x0020
|
||
#define INDICATE_LOCAL_STATION_BUSY 0x0001
|
||
|
||
//
|
||
// LLC Command completion indications.
|
||
//
|
||
|
||
enum _LLC_COMPLETION_CODES {
|
||
LLC_RECEIVE_COMPLETION,
|
||
LLC_SEND_COMPLETION,
|
||
LLC_REQUEST_COMPLETION,
|
||
LLC_CLOSE_COMPLETION,
|
||
LLC_RESET_COMPLETION,
|
||
LLC_CONNECT_COMPLETION,
|
||
LLC_DISCONNECT_COMPLETION
|
||
};
|
||
|
||
typedef union {
|
||
LLC_ADAPTER_INFO Adapter;
|
||
DLC_LINK_PARAMETERS LinkParms;
|
||
LLC_TICKS Timer;
|
||
DLC_LINK_LOG LinkLog;
|
||
DLC_SAP_LOG SapLog;
|
||
UCHAR PermanentAddress[6];
|
||
UCHAR auchBuffer[1];
|
||
} LLC_QUERY_INFO_BUFFER, *PLLC_QUERY_INFO_BUFFER;
|
||
|
||
typedef union {
|
||
DLC_LINK_PARAMETERS LinkParms;
|
||
LLC_TICKS Timers;
|
||
UCHAR auchFunctionalAddress[4];
|
||
UCHAR auchGroupAddress[4];
|
||
UCHAR auchBuffer[1];
|
||
} LLC_SET_INFO_BUFFER, *PLLC_SET_INFO_BUFFER;
|
||
|
||
//
|
||
// LLC_FRMR_INFORMATION - 5 bytes of FRaMe Reject code
|
||
//
|
||
|
||
typedef struct {
|
||
UCHAR Command; // format: mmmpmm11, m=modifiers, p=poll/final.
|
||
UCHAR Ctrl; // control field of rejected frame.
|
||
UCHAR Vs; // our next send when error was detected.
|
||
UCHAR Vr; // our next receive when error was detected.
|
||
UCHAR Reason; // reason for sending FRMR: 000VZYXW.
|
||
} LLC_FRMR_INFORMATION, *PLLC_FRMR_INFORMATION;
|
||
|
||
//
|
||
// DLC_STATUS_TABLE - format of status information returned in a READ command
|
||
//
|
||
|
||
typedef struct {
|
||
USHORT StatusCode;
|
||
LLC_FRMR_INFORMATION FrmrData;
|
||
UCHAR uchAccessPriority;
|
||
UCHAR auchRemoteNode[6];
|
||
UCHAR uchRemoteSap;
|
||
UCHAR uchLocalSap;
|
||
PVOID hLlcLinkStation;
|
||
} DLC_STATUS_TABLE, *PDLC_STATUS_TABLE;
|
||
|
||
typedef struct {
|
||
ULONG IsCompleted;
|
||
ULONG Status;
|
||
} ASYNC_STATUS, *PASYNC_STATUS;
|
||
|
||
union _LLC_OBJECT;
|
||
typedef union _LLC_OBJECT LLC_OBJECT, *PLLC_OBJECT;
|
||
|
||
struct _BINDING_CONTEXT;
|
||
typedef struct _BINDING_CONTEXT BINDING_CONTEXT, *PBINDING_CONTEXT;
|
||
|
||
//
|
||
// LLC packet headers
|
||
//
|
||
|
||
//
|
||
// LLC_XID_INFORMATION - 3 information bytes in a standard LLC XID packet
|
||
//
|
||
|
||
typedef struct {
|
||
UCHAR FormatId; // format of this XID frame.
|
||
UCHAR Info1; // first information byte.
|
||
UCHAR Info2; // second information byte.
|
||
} LLC_XID_INFORMATION, *PLLC_XID_INFORMATION;
|
||
|
||
//
|
||
// LLC_TEST_INFORMATION - information field for TEST frame
|
||
//
|
||
|
||
typedef struct {
|
||
UCHAR Padding[4];
|
||
PMDL pMdl; // we keep test MDL in the same slot as U-MDL
|
||
} LLC_TEST_INFORMATION, *PLLC_TEST_INFORMATION;
|
||
|
||
typedef union {
|
||
LLC_XID_INFORMATION Xid; // XID information.
|
||
LLC_FRMR_INFORMATION Frmr; // FRMR information.
|
||
LLC_TEST_INFORMATION Test; // Test MDL pointer
|
||
UCHAR Padding[8]; //
|
||
} LLC_RESPONSE_INFO, *PLLC_RESPONSE_INFO;
|
||
|
||
//
|
||
// LLC_U_HEADER - Unnumbered format frame LLC header
|
||
//
|
||
|
||
typedef struct {
|
||
UCHAR Dsap; // Destination Service Access Point.
|
||
UCHAR Ssap; // Source Service Access Point.
|
||
UCHAR Command; // command code.
|
||
} LLC_U_HEADER, *PLLC_U_HEADER;
|
||
|
||
//
|
||
// LLC_S_HEADER - Supervisory format frame LLC header
|
||
//
|
||
|
||
typedef struct {
|
||
UCHAR Dsap; // Destination Service Access Point.
|
||
UCHAR Ssap; // Source Service Access Point.
|
||
UCHAR Command; // RR, RNR, REJ command code.
|
||
UCHAR Nr; // receive seq #, bottom bit is poll/final.
|
||
} LLC_S_HEADER, *PLLC_S_HEADER;
|
||
|
||
//
|
||
// LLC_I_HEADER - Information frame LLC header
|
||
//
|
||
|
||
typedef struct {
|
||
UCHAR Dsap; // Destination Service Access Point.
|
||
UCHAR Ssap; // Source Service Access Point.
|
||
UCHAR Ns; // send sequence number, bottom bit 0.
|
||
UCHAR Nr; // rcv sequence number, bottom bit p/f.
|
||
} LLC_I_HEADER, *PLLC_I_HEADER;
|
||
|
||
typedef struct {
|
||
LLC_U_HEADER U; // normal U- frame
|
||
UCHAR Type; // its lan header conversion type
|
||
} LLC_U_PACKET_HEADER, *PLLC_U_PACKET_HEADER;
|
||
|
||
typedef union {
|
||
LLC_S_HEADER S;
|
||
LLC_I_HEADER I;
|
||
LLC_U_HEADER U;
|
||
ULONG ulRawLLc;
|
||
UCHAR auchRawBytes[4];
|
||
USHORT EthernetType;
|
||
} LLC_HEADER, *PLLC_HEADER;
|
||
|
||
typedef struct _LLC_PACKET {
|
||
|
||
struct _LLC_PACKET* pNext;
|
||
struct _LLC_PACKET* pPrev;
|
||
UCHAR CompletionType;
|
||
UCHAR cbLlcHeader;
|
||
USHORT InformationLength;
|
||
PBINDING_CONTEXT pBinding;
|
||
|
||
union {
|
||
|
||
struct {
|
||
PUCHAR pLanHeader;
|
||
LLC_HEADER LlcHeader;
|
||
PLLC_OBJECT pLlcObject;
|
||
PMDL pMdl;
|
||
} Xmit;
|
||
|
||
struct {
|
||
PUCHAR pLanHeader;
|
||
UCHAR TranslationType;
|
||
UCHAR Dsap;
|
||
UCHAR Ssap;
|
||
UCHAR Command;
|
||
PLLC_OBJECT pLlcObject;
|
||
PMDL pMdl;
|
||
} XmitU;
|
||
|
||
struct {
|
||
PUCHAR pLanHeader;
|
||
UCHAR TranslationType;
|
||
UCHAR EthernetTypeHighByte;
|
||
UCHAR EthernetTypeLowByte;
|
||
UCHAR Padding;
|
||
PLLC_OBJECT pLlcObject;
|
||
PMDL pMdl;
|
||
} XmitDix;
|
||
|
||
struct {
|
||
PUCHAR pLanHeader;
|
||
UCHAR TranslationType;
|
||
UCHAR Dsap;
|
||
UCHAR Ssap;
|
||
UCHAR Command;
|
||
LLC_RESPONSE_INFO Info;
|
||
} Response;
|
||
|
||
//
|
||
// Link station data packet may be acknowledged by the other
|
||
// side, before it is completed by NDIS. Ndis completion
|
||
// routine expects to find pLlcObject link => we must not change
|
||
// that field, when the xmit packet is translated to
|
||
// a completion packet. Otherwise is corrupt pFileContext pointer,
|
||
// when NdisSendCount is incremented.
|
||
//
|
||
|
||
struct {
|
||
ULONG Status;
|
||
ULONG CompletedCommand;
|
||
PLLC_OBJECT pLlcObject;
|
||
PVOID hClientHandle;
|
||
} Completion;
|
||
|
||
} Data;
|
||
|
||
} LLC_PACKET, *PLLC_PACKET;
|
||
|
||
//
|
||
// DLC API return codes
|
||
//
|
||
// The base value of the error codes is not compatible with the other
|
||
// nt error codes, but it doesn't matter because these are internal
|
||
// for DLC driver (and its data link layer).
|
||
// 16 bit- error codes are used, because in MIPS they need less
|
||
// instructions (MIPS cannot load directly over 16 bits constants)
|
||
// and this code can also be emuulated on OS/2.
|
||
//
|
||
|
||
typedef enum _DLC_STATUS {
|
||
DLC_STATUS_SUCCESS = 0,
|
||
DLC_STATUS_ERROR_BASE = 0x6000,
|
||
DLC_STATUS_INVALID_COMMAND = 0x01 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_DUPLICATE_COMMAND = 0x02 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_ADAPTER_OPEN = 0x03 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_ADAPTER_CLOSED = 0x04 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_PARAMETER_MISSING = 0x05 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_OPTION = 0x06 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_COMMAND_CANCELLED_FAILURE = 0x07 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_CANCELLED_BY_USER = 0x0A + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_SUCCESS_NOT_OPEN = 0x0C + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_TIMER_ERROR = 0x11 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_NO_MEMORY = 0x12 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_LOST_LOG_DATA = 0x15 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_BUFFER_SIZE_EXCEEDED = 0x16 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_BUFFER_LENGTH = 0x18 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INADEQUATE_BUFFERS = 0x19 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_USER_LENGTH_TOO_LARGE = 0x1A + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_CCB_POINTER = 0x1B + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_POINTER = 0x1C + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_ADAPTER = 0x1D + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_FUNCTIONAL_ADDRESS = 0x1E + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_LOST_DATA_NO_BUFFERS = 0x20 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_TRANSMIT_ERROR_FS = 0x22 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_TRANSMIT_ERROR = 0x23 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_UNAUTHORIZED_MAC = 0x24 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_LINK_NOT_TRANSMITTING = 0x27 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_FRAME_LENGTH = 0x28 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_NODE_ADDRESS = 0x32 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_RECEIVE_BUFFER_LENGTH = 0x33 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_TRANSMIT_BUFFER_LENGTH = 0x34 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_STATION_ID = 0x40 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_LINK_PROTOCOL_ERROR = 0x41 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_PARMETERS_EXCEEDED_MAX = 0x42 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_SAP_VALUE = 0x43 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_ROUTING_INFO = 0x44 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_LINK_STATIONS_OPEN = 0x47 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INCOMPATIBLE_COMMAND_IN_PROGRESS = 0x4A + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_CONNECT_FAILED = 0x4D + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_REMOTE_ADDRESS = 0x4F + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_CCB_POINTER_FIELD = 0x50 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INADEQUATE_LINKS = 0x57 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_PARAMETER_1 = 0x58 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_DIRECT_STATIONS_NOT_AVAILABLE = 0x5C + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_DEVICE_DRIVER_NOT_INSTALLED = 0x5d + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_ADAPTER_NOT_INSTALLED = 0x5e + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_CHAINED_DIFFERENT_ADAPTERS = 0x5f + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INIT_COMMAND_STARTED = 0x60 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_CANCELLED_BY_SYSTEM_ACTION = 0x62 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_MEMORY_LOCK_FAILED = 0x69 + DLC_STATUS_ERROR_BASE,
|
||
|
||
//
|
||
// New Nt DLC specific error codes begin from 0x80
|
||
// These error codes are for new Windows/Nt DLC apps.
|
||
// This far we have tried too much use the OS/2 error codes,
|
||
// that results often uninformative return codes.
|
||
//
|
||
|
||
DLC_STATUS_INVALID_BUFFER_ADDRESS = 0x80 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_BUFFER_ALREADY_RELEASED = 0x81 + DLC_STATUS_ERROR_BASE,
|
||
|
||
|
||
DLC_STATUS_INVALID_VERSION = 0xA1 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INVALID_BUFFER_HANDLE = 0xA2 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_NT_ERROR_STATUS = 0xA3 + DLC_STATUS_ERROR_BASE,
|
||
|
||
//
|
||
// These error codes are just internal for LLC- kernel level interface
|
||
// and they are not returned to application level.
|
||
//
|
||
|
||
DLC_STATUS_UNKNOWN_MEDIUM = 0xC0 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_DISCARD_INFO_FIELD = 0xC1 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_NO_ACTION = 0xC2 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_ACCESS_DENIED = 0xC3 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_IGNORE_FRAME = 0xC4 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_WAIT_TIMEOUT = 0xC5 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_NO_RECEIVE_COMMAND = 0xC6 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_FILE_CONTEXT_DELETED = 0xC7 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_EXPAND_BUFFER_POOL = 0xC8 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_INTERNAL_ERROR = 0xC9 + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_ASYNC_DATA_TRANSFER_FAILED = 0xCA + DLC_STATUS_ERROR_BASE,
|
||
DLC_STATUS_OUT_OF_RCV_BUFFERS = 0xCB + DLC_STATUS_ERROR_BASE,
|
||
|
||
DLC_STATUS_PENDING = 0xFF + DLC_STATUS_ERROR_BASE,
|
||
|
||
DLC_STATUS_MAX_ERROR = 0xFF + DLC_STATUS_ERROR_BASE
|
||
} DLC_STATUS;
|
||
|
||
//
|
||
// Data link indication handler prototypes.
|
||
// The protocols registering to data link driver
|
||
// must provide these entry points.
|
||
//
|
||
|
||
typedef
|
||
DLC_STATUS
|
||
(*PFLLC_RECEIVE_INDICATION)(
|
||
IN PVOID hClientContext,
|
||
IN PVOID hClientHandle,
|
||
IN NDIS_HANDLE MacReceiveContext,
|
||
IN USHORT FrameType,
|
||
IN PVOID pLookBuf,
|
||
IN UINT cbLookBuf
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PFLLC_COMMAND_COMPLETE)(
|
||
IN PVOID hClientContext,
|
||
IN PVOID hClientHandle,
|
||
IN PVOID hPacket
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PFLLC_EVENT_INDICATION)(
|
||
IN PVOID hClientContext,
|
||
IN PVOID hClientHandle,
|
||
IN UINT uiEvent,
|
||
IN PVOID pDlcStatus,
|
||
IN ULONG SecondaryInformation
|
||
);
|
||
|
||
UINT
|
||
LlcBuildAddressFromLanHeader(
|
||
IN NDIS_MEDIUM NdisMedium,
|
||
IN PUCHAR pRcvFrameHeader,
|
||
IN OUT PUCHAR pLanHeader
|
||
);
|
||
|
||
DLC_STATUS
|
||
LlcInitialize(
|
||
VOID
|
||
);
|
||
|
||
UINT
|
||
LlcBuildAddress(
|
||
IN NDIS_MEDIUM NdisMedium,
|
||
IN PUCHAR DestinationAddress,
|
||
IN PVOID pSrcRouting,
|
||
IN OUT PUCHAR pLanHeader
|
||
);
|
||
|
||
USHORT
|
||
LlcGetMaxInfoField(
|
||
IN NDIS_MEDIUM NdisMedium,
|
||
IN PVOID hBinding,
|
||
IN PUCHAR pLanHeader
|
||
);
|
||
|
||
DLC_STATUS
|
||
LlcQueryInformation(
|
||
IN PVOID hObject,
|
||
IN UINT InformationType,
|
||
IN PLLC_QUERY_INFO_BUFFER pQuery,
|
||
IN UINT QueryBufferSize
|
||
);
|
||
|
||
DLC_STATUS
|
||
LlcSetInformation(
|
||
IN PVOID hObject,
|
||
IN UINT InformationType,
|
||
IN PLLC_SET_INFO_BUFFER pSetInfo,
|
||
IN UINT ParameterBufferSize
|
||
);
|
||
|
||
DLC_STATUS
|
||
LlcNdisRequest(
|
||
IN PVOID hBindingContext,
|
||
IN PLLC_NDIS_REQUEST pDlcParms
|
||
);
|
||
|
||
DLC_STATUS
|
||
LlcOpenAdapter(
|
||
IN PWSTR pAdapterName,
|
||
IN PVOID hClientContext,
|
||
IN PFLLC_COMMAND_COMPLETE pfCommandComplete,
|
||
IN PFLLC_RECEIVE_INDICATION pfReceiveIndication,
|
||
IN PFLLC_EVENT_INDICATION pfEventIndication,
|
||
IN NDIS_MEDIUM NdisMedium,
|
||
IN LLC_ETHERNET_TYPE EthernetType,
|
||
IN UCHAR AdapterNumber,
|
||
OUT PVOID *phBindingContext,
|
||
OUT PUINT puiOpenStatus,
|
||
OUT PUSHORT puiMaxFrameLength,
|
||
OUT PNDIS_MEDIUM pActualNdisMedium
|
||
);
|
||
|
||
|
||
#define LlcOpenSap(Context, Handle, Sap, Options, phSap) \
|
||
LlcOpenStation(Context, Handle, (USHORT)(Sap), LLC_SAP_OBJECT, (USHORT)(Options), phSap)
|
||
|
||
#define LlcOpenDirectStation(Context, Handle, Sap, phSap) \
|
||
LlcOpenStation(Context, Handle, (USHORT)(Sap), LLC_DIRECT_OBJECT, 0, phSap)
|
||
|
||
#define LlcOpenDixStation(Context, Handle, Sap, phSap) \
|
||
LlcOpenStation(Context, Handle, (USHORT)(Sap), LLC_DIX_OBJECT, 0, phSap)
|
||
|
||
|
||
VOID
|
||
RemoveFromLinkList(
|
||
OUT PVOID* ppBase,
|
||
IN PVOID pElement
|
||
);
|
||
|
||
VOID
|
||
LlcSleep(
|
||
IN LONG lMicroSeconds
|
||
);
|
||
|
||
VOID
|
||
LlcTerminate(
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
LlcDereferenceObject(
|
||
IN PVOID pStation
|
||
);
|
||
|
||
VOID
|
||
LlcReferenceObject(
|
||
IN PVOID pStation
|
||
);
|
||
|
||
DLC_STATUS
|
||
LlcTraceInitialize(
|
||
IN PVOID UserTraceBuffer,
|
||
IN ULONG UserTraceBufferSize,
|
||
IN ULONG TraceFlags
|
||
);
|
||
|
||
VOID
|
||
LlcTraceClose(
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
LlcTraceWrite(
|
||
IN UINT Event,
|
||
IN UCHAR AdapterNumber,
|
||
IN UINT DataBufferSize,
|
||
IN PVOID DataBuffer
|
||
);
|
||
|
||
VOID
|
||
LlcTraceDump(
|
||
IN UINT LastEvents,
|
||
IN UINT AdapterNumber,
|
||
IN PUCHAR pRemoteNode
|
||
);
|
||
|
||
VOID
|
||
LlcTraceDumpAndReset(
|
||
IN UINT LastEvents,
|
||
IN UINT AdapterNumber,
|
||
IN PUCHAR pRemoteNode
|
||
);
|
||
|
||
#if DBG
|
||
|
||
typedef struct {
|
||
USHORT Input;
|
||
USHORT Time;
|
||
PVOID pLink;
|
||
} LLC_SM_TRACE;
|
||
|
||
#define LLC_INPUT_TABLE_SIZE 500
|
||
|
||
extern ULONG AllocatedNonPagedPool;
|
||
extern ULONG LockedPageCount;
|
||
extern ULONG AllocatedMdlCount;
|
||
extern ULONG AllocatedPackets;
|
||
extern NDIS_SPIN_LOCK MemCheckLock;
|
||
extern ULONG cExAllocatePoolFailed;
|
||
extern ULONG FailedMemoryLockings;
|
||
|
||
VOID PrintMemStatus(VOID);
|
||
|
||
extern ULONG cFramesReceived;
|
||
extern ULONG cFramesIndicated;
|
||
extern ULONG cFramesReleased;
|
||
|
||
extern ULONG cLockedXmitBuffers;
|
||
extern ULONG cUnlockedXmitBuffers;
|
||
|
||
extern LLC_SM_TRACE aLast[];
|
||
extern UINT InputIndex;
|
||
|
||
#endif
|
||
|
||
//
|
||
// The inline memcpy and memset functions are faster,
|
||
// in x386 than RtlMoveMemory
|
||
//
|
||
|
||
#if defined(i386)
|
||
|
||
#define LlcMemCpy(Dest, Src, Len) memcpy(Dest, Src, Len)
|
||
#define LlcZeroMem(Ptr, Len) memset(Ptr, 0, Len)
|
||
|
||
#else
|
||
|
||
#define LlcMemCpy(Dest, Src, Len) RtlMoveMemory(Dest, Src, Len)
|
||
#define LlcZeroMem(Ptr, Len) RtlZeroMemory(Ptr, Len)
|
||
|
||
#endif
|
||
|
||
//
|
||
//
|
||
// PVOID
|
||
// PopEntryList(
|
||
// IN PQUEUE_PACKET ListHead,
|
||
// );
|
||
//
|
||
|
||
#define PopFromList(ListHead) \
|
||
(PVOID)(ListHead); \
|
||
(ListHead) = (PVOID)(ListHead)->pNext;
|
||
|
||
|
||
//
|
||
// VOID
|
||
// PushToList(
|
||
// IN PQUEUE_PACKET ListHead,
|
||
// IN PQUEUE_PACKET Entry
|
||
// );
|
||
//
|
||
|
||
#define PushToList(ListHead,Entry) { \
|
||
(Entry)->pNext = (PVOID)(ListHead); \
|
||
(ListHead) = (Entry); \
|
||
}
|
||
|
||
//
|
||
// About 30% of all bugs are related with the invalid operations with
|
||
// packets. A packet may be inserted to another list before it
|
||
// has been removed from the previous one, etc.
|
||
// The debug version of the list macroes reset the next pointer
|
||
// every time it is removed from the list and check it when it is
|
||
// inserted to a new list or released to a packet pool. The packet
|
||
// alloc will reset the next pointer automatically.
|
||
// Problem: the packets are used for many other purposes as well =>
|
||
// we must do quite a lot conditional code.
|
||
//
|
||
|
||
#if LLC_DBG
|
||
|
||
#if LLC_DBG_MP
|
||
|
||
#define DBG_INTERLOCKED_INCREMENT(Count) \
|
||
InterlockedIncrement( \
|
||
(PLONG)&(Count) \
|
||
)
|
||
|
||
#define DBG_INTERLOCKED_DECREMENT(Count) \
|
||
InterlockedDecrement( \
|
||
(PLONG)&(Count) \
|
||
)
|
||
|
||
#define DBG_INTERLOCKED_ADD(Added, Value) \
|
||
ExInterlockedAddUlong( \
|
||
(PULONG)&(Added), \
|
||
(ULONG)(Value), \
|
||
&MemCheckLock.SpinLock \
|
||
)
|
||
#else
|
||
|
||
#define DBG_INTERLOCKED_INCREMENT(Count) (Count)++
|
||
#define DBG_INTERLOCKED_DECREMENT(Count) (Count)--
|
||
#define DBG_INTERLOCKED_ADD(Added, Value) (Added) += (Value)
|
||
|
||
#endif // LLC_DBG_MP
|
||
|
||
#else
|
||
|
||
#define DBG_INTERLOCKED_INCREMENT(Count)
|
||
#define DBG_INTERLOCKED_DECREMENT(Count)
|
||
#define DBG_INTERLOCKED_ADD(Added, Value)
|
||
|
||
#endif // LLC_DBG
|
||
|
||
|
||
#if LLC_DBG
|
||
|
||
VOID LlcBreakListCorrupt( VOID );
|
||
|
||
#define LlcRemoveHeadList(ListHead) \
|
||
(PVOID)(ListHead)->Flink; \
|
||
{ \
|
||
PLIST_ENTRY FirstEntry; \
|
||
FirstEntry = (ListHead)->Flink; \
|
||
FirstEntry->Flink->Blink = (ListHead); \
|
||
(ListHead)->Flink = FirstEntry->Flink; \
|
||
FirstEntry->Flink = NULL; \
|
||
}
|
||
|
||
#define LlcRemoveTailList(ListHead) \
|
||
(ListHead)->Blink; \
|
||
{ \
|
||
PLIST_ENTRY FirstEntry; \
|
||
FirstEntry = (ListHead)->Blink; \
|
||
FirstEntry->Blink->Flink = (ListHead); \
|
||
(ListHead)->Blink = FirstEntry->Blink; \
|
||
FirstEntry->Flink = NULL; \
|
||
}
|
||
|
||
#define LlcRemoveEntryList(Entry) \
|
||
{ \
|
||
RemoveEntryList((PLIST_ENTRY)Entry); \
|
||
((PLIST_ENTRY)(Entry))->Flink = NULL; \
|
||
}
|
||
|
||
#define LlcInsertTailList(ListHead,Entry) \
|
||
if (((PLIST_ENTRY)(Entry))->Flink != NULL){ \
|
||
LlcBreakListCorrupt(); \
|
||
} \
|
||
InsertTailList(ListHead, (PLIST_ENTRY)Entry)
|
||
|
||
#define LlcInsertHeadList(ListHead,Entry) \
|
||
if (((PLIST_ENTRY)(Entry))->Flink != NULL) { \
|
||
LlcBreakListCorrupt(); \
|
||
} \
|
||
InsertHeadList(ListHead,(PLIST_ENTRY)Entry)
|
||
|
||
/*
|
||
#define DeallocatePacket( PoolHandle, pBlock ) { \
|
||
if (((PLIST_ENTRY)pBlock)->Flink != NULL) { \
|
||
LlcBreakListCorrupt(); \
|
||
} \
|
||
DBG_INTERLOCKED_DECREMENT( AllocatedPackets ); \
|
||
ExFreeToZone( \
|
||
&(((PEXTENDED_ZONE_HEADER)PoolHandle)->Zone), \
|
||
pBlock); \
|
||
}
|
||
*/
|
||
|
||
#else
|
||
|
||
|
||
//
|
||
// PVOID
|
||
// LlcRemoveHeadList(
|
||
// IN PLIST_ENTRY ListHead
|
||
// );
|
||
//
|
||
|
||
#define LlcRemoveHeadList(ListHead) (PVOID)RemoveHeadList(ListHead)
|
||
|
||
|
||
//
|
||
// PLIST_ENTRY
|
||
// LlcRemoveTailList(
|
||
// IN PLIST_ENTRY ListHead
|
||
// );
|
||
//
|
||
|
||
#define LlcRemoveTailList(ListHead) \
|
||
(ListHead)->Blink; { \
|
||
PLIST_ENTRY FirstEntry; \
|
||
FirstEntry = (ListHead)->Blink; \
|
||
FirstEntry->Blink->Flink = (ListHead); \
|
||
(ListHead)->Blink = FirstEntry->Blink; \
|
||
}
|
||
|
||
|
||
//
|
||
// VOID
|
||
// LlcRemoveEntryList(
|
||
// IN PVOID Entry
|
||
// );
|
||
//
|
||
|
||
#define LlcRemoveEntryList(Entry) RemoveEntryList((PLIST_ENTRY)Entry)
|
||
|
||
|
||
//
|
||
// VOID
|
||
// LlcInsertTailList(
|
||
// IN PLIST_ENTRY ListHead,
|
||
// IN PVOID Entry
|
||
// );
|
||
//
|
||
|
||
#define LlcInsertTailList(ListHead,Entry) \
|
||
InsertTailList(ListHead, (PLIST_ENTRY)Entry)
|
||
|
||
//
|
||
// VOID
|
||
// LlcInsertHeadList(
|
||
// IN PLIST_ENTRY ListHead,
|
||
// IN PVOID Entry
|
||
// );
|
||
//
|
||
|
||
#define LlcInsertHeadList(ListHead,Entry) \
|
||
InsertHeadList(ListHead,(PLIST_ENTRY)Entry)
|
||
|
||
//
|
||
// VOID
|
||
// DeallocatePacket(
|
||
// PEXTENDED_ZONE_HEADER PoolHandle,
|
||
// PVOID pBlock
|
||
// );
|
||
//
|
||
|
||
/*
|
||
#define DeallocatePacket( PoolHandle, pBlock ) { \
|
||
ExFreeToZone( &(((PEXTENDED_ZONE_HEADER)PoolHandle)->Zone), \
|
||
pBlock); \
|
||
}
|
||
*/
|
||
|
||
#endif // DBG
|
||
|
||
#if LLC_DBG == 2
|
||
|
||
VOID LlcMemCheck(VOID);
|
||
|
||
#define MEM_CHECK() LlcMemCheck()
|
||
|
||
#else
|
||
|
||
#define MEM_CHECK()
|
||
|
||
#endif
|
||
|
||
|
||
VOID LlcInvalidObjectType(VOID);
|
||
|
||
/*++
|
||
|
||
Trace codes
|
||
|
||
Big letters are reserved for actions, small letters are used to identify
|
||
objects and packet types. The trace macroes simply writes to DLC
|
||
trace tree (remember: we have another trace for the state machine!!!)
|
||
|
||
'a' = dix stations
|
||
'b' = direct station
|
||
'c' = link station
|
||
'd' = sap station
|
||
|
||
'e' = Connect command
|
||
'f' = Close command
|
||
'g' = Disconnect command
|
||
'h' = Receive command
|
||
'i' = transmit command
|
||
|
||
'j' = Type1 packet
|
||
'k' = type 2 packet
|
||
'l' = data link packet
|
||
|
||
'A' = CompleteSendAndLock
|
||
'B' = LlcCommandCompletion
|
||
'C' = LlcCloseStation
|
||
'D' = LlcReceiveIndication
|
||
'E' = LlcEventIndication
|
||
'F' = DlcDeviceIoControl
|
||
'G' = DlcDeviceIoControl sync exit
|
||
'H' = DlcDeviceIoControl async exit
|
||
'I' = LlcSendI
|
||
'J' = DirCloseAdapter
|
||
'K' = CompleteDirCloseAdapter
|
||
'L' = LlcDereferenceObject
|
||
'M' = LlcReferenceObject
|
||
'N' = CompleteCloseStation (final)
|
||
'O' = DereferenceLlcObject (in dlc)
|
||
'P' = CompleteLlcObjectClose (final)
|
||
'Q' = DlcReadCancel
|
||
'R' =
|
||
'S' =
|
||
'T' = DlcTransmit
|
||
'U' = LlcSendU
|
||
'V' =
|
||
'W' =
|
||
'X' =
|
||
'Y' =
|
||
'Z' =
|
||
|
||
--*/
|
||
|
||
#if DBG & DLC_TRACE_ENABLED
|
||
|
||
#define LLC_TRACE_TABLE_SIZE 0x400 // this must be exponent of 2!
|
||
|
||
extern UINT LlcTraceIndex;
|
||
extern UCHAR LlcTraceTable[];
|
||
|
||
#define DLC_TRACE(a) {\
|
||
LlcTraceTable[LlcTraceIndex] = (a);\
|
||
LlcTraceIndex = (LlcTraceIndex + 1) & (LLC_TRACE_TABLE_SIZE - 1);\
|
||
}
|
||
|
||
#else
|
||
|
||
#define DLC_TRACE(a)
|
||
|
||
#endif // LLC_DBG
|
||
|
||
//
|
||
// the following functions can be macros if DLC and LLC live in the same driver
|
||
// and each knows about the other's structures
|
||
//
|
||
|
||
#if DLC_AND_LLC
|
||
|
||
//
|
||
// UINT
|
||
// LlcGetReceivedLanHeaderLength(
|
||
// IN PVOID pBinding
|
||
// );
|
||
//
|
||
|
||
#if 0
|
||
|
||
//
|
||
// this gives the wrong length for DIX lan header
|
||
//
|
||
|
||
#define LlcGetReceivedLanHeaderLength(pBinding) \
|
||
((((PBINDING_CONTEXT)(pBinding))->pAdapterContext->NdisMedium == NdisMedium802_3) \
|
||
? (((PBINDING_CONTEXT)(pBinding))->pAdapterContext->FrameType == LLC_DIRECT_ETHERNET_TYPE) \
|
||
? 12 \
|
||
: 14 \
|
||
: (((PBINDING_CONTEXT)(pBinding))->pAdapterContext->NdisMedium == NdisMediumFddi) \
|
||
? 14 \
|
||
: ((PBINDING_CONTEXT)(pBinding))->pAdapterContext->RcvLanHeaderLength)
|
||
|
||
#else
|
||
|
||
//
|
||
// this always returns 14 as the DIX lan header length
|
||
//
|
||
|
||
#define LlcGetReceivedLanHeaderLength(pBinding) \
|
||
((((PBINDING_CONTEXT)(pBinding))->pAdapterContext->NdisMedium == NdisMedium802_3) \
|
||
? 14 \
|
||
: (((PBINDING_CONTEXT)(pBinding))->pAdapterContext->NdisMedium == NdisMediumFddi) \
|
||
? 14 \
|
||
: ((PBINDING_CONTEXT)(pBinding))->pAdapterContext->RcvLanHeaderLength)
|
||
|
||
#endif
|
||
|
||
//
|
||
// USHORT
|
||
// LlcGetEthernetType(
|
||
// IN PVOID hContext
|
||
// );
|
||
//
|
||
|
||
#define LlcGetEthernetType(hContext) \
|
||
(((PBINDING_CONTEXT)(hContext))->pAdapterContext->EthernetType)
|
||
|
||
//
|
||
// UINT
|
||
// LlcGetCommittedSpace(
|
||
// IN PVOID hLink
|
||
// );
|
||
//
|
||
|
||
#define LlcGetCommittedSpace(hLink) \
|
||
(((PDATA_LINK)(hLink))->BufferCommitment)
|
||
|
||
#else
|
||
|
||
//
|
||
// separation of church and state, or DLC and LLC even
|
||
//
|
||
|
||
UINT
|
||
LlcGetReceivedLanHeaderLength(
|
||
IN PVOID pBinding
|
||
);
|
||
|
||
USHORT
|
||
LlcGetEthernetType(
|
||
IN PVOID hContext
|
||
);
|
||
|
||
UINT
|
||
LlcGetCommittedSpace(
|
||
IN PVOID hLink
|
||
);
|
||
|
||
#endif // DLC_AND_LLC
|
||
|
||
#endif // _LLC_API_
|
||
|