/* atmdev.h - ATM device driver declarations */
 
/* Written 1995 by Werner Almesberger, EPFL LRC */
 

#ifndef LINUX_ATMDEV_H
#define LINUX_ATMDEV_H


#define MAX_ATM_ITF	10	/* for now, should be lowered */
#define MAX_ATM_VCC	128	/* for now, should be dynamic */

#define ESI_LEN		6

#define ATM_OC3_PCR	(155520000/270*260/8/53)
			/* OC3 link rate:  155520000 bps
			   SONET overhead: /270*260 (9 section, 1 path)
			   bits per cell:  /8/53
			   max cell rate:  353207.547 cells/sec */

#define ATM_SD(s)	((struct atm_vcc *) ((s)->data))


struct atm_aal_stats {
	long		tx,tx_err;	/* TX okay and errors */
	long		rx,rx_err;	/* RX okay and errors */
	long		rx_drop;	/* RX out of memory */
};


struct atm_dev_stats {
	struct atm_aal_stats aal0;
	struct atm_aal_stats aal5;
};


#define ATM_GETNAMES	0x41544df0
#define ATM_GETSTATZ	0x41544df4
#define ATM_GETSTAT	0x41544df5


struct atm_iobuf {
	int length;
	int *buffer;
};


#define ATM_BACKLOG_DEFAULT 32 /* if we get more, we're likely to time out
				  anyway */

#ifdef __KERNEL__

#include <linux/sched.h> /* struct wait_queue */
#include <linux/time.h> /* struct timeval */
#include <linux/net.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/atm.h>


#define ATM_VF_ADDR	 1	/* Address is in use. Set by anybody, cleared
				   by device driver. */
#define ATM_VF_READY	 2	/* VC is ready to transfer data. Set by device
				   driver, cleared by anybody. */
#define ATM_VF_PARTIAL	 4	/* resources are bound to PVC (partial PVC
				   setup), controlled by device driver */
#define ATM_VF_BOUND	 4	/* local SAP is set, controlled by SVC socket
				   layer */
#define ATM_VF_REGIS	 8	/* registered with demon, controlled by SVC
				   socket layer */
#define ATM_VF_RELEASED 16	/* demon has indicated/requested release,
				   controlled by SVC socket layer */

struct atm_vcc {
	unsigned char	flags;		/* VCC flags (ATM_VF_*) */
	unsigned char	family;		/* address family; 0 if unused */
	unsigned char	aal;		/* ATM Adaption Layer */
	short		vpi;		/* VPI and VCI (types must be equal */
					/* with sockaddr) */
	int 		vci;
	unsigned long	aal_options;	/* AAL layer options */
	unsigned long	atm_options;	/* ATM layer options */
	struct atm_dev	*dev;		/* device back pointer */
	struct atm_trafprm txtp,rxtp;	/* traffic parameters */
	unsigned long	tx_quota,rx_quota; /* buffer quotas */
	unsigned long	tx_inuse,rx_inuse; /* buffer space in use */
	void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);
	void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */
	struct sk_buff *(*peek)(struct atm_vcc *vcc,unsigned long pdu_size,
	    unsigned long (*fetch)(struct atm_vcc *vcc,int i));
					/* super-efficient xfers; note that */
					/* PDU_SIZE may be rounded */
	int (*push_oam)(struct atm_vcc *vcc,void *cell);
	void		*dev_data;	/* per-device data */
	void		*proto_data;	/* per-protocol data */
	struct timeval	timestamp;	/* AAL timestamps */
	struct sk_buff_head recvq;	/* receive queue */
	struct atm_aal_stats *stats;	/* pointer to AAL stats group */
	struct wait_queue *sleep;	/* if socket is busy */
	struct atm_vcc	*prev,*next;
	/* SVC part --- may move later */
	struct sockaddr_atmsvc local;
	struct sockaddr_atmsvc remote;
	void (*callback)(struct atm_vcc *vcc);
	struct sk_buff_head listenq;
	int		backlog_quota;	/* number of connection requests we */
					/* can still accept */
	int		reply;
	void		*user_back;	/* user backlink - not touched */
};


struct atm_dev {
	struct atmdev_ops *ops;		/* device operations; NULL if unused */
	struct atmphy_ops *phy;		/* PHY operations, may be undefined */
					/* (NULL) */
	const char	*type;		/* device type name */
	int		number;		/* device index */
	struct atm_vcc	*vccs;		/* VCC table (or NULL) */
	struct atm_vcc	*last;		/* last VCC (or undefined) */
	void		*dev_data;	/* per-device data */
	void		*phy_data;	/* private PHY date */
	unsigned char	esi[ESI_LEN];	/* ESI ("MAC" addr) */
	unsigned char	prv[ATM_ESA_LEN];/* private ATM address */
	char		pub[ATM_E164_LEN+1]; /* public address (E.164) */
	struct atm_cirange ci_range;	/* VPI/VCI range */
	struct atm_dev_stats stats;	/* statistics */
/* */ int sending;
};


/*
 * ioctl, getsockopt, setsockopt, sg_send, and poll are optional and can
 * be set to NULL.
 */

#define ATM_OF_IMMED	1	/* Attempt immediate delivery */
#define ATM_OF_INRATE	2	/* Attempt in-rate delivery */

struct atmdev_ops { /* only send is required */
	int (*open)(struct atm_vcc *vcc,short vpi,int vci);
	void (*close)(struct atm_vcc *vcc);
	int (*ioctl)(struct atm_dev *dev,unsigned int cmd,unsigned long arg);
	int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
	    char *optval,int *optlen);
	int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
	    char *optval,int optlen);
	int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
	int (*sg_send)(struct atm_vcc *vcc,unsigned long start,
	    unsigned long size);
	void (*poll)(struct atm_vcc *vcc,int nonblock);
	int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
	void (*phy_put)(struct atm_dev *dev,unsigned char value,
	    unsigned long addr);
	unsigned char (*phy_get)(struct atm_dev *dev,unsigned long addr);
	void (*feedback)(struct atm_vcc *vcc,struct sk_buff *skb,
	    unsigned long start,unsigned long dest,int len);
};


struct atmphy_ops {
	int (*start)(struct atm_dev *dev);
	int (*ioctl)(struct atm_dev *dev,unsigned int cmd,unsigned long arg);
	void (*interrupt)(struct atm_dev *dev);
};


struct atm_dev *atm_dev_register(const char *type,struct atmdev_ops *ops);
void atm_dev_deregister(struct atm_dev *dev);
int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci);

#endif /* __KERNEL__ */

#endif
