/*++

*******************************************************************************
* Copyright (c) 1994-95 Digi International Inc., All Rights Reserved          *
*                                                                             *
* This  software  contains  proprietary  and  confidential   information   of *
* Digi International  Inc.   By  accepting  transfer  of this copy, Recipient *
* agrees to retain this software in  confidence,  to  prevent  disclosure  to *
* others,  and  to make no  use of this software other than that for which it *
* was delivered.  This is an unpublished copyright work  Digi   International *
* Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is *
* strictly prohibited.                                                        *
*                                                                             *
* Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc. *
* Confidential  when   combined   with   the   aggregated  modules  for  this *
* product) OBJECT CODE ONLY SOURCE MATERIALS                                  *
*                                                                             *
* (C) COPYRIGHT Digi International Inc. 1994-95                               *
*                                                                             *
* All Rights Reserved                                                         *
*                                                                             *
* US   Government   Users   Restricted   Rights   -   Use,   duplication   or *
* disclosure  restricted by GSA ADP Schedule Contract with Digi International *
* Inc.                                                                        *
*                                                                             *
*******************************************************************************

Module Name:

   digilan.h

Abstract:

   This module defines the structures and macros specific to the Digi Frame Relay 
   driver.

Author:

   Michael Zarns

--*/

#ifndef DIGILAN
#define DIGILAN

// System 
#define UNICODE
// Changed to NDIS V4.0 from V3.0 (default), required for WHQL testing

// SDB changed to NDIS 5.0 for WHQL testing
//#define NDIS40_MINIPORT   1
#define NDIS50_MINIPORT    1

#include <ndis.h> 

// DStreams 
#include "dxbtypes.h"

// Sync Firmware
#include "fr_cont.h"

// Digi Driver Libraries
#include "digilib.h"
#include "dsapi.h"

#include "dxbreg.h"		// Must be after the include of digilib.h, so NT5_BUILD is set.
#include "dxbbuildnumber.h"

//
// As an ndis driver, we handle three network packet types: IP, IPX, and 802.3
// (ethernet).  This enum defines IDs for each of them.
//
typedef enum
{
	PACKET_TYPE_UNKNOWN,
	PACKET_TYPE_IP,
	PACKET_TYPE_IPX,
	PACKET_TYPE_ARP,
	PACKET_TYPE_802_3,
	PACKET_TYPE_MAX
} PACKET_TYPE;


//
// This driver supports Frame Relay, X25, and may soon support PPP and
// other protocols.  This enum defines the protocol types supported.  To
// add support for a new protocol, add it's id here and add an entry for
// it in the gProtocolInitTable.
//
typedef enum
{
	PROTOCOL_FR = 0,
	PROTOCOL_X25,
	PROTOCOL_MAX
} PROTOCOL_ID;


typedef enum
{
	LINK_INACTIVE,
	LINK_ACTIVE	
} LINKSTATE;

// Definition of the init routine required for each sync protocol
typedef NDIS_STATUS
( * PROTOCOL_INIT_ROUTINE )(
	IN OUT PDIGILAN_LOGICAL_ADAPTER,
	IN NDIS_HANDLE
	);

// Send routine required for each sync protocol
typedef NDIS_STATUS
( * PROTOCOL_SEND_ROUTINE )(
	IN OUT PDIGILAN_LOGICAL_ADAPTER,
	IN NDIS_HANDLE
	);

// SendComplete routine required for each sync protocol
typedef VOID
( * PROTOCOL_SEND_COMPLETE_ROUTINE )(
	IN PDIGILAN_LOGICAL_ADAPTER,
	IN PVOID,
	IN ULONG,
	IN PNDIS_PACKET,
	IN NDIS_STATUS
	);

// Definition of the receive routine required for each protocol
typedef VOID
( * PROTOCOL_RECEIVE_ROUTINE )(
	IN PDIGI_LOGICAL_ADAPTER,
	IN PVOID,
	IN PDIGI_FRAME_BUFFER,
	IN ULONG
	);

