/*
 * frf9.h - header file for Frame Relay compression protocol
 *
 * @(#) $Id: frf9.h,v 1.6 1996/10/22 21:18:47 gary Exp $
 */

#ifndef _FRF9_H
#define	_FRF9_H

#include "staclib.h"

/*
 * FRF.9 & Annex A Bit Field/Byte Field Definitions
 */

#define	DATA_COMPRESSION_NLPID	0xB0
#define	MODE_ONE_REQ		0x01
#define	MODE_ONE_RESP		0x02

/* DCP Header Bitfields */
#define	DCP_CONTROL_BIT		0x01
#define	DCP_RESERVED_BITS	0x0E
#define	DCP_RESET_REQUEST_BIT	0x10
#define	DCP_RESET_ACK_BIT	0x20
#define	DCP_COMPRESSED_BIT	0x40
#define	DCP_EXTENSION_BIT	0x80

/* ------------------------------------------------------------------------ */

/*
 * Maximum Contexts Supported Per DLCI
 */
#define	FRF9_MAX_CONTEXTS_PER_DLCI	6

/*
 * Queue Control Block.  Identical to QTCB structure.
 */

typedef struct LocalQptr_tag
{
	void *qtop;
	void *qbot;
} LocalQptrs_t;

typedef struct LocalQ_tag
{
    unsigned short    qcnt;
    LocalQptrs_t      Q;
}
LocalQ_t;

/*
 * Contains information about a single FRF.9 compression context
 */
typedef struct FRF9_Context_struct {

	/* Handle to compression context */
	uint32 Context;

	/* Pointers to frames for deferred operations */
	mblk_t *DefCompressFrame;
	mblk_t *DefDecompressFrame;

	/* Pointer to CCB which this DCCI is a part of */
	caddr_t ThisCCB;

	/* Sequence Number states */
	uint8 SequenceExpected;
	uint8 SequenceLastSent;

	/* Reset Request / Reset Ack States */
	uint8 RR_RA_State;

} FRF9_Context_t ;

/*
 * Contains all state information about a single FRF.9 session
 */
typedef struct FRF9_struct {

	/* Tracks state of FRF.9 negotiations */
	uint8 Phase;

	/* Tunable:  Seconds between Mode One Negotiation Packets */
	uint8 RetryPeriod;

	/* Tunable:  Number of retransmissions of Mode One Requests */
	uint8 RetryCount;

	/* Tunable:  Error-checking & data handling methods desired */
	uint8 ModesWanted;

	/* Tunable:  Contexts Allowed, limited to FRF9_MAX_CONTEXTS_PER_DLCI */
	uint16 ContextMax;

	/* Number of contexts actually negotiated */
	uint16 ContextCount;

	/* Error-checking & data handling methods actually negotiated */
	uint8 CurrentMode;

	/* Retransmissions of Mode One Requests remaining */
	uint8 RetriesLeft;

	/* Handle to Mode One retransmission timer */
	uint32 ModeOneTimer;

	/* Handle to History Reset Request timer */
	uint32 ResetTimer;

	/* Queue for Tx frames to be processed */
	LocalQ_t TxQueue;

	/* Context Database */
	FRF9_Context_t FRF9_Context[FRF9_MAX_CONTEXTS_PER_DLCI];

	/* Statistics */
	FRF9_Stats_t FRF9_Stats;

} FRF9_t ;

/*
 * Mode One Frame Structure
 */
typedef struct ModeOneFrame_struct {
	uint8  Q922MSB;
	uint8  Q922LSB;
	uint8  Control;
	uint8  NLPID;
	uint8  DCPHeader;
	uint8  Code;
	uint8  ID;
	uint8  ReqLength[2];
	uint8  Type;
	uint8  ConfLength;
	uint8  Revision;
} ModeOneFrame_t ;

#define	SIZEOF_EMPTY_DATA_FRAME	(Q922_ADDR_LEN+3)
/*
 * Values for RR_RA_State field (values chosen to match RR/RA bit positions)
 */
#define	SEND_RR		DCP_RESET_REQUEST_BIT
#define	SEND_RA		DCP_RESET_ACK_BIT

/*
 * Values for Phase field
 */
#define	FRF9_PHASE_UNUSED	0x00
#define	FRF9_PHASE_DISABLED	0x01
#define	FRF9_PHASE_INIT		0x02
#define	FRF9_PHASE_RESP_SENT	0x04
#define	FRF9_PHASE_RESP_RCVD	0x08
#define	FRF9_PHASE_OPERATIONAL	(FRF9_PHASE_INIT|FRF9_PHASE_RESP_SENT| \
				 FRF9_PHASE_RESP_RCVD)

/*
 * Check Mode & Process Mode flags
 */
#define	FRF9_TX_CKMODE_NONE	0x00
#define	FRF9_TX_CKMODE_SEQ	0x01
#define	FRF9_TX_CKMODE_LCB	0x02
#define	FRF9_TX_CKMODE_SEQ_LCB	0x03
#define	FRF9_TX_CKMODE_MASK	0x03
#define	FRF9_RX_CKMODE_NONE	0x00
#define	FRF9_RX_CKMODE_SEQ	0x04
#define	FRF9_RX_CKMODE_LCB	0x08
#define	FRF9_RX_CKMODE_SEQ_LCB	0x0C
#define	FRF9_RX_CKMODE_MASK	0x0C
#define	FRF9_TX_PMODE_COMP_ONLY		0x00
#define	FRF9_TX_PMODE_COMP_UNCOMP	0x10
#define	FRF9_TX_PMODE_MASK		0x10
#define	FRF9_RX_PMODE_COMP_ONLY		0x00
#define	FRF9_RX_PMODE_COMP_UNCOMP	0x20
#define	FRF9_RX_PMODE_MASK		0x20

/* Functional prototypes */
void FRF9LaunchModeOne();
void FRF9ResetCompleted();
void FRF9CompressFinished();
void FRF9DecompressFinished();
void FRF9RRTransmit();
void FRF9RxControl();
uint32 StopFRF9OperationPhase();
extern mblk_t *allocb();

/* Useful macros */
#define	SET_RR(x)	x |= SEND_RR
#define	SET_RA(x)	x |= SEND_RA
#define	UNSET_RR(x)	x &= ~SEND_RR
#define	UNSET_RA(x)	x &= ~SEND_RA

#endif	/* _FRF9_H */