// Table of protocol ID's and init routines.  See comments for  
// PROTOCOL_ID definition above.
extern PROTOCOL_INIT_ROUTINE gProtocolInitTable[PROTOCOL_MAX];


extern UCHAR EthernetTypeIpx[3];
extern UCHAR EthernetTypeIP[2];
extern UCHAR EthernetTypeArp[2];
extern UCHAR ArpCommandRequest[2];
extern UCHAR ArpCommandReply[2];

#define DIGIINIT               ((ULONG)0x00000001)
#define DIGITX                 ((ULONG)0x00000002)
#define DIGIRX                 ((ULONG)0x00000004)
#define DIGITXTRACE            ((ULONG)0x00000008)
#define DIGIRXTRACE            ((ULONG)0x00000010)
#define DIGISXBPUTMSG          ((ULONG)0x00000020)
#define DIGISXBGETMSG          ((ULONG)0x00000040)
#define DIGISXBIOCTL           ((ULONG)0x00000080)
#define DIGIIRP                ((ULONG)0x00000100)
#define DIGISETINFO            ((ULONG)0x00000200)
#define DIGIQUERYINFO          ((ULONG)0x00000400)
#define DIGIX25MSG             ((ULONG)0x00000800)
#define DIGITIMER              ((ULONG)0x00001000)
#define DIGITHRESHOLD          ((ULONG)0x00002000)
#define DIGIFLOW               ((ULONG)0x00004000)
#define DIGI15                 ((ULONG)0x00008000)
#define DIGI16                 ((ULONG)0x00010000)
#define DIGI17                 ((ULONG)0x00020000)
#define DIGI18                 ((ULONG)0x00040000)
#define DIGI19                 ((ULONG)0x00080000)
#define DIGI20                 ((ULONG)0x00100000)
#define DIGI21                 ((ULONG)0x00200000)
#define DIGI22                 ((ULONG)0x00400000)
#define DIGI23                 ((ULONG)0x00800000)
#define DIGI24                 ((ULONG)0x01000000)
#define DIGI25                 ((ULONG)0x02000000)
#define DIGIWARN               DEBUG_WARN
#define DIGIERRORS             DEBUG_ERROR
#define DIGIBREAK              DEBUG_BREAK


#define ENTER( RoutineName )                            \
	DigiDump( DIGIFLOW, ("Enter "RoutineName"\n") );

#define LEAVE( RoutineName, ReturnVal )                 \
{																		  \
	DigiDump( DIGIFLOW, ("Leave "RoutineName"\n" ) );	  \
	return ReturnVal;											     \
}

#define LEAVE_NOVAL( RoutineName )                      \
{																		  \
	DigiDump( DIGIFLOW, ("Leave "RoutineName"\n" ) );	  \
	return;											              \
}


//
// Ndis version info
//
// Changed from NDIS V3.0 to V4.0
//#define DIGILAN_MAJOR_VERSION   0x04
//#define DIGILAN_MINOR_VERSION   0x00

// SDB
// Changed from NDIS V4.0 to V5.0
#define DIGILAN_MAJOR_VERSION   0x05
#define DIGILAN_MINOR_VERSION   0x00


///Max Send Packets

#define DIGILAN_MAXIMUM_SEND_PACKETS 0x10

//
// Size (in bytes) of the ethernet address
//
#define DIGILAN_LENGTH_OF_ADDRESS 6

//
// Number of Multicast Addresses we'll support
//
#define DIGILAN_MAX_MULTICAST		64

//
// Max allowed number of nested calls into DigiLanGetMsg
//
#define DIGILAN_GETMSG_THRESHOLD	2

//
// enumeration of various types of objects used in this driver.
//
typedef enum DIGILAN_OBJECT_TYPE
{
	DIGI_TYPE_UNKNOWN,
	DIGI_TYPE_DRIVER_OBJECT,
	DIGI_TYPE_ADAPTER_OBJECT,
	DIGI_TYPE_QUEUE_ENTRY_OBJECT,
	DIGI_TYPE_MAX
} DIGILAN_OBJECT_TYPE;


#define ETHERNET_MAC_HEADER_SIZE   14
#define ETHERNET_MAX_FRAME_SIZE    1514
#define ETHERNET_LLC_HEADER_SIZE   3
#define ETHERNET_PAYLOAD_SIZE      \
				( ETHERNET_MAX_FRAME_SIZE - ETHERNET_MAC_HEADER_SIZE )

#define ETHERNET_MAC_ADDR_SIZE     6

#define ETHERNET_MAC_DEST_OFFSET   0
#define ETHERNET_MAC_SRC_OFFSET    ( ETHERNET_MAC_ADDR_SIZE )
#define ETHERNET_MAC_TYPE_OFFSET   ( 2 * ( ETHERNET_MAC_ADDR_SIZE ) )

#define ARP_COMMAND_REQUEST        1
#define ARP_COMMAND_REPLY          2
#define ARP_PROTOCOL_ADDR_LENGTH   4
#define ARP_HW_ADDR_LENGTH         ( ETHERNET_MAC_ADDR_SIZE )

//
// The following constants are used in the LOGICAL_ADAPTER Protocols fields to
// indicate the communications method desired for each protocol.
typedef enum
{
	PROTOCOL_SUPPORT_NONE = 0,		// Protocol not to be supported
	PROTOCOL_SUPPORT_ROUTE,			// Route this protocol
	PROTOCOL_SUPPORT_BRIDGE,		// Bridge this protocol
	PROTOCOL_SUPPORT_BRIDGE_FCS,	// Bridge this protocol w/ added FCS
	PROTOCOL_SUPPORT_CICSO_ROUTED,	// Routed Cicso IP Encapsulation
	PROTOCOL_SUPPORT_MAX			// Used only for range checking
} PROTOCOL_SUPPORT;

//
// This record type defines an ethernet frame for our purposes.  We only care
// about two pieces of the frame: the ethernet header and the payload (which 
// in our case would be the IP, IPX, or NETBEUI data packet).
//

typedef struct DIGILAN_ETHERNET_FRAME
{
	UCHAR Header[ETHERNET_MAC_HEADER_SIZE];
	UCHAR Payload[ETHERNET_PAYLOAD_SIZE];

} DIGILAN_ETHERNET_FRAME, *PDIGILAN_ETHERNET_FRAME;

//
// This is the data buffer allocated for GetMsg Ioctls into DigiSxb.  Since we
// support RFC1490 encapsulation of 802.3, IP, and IPX frame types simultaneously
// we don't know ahead of time which type will be stuffed into or GetMsg buffer.
// This buffer has padding at the beginning in which we can stuff MAC and LLC 
// headers if necessary.  i.e. for IP, we must stuff in a MAC header.  For
// IPX, we must stuff both MAC and LLC headers.
//

typedef struct DIGILAN_FRAME_BUFFER
{
	UCHAR Padding[ ( ETHERNET_LLC_HEADER_SIZE + ETHERNET_MAC_HEADER_SIZE ) ];
	UCHAR Data[ ETHERNET_MAX_FRAME_SIZE ];
} DIGILAN_FRAME_BUFFER, *PDIGILAN_FRAME_BUFFER;

//
// This record type is used to store FR Driver global data.  
//

typedef struct _DIGILAN_DRIVER_OBJECT
{
	//
	// Indicate type of object this is.
	//
	DIGILAN_OBJECT_TYPE  Type;

	//
	// The driver object which was passed into our DriverEntry routine.
	//
	PDRIVER_OBJECT DriverObject;

	//
	// The handle returned by NdisMInitializeWrapper.
	//

	NDIS_HANDLE WrapperHandle;

	//
	// List of adapters registerd for this Miniport driver.
	//
	NDIS_SPIN_LOCK AdapterListLock;
	LIST_ENTRY AdapterList;

	//
	//	Flag set before NdisMSendComplete indications and cleared on return.  Used
	// to protect recursive calls into DigiLanSend from NdisMSendComplete from
	//	from blowing the stack.
	//
	BOOLEAN bInSendComplete;

	//
	// Spinlock for protecting the bInSendComplete flags.
	//
	NDIS_SPIN_LOCK InSendCompleteLock;

	//
	// Keep the recursion down!  Use this count to limit the number of times
	// DigiLanSend is called from NDISMSendComplete.
	//
	ULONG nInSendComplete;

}  DIGILAN_DRIVER_OBJECT, *PDIGILAN_DRIVER_OBJECT;


//
// This structure contains information about a single logical adapter.  A logical
// adapter is what we use to represent a single Frame Relay virtual circuit (VC).
// Many VCs can share the same physical Frame Relay line (or Link).  Each VC on a
// line can be identified by it's DLCI (Data Link Connection Identifier).  DLCI's 
// are only guaranteed to be unique on a "per physical link" basis, so we need to 
// know both the device name (i.e. DigiSxb15A) and the DLCI (i.e. 53) to uniquely 
// identify a specific connection (or VC).
//
// Since each VC is represented by a single Logical Adapter, as far as NDIS is 
// concerned, each VC is a separate network adapter.
//

typedef struct _DIGILAN_LOGICAL_ADAPTER_
{

//
// The following fields are not protected by any spinlock:
//
    //
    // Indicate type of object this is.
    //
    DIGILAN_OBJECT_TYPE  Type;

    //
    // This adapter's entry in the linked list of adapters registered for this 
    // miniport.
    //
    LIST_ENTRY ListEntry;

    //
    // Adapter name (ASCII)
    //
    CHAR Name[16];

    //
    // Adapter Name (Unicode)
    //
    UNICODE_STRING UName;

    //
    // This is the handle given by the wrapper for calling ndis functions.
    //
    NDIS_HANDLE MiniportAdapterHandle;

    //
    // SXB Device Name (Unicode) - this is the name of the port exposed by SXB
    // on which we make the Virtual Connection for this adapter (i.e. DigiSxb15).
    // 
    UNICODE_STRING UDeviceName;

    //
    // The identifier of the physical line on which this PVC runs.
    // (used by X.25 and Frame Relay)
    //
    ULONG Snid;

    //
    // Handle on which we send Sxb open requests.  It is returned from the call
    // to SxbInitialize.  The fileobject and deviceobject are maintained by the 
    // SxbWrap library.
    //
    HANDLE hDevice;

    //
    // Handle returned from SxbWrap library routine SxbOpen.  Remaining SxbWrap 
    // library api's require this handle: PutMsg, GetMsg, Ioctl, and Close.
    //
    HANDLE hStream;

    // SDB: statistic stream handle
    HANDLE hWans;	

#if NT5_BUILD
    NDIS_TIMER UpdateTimer;
    NDIS_WORK_ITEM UpdateWorkItem;
    BOOLEAN HaltReceived;
    BOOLEAN WorkItemPending;
    BOOLEAN X25AttachPending;
#endif

    //
    // The broadcast ethernet address:
    //
    UCHAR BroadCastAddress[
        ((DIGILAN_LENGTH_OF_ADDRESS + (sizeof(ULONG)-1)) & ~(sizeof(ULONG)-1)) ];

    //
    // The ethernet address currently in use for this adapter:
    //
    UCHAR CurrentNetworkAddress[
        ((DIGILAN_LENGTH_OF_ADDRESS + (sizeof(ULONG)-1)) & ~(sizeof(ULONG)-1)) ];

    //
    // The ethernet address "hardcoded" by the configuration for this adapter:
    //
    UCHAR PermanentNetworkAddress[
        ((DIGILAN_LENGTH_OF_ADDRESS + (sizeof(ULONG)-1)) & ~(sizeof(ULONG)-1)) ];

    //
    // The ethernet address of the remote connection ( assigned via registry??? )
    //
    UCHAR RemoteNetworkAddress[
        ((DIGILAN_LENGTH_OF_ADDRESS + (sizeof(ULONG)-1)) & ~(sizeof(ULONG)-1)) ];

    struct 
    {
        // The protocol, PROTOCOL_X25 or PROTOCOL_FR
        PROTOCOL_ID Id;

        // Maximum length of a control header for this protocol.  Used by
        // DigiNewGetMsg to alloc the correct size buffer for GetMsg's.
        ULONG RxControlLength;

        // Protocol specific (FR, X.25) send and receive routines to do per-packet
        // processing.  They convert Ndis_packet style packets to and from FR or X.25 
        // style put/get msg requests.
        PROTOCOL_SEND_ROUTINE Send;
        PROTOCOL_SEND_COMPLETE_ROUTINE SendComplete;
        PROTOCOL_RECEIVE_ROUTINE Receive;

        // Pointer to struct containing protocol specific info.  Struct should be
        // defined by the protocol module.
        union
        {
            struct
            {

                // Flag which specifies whether the frame relay link is active or inactive
                // 0 == inactive otherwise active
                LINKSTATE LinkState;

                // Frame Relay identifier for the PVC for this logical adapter.
                ULONG Dlci;

                // Handle returned from the hardware on the ENCAP_OpenPLL ioctl.  
                // Identifies a single FR virtual circuit (also called VC, PVC or 
                // PLL, they're all synonymous).
                ULONG PllHandle;

                // Flags whether we've been able to sniff the remote's MAC addr from
                // inside an IPX packet.  Only used in IPX Routed.
                BOOLEAN bSniffedRemoteNetworkAddress;
            } FR;

            struct 
            {
                // X.25 Logical channel number for this PVC
                ULONG Channel;

                // Local packet size
                ULONG LocalPacket;

                // Remote packet size
                ULONG RemotePacket;

                // Local window size
                ULONG LocalWindow;

                // Local window size
                ULONG RemoteWindow;

                // PVC state machine 
                ULONG State;
                KSPIN_LOCK StateLock;

                // Used to send PVC_ATTACH message down to firmware
                KDPC AttachDpc;
                KTIMER AttachTimer;

                // Rx packets may be received in chunks with the More bit set.  
                // Accumulate chunks until we can indicate a full packet up to Ndis.
                PDIGILAN_FRAME_BUFFER pMoreBuffer;

                // Located inside pMoreBuffer, start of ethernet frame to indicate up.
                PDIGILAN_ETHERNET_FRAME pMoreFrame;

                // Current offset into pMoreFrame to append next packet
                ULONG MoreOffset;
                KSPIN_LOCK MoreLock;
            } X25;

        } Private;

    } SyncProtocol;

    //
    // Protocol support
    //

    struct
    {
        PROTOCOL_SUPPORT Ip;
        PROTOCOL_SUPPORT Ipx;
        PROTOCOL_SUPPORT Ethernet;
    } LanProtocol;
	
    //
    // Spinlock for protecting the AdapterContextQueue.
    //
    NDIS_SPIN_LOCK AdapterContextLock;

    //
    // Spinlock for Protecting LOGICAL_ADAPTER fields
    //

    NDIS_SPIN_LOCK Lock;

//
// The following fields must be protected by the AdapterContextLock spinlock:
//

    //
    // Queue for indicating status and data back to the NDIS Miniport Wrapper.
    //
    LIST_ENTRY AdapterContextQueue;

    //
    // Timer for processing items on the AdapterContextQueue
    //
    NDIS_MINIPORT_TIMER AdapterContextTimer;

//
// The following fields must be protected by the Lock spinlock:
//

    // 
    // Flag used by GetMsg and GetMsgComplete routines to prevent recursion.
    //
    BOOLEAN InGetMsg;

    //
    // When DigiLanGetMsg fails due to resources limitations, we reschedule it 
    // using this timer.
    //
    KTIMER GetMsgTimer;
    KDPC   GetMsgDpc;

    //
    // Ndis packet filter for this adapter.  Set by DigiLanSetInformation, this
    // field determines which types of packets (i.e. NDIS_PACKET_TYPE_PROMISCUOUS)
    // will be forwarded up to Ndis on receive.
    //
    ULONG PacketFilter;

    //
    // Multicast info
    //
    struct 
    {
        //
        // Pointer to list of multicast addresses which we'll pass up to Ndis
        //
        PUCHAR AddressList;

        //
        // Count of multicast address entries
        //
        ULONG Count;

    } Multicast;

    //
    // Statistic information
    //
    ULONG SendPacketsScheduled; // SDB: for debug purposes
    ULONG PacketsSent;
    ULONG PacketsReceived;
    ULONG SendPacketsDropped;
    ULONG RecvPacketsDropped;
    ULONG Speed;

    BOOLEAN	bSpoof;

}  DIGILAN_LOGICAL_ADAPTER, *PDIGILAN_LOGICAL_ADAPTER;


//
// The following structures define the adapterContext Queue entries.
//

typedef struct QUEUE_ENTRY_SEND_COMPLETE
{
	PDIGILAN_LOGICAL_ADAPTER Adapter;
	PNDIS_PACKET Packet;
	NDIS_STATUS CompletionStatus;
} QUEUE_ENTRY_SEND_COMPLETE, *PQUEUE_ENTRY_SEND_COMPLETE;


typedef struct QUEUE_ENTRY_INDICATE_RECV
{
	PDIGILAN_LOGICAL_ADAPTER Adapter;
	PDIGILAN_FRAME_BUFFER pBuffer;
	PDIGILAN_ETHERNET_FRAME pFrame;
	ULONG PayloadLength;
} QUEUE_ENTRY_INDICATE_RECV, *PQUEUE_ENTRY_INDICATE_RECV;

typedef struct QUEUE_ENTRY_INTERNAL_RECV
{
	PDIGILAN_LOGICAL_ADAPTER pAdapter;
	PDIGILAN_ETHERNET_FRAME pFrame;
	ULONG FrameLength;
} QUEUE_ENTRY_INTERNAL_RECV, *PQUEUE_ENTRY_INTERNAL_RECV;

typedef struct QUEUE_ENTRY_INDICATE_STATUS 
{
	PDIGILAN_LOGICAL_ADAPTER Adapter;
	NDIS_STATUS GeneralStatus;
	PVOID StatusBuffer;
	UINT	BufferLength;	
} QUEUE_ENTRY_INDICATE_STATUS, *PQUEUE_ENTRY_INDICATE_STATUS;	


typedef enum ADAPTER_CONTEXT_ENTRY_TYPE
{
	DIGI_QUEUE_ENTRY_UNKNOWN,
	DIGI_QUEUE_ENTRY_SEND_COMPLETE,
	DIGI_QUEUE_ENTRY_SEND_RESOURCES_AVAILABLE,
	DIGI_QUEUE_ENTRY_INDICATE_RECEIVE,
	DIGI_QUEUE_ENTRY_INDICATE_STATUS,	
	DIGI_QUEUE_ENTRY_INTERNAL_RECEIVE,
	DIGI_QUEUE_ENTRY_MAX
} ADAPTER_CONTEXT_ENTRY_TYPE;

//
// Adapter Context Queue entry.  This structure defines what a single entry in the 
// AdapterContextQueue must be.  See below for definitions of the union structs.
//
typedef struct ADAPTER_CONTEXT_QUEUE_ENTRY
{
	DIGILAN_OBJECT_TYPE Type;

	ADAPTER_CONTEXT_ENTRY_TYPE Request;

	LIST_ENTRY ListEntry;

	union 
	{
		QUEUE_ENTRY_SEND_COMPLETE SendComplete;
		QUEUE_ENTRY_INDICATE_RECV IndicateRecv;
		QUEUE_ENTRY_INTERNAL_RECV InternalRecv;
		QUEUE_ENTRY_INDICATE_STATUS IndicateStatus; //VK
	} Indication;

} ADAPTER_CONTEXT_QUEUE_ENTRY, *PADAPTER_CONTEXT_QUEUE_ENTRY;


///////////////////////////////////////////////////////////////////////////////
//
// Macros
//

#define IsPacketIP( pFrame )												 						\
	DigiCompareMemory( 																				\
		&( (PDIGILAN_ETHERNET_FRAME)pFrame )->Header[ ETHERNET_MAC_TYPE_OFFSET ],	\
		EthernetTypeIP,																				\
		2 )

#define IsPacketARP( pFrame )												 						\
	DigiCompareMemory(																				\
		&( (PDIGILAN_ETHERNET_FRAME)pFrame )->Header[ ETHERNET_MAC_TYPE_OFFSET ],	\
		EthernetTypeArp,																				\
		2 )

#define IsPacketIPX( pFrame )																									\
	( ( (USHORT)( ( ( (PDIGILAN_ETHERNET_FRAME)pFrame )->Header[ ETHERNET_MAC_TYPE_OFFSET ] ) << 8 |	\
	  ( ( (PDIGILAN_ETHERNET_FRAME)pFrame )->Header[ ETHERNET_MAC_TYPE_OFFSET + 1 ] ) ) <= 1500 ) &&	\
	  DigiCompareMemory( ( (PDIGILAN_ETHERNET_FRAME)pFrame )->Payload,											\
	                     EthernetTypeIpx,																					\
	                     sizeof( EthernetTypeIpx	) ) )



///////////////////////////////////////////////////////////////////////////////
//
// Function Prototypes
//

//
// acontext.c
//

VOID
DigiAdapterContextQueueInit(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN NDIS_HANDLE MiniportAdapterHandle
	);

VOID
DigiAdapterContextQueueDeInit(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter
	);

NDIS_STATUS
DigiQueueSendComplete(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN PNDIS_PACKET pPacket,
	IN NDIS_STATUS Status
	);

NDIS_STATUS
DigiQueueIndicateReceive(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN PDIGILAN_FRAME_BUFFER pBuffer,
	IN PDIGILAN_ETHERNET_FRAME pFrame,
	IN ULONG PayloadLength
	);

NDIS_STATUS							
DigiQueueIndicateStatus(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN NDIS_STATUS GeneralStatus,
	IN PVOID StatusBuffer,
	IN UINT	BufferLength	
	);

VOID
AdapterContextTimerFunction(
	IN PVOID SystemSpecific1,
	IN PVOID FunctionContext,
	IN PVOID SystemSpecific2,
	IN PVOID SystemSpecific3
	);

//
// arp.c
//

VOID
DigiLanSpoofArpReply(
	PDIGILAN_LOGICAL_ADAPTER pAdapter, 
	PNDIS_PACKET pNdisPacket
	);

//
// init.c
//

NTSTATUS
DigiLanInitialize(
	OUT PNDIS_STATUS OpenErrorStatus, 
	OUT PUINT SelectedMediumIndex, 
	IN PNDIS_MEDIUM MediumArray,
	IN UINT MediumArraySize, 
	IN NDIS_HANDLE MiniportAdapterHandle, 
	IN NDIS_HANDLE WrapperConfigurationContext
	);

NDIS_STATUS
DigiReadConfiguration(
	IN NDIS_HANDLE ConfigurationHandle,
	IN PNDIS_STRING Keyword,
	IN NDIS_PARAMETER_TYPE ParameterType,
	OUT PUNICODE_STRING pwOutString OPTIONAL,
	OUT PVOID pOut OPTIONAL
	);

//
// Irp.c
//

PIRP
DigiNewIrp(
	IN LONG IoControlCode,
	IN PDEVICE_OBJECT DeviceObject,
	IN PVOID InputBuffer OPTIONAL,
	IN ULONG InputBufferLength,
	OUT PVOID OutputBuffer OPTIONAL,
	IN ULONG OutputBufferLength,
	IN BOOLEAN InternalDeviceIoControl,
	IN PKEVENT Event,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
	IN PVOID CompletionRoutineContext OPTIONAL
	);

//
// msg.c
//

BOOLEAN
DlwBuffersAllocated(PVOID pAdapter,PVOID hStream);

NDIS_STATUS
DlwOpen(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN PCSZ pcszDeviceName );

NDIS_STATUS
DlwIoctl(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN ULONG Ioctl,
	IN PUCHAR pData,
	IN ULONG DataLength,
	OUT PULONG pReturnCode );

NTSTATUS
DlwPutMsg(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN PUCHAR pControlBuffer,
	IN ULONG ControlLength,
	IN PNDIS_PACKET pNdisPacket,
	IN ULONG DataOffset,
	IN ULONG DataLength );

NDIS_STATUS
DlwGetMsg(
	PDIGILAN_LOGICAL_ADAPTER pAdapter );

VOID 
DlwGetMsgTimeout( 
	IN PKDPC Dpc,
	IN PVOID DeferredContext,
	IN PVOID SystemContext1,
	IN PVOID SystemContext2  );

//
// receive.c
//

VOID
DigiLanIndicateReceive(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN PDIGILAN_FRAME_BUFFER pBuffer,
	IN PDIGILAN_ETHERNET_FRAME pFrame,
	IN ULONG PayloadLength
	);

NDIS_STATUS
DigiLanTransferData(
	OUT PNDIS_PACKET pPacket,
	OUT PUINT BytesTransferred,
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_HANDLE MiniportReceiveContext,
	IN UINT ByteOffset,
	IN UINT BytesToTransfer
	);

//
// send.c
//

NDIS_STATUS
DigiLanSend(
	IN NDIS_HANDLE MiniportAdapterContext,
	IN PNDIS_PACKET pNdisPacket,
	IN UINT Flags
	);

//
// setquery.c
//

NDIS_STATUS
DigiLanSetInformation(
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_OID Oid,
	IN PVOID pInformationBuffer,
	IN ULONG InformationBufferLength,
	OUT PULONG pBytesRead,
	OUT PULONG pBytesNeeded
	);

NDIS_STATUS
DigiLanQueryInformation(
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_OID Oid,
	IN PVOID InformationBuffer,
	IN ULONG InformationBufferLength,
	OUT PULONG BytesWritten,
	OUT PULONG BytesNeeded
	);

//
// utils.c
//

BOOLEAN
DigiCompareMemory(
	PUCHAR pMem1, 
	PUCHAR pMem2, 
	ULONG Length
	);

PACKET_TYPE
DigiLanGetPacketType(
	IN PNDIS_PACKET pNdisPacket
	);

NTSTATUS
DigiGetNdisPacketData( 
	OUT PUCHAR pBuffer,
	IN PNDIS_PACKET pNdisPacket,
	IN ULONG DataLength,
	IN ULONG DataOffset
	);

//
// fr.c
//

NTSTATUS
FrInitialize(
	IN OUT PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN HANDLE hRedirectKey
	);

void
FrStartUpdate(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter
	);

void
FrStopUpdate(
	IN PDIGILAN_LOGICAL_ADAPTER pAdapter
	);

//
// x25.c
//

NTSTATUS
X25Initialize(
	IN OUT PDIGILAN_LOGICAL_ADAPTER pAdapter,
	IN HANDLE hRedirectKey
	);

VOID
X25StopAttach(
    IN PDIGILAN_LOGICAL_ADAPTER pAdapter
    );

//
// Global data
//
extern DIGILAN_DRIVER_OBJECT DigiLanDriverObject;

#endif
