diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 | 
| commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
| tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/linux/hdlcdrv.h | |
| download | olio-linux-3.10-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.xz olio-linux-3.10-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip  | |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/linux/hdlcdrv.h')
| -rw-r--r-- | include/linux/hdlcdrv.h | 378 | 
1 files changed, 378 insertions, 0 deletions
diff --git a/include/linux/hdlcdrv.h b/include/linux/hdlcdrv.h new file mode 100644 index 00000000000..4f6ee3b267f --- /dev/null +++ b/include/linux/hdlcdrv.h @@ -0,0 +1,378 @@ +/* + * hdlcdrv.h  -- HDLC packet radio network driver. + * The Linux soundcard driver for 1200 baud and 9600 baud packet radio + * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA + */ + +#ifndef _HDLCDRV_H +#define _HDLCDRV_H + +/* -------------------------------------------------------------------- */ +/* + * structs for the IOCTL commands + */ + +struct hdlcdrv_params { +	int iobase; +	int irq; +	int dma; +	int dma2; +	int seriobase; +	int pariobase; +	int midiiobase; +};	 + +struct hdlcdrv_channel_params { +	int tx_delay;  /* the transmitter keyup delay in 10ms units */ +	int tx_tail;   /* the transmitter keyoff delay in 10ms units */ +	int slottime;  /* the slottime in 10ms; usually 10 = 100ms */ +	int ppersist;  /* the p-persistence 0..255 */ +	int fulldup;   /* some driver do not support full duplex, setting */ +	               /* this just makes them send even if DCD is on */ +};	 + +struct hdlcdrv_old_channel_state { +  	int ptt; +  	int dcd; +  	int ptt_keyed; +}; + +struct hdlcdrv_channel_state { + 	int ptt; + 	int dcd; + 	int ptt_keyed; + 	unsigned long tx_packets; + 	unsigned long tx_errors; + 	unsigned long rx_packets; + 	unsigned long rx_errors; +}; + +struct hdlcdrv_ioctl { +	int cmd; +	union { +		struct hdlcdrv_params mp; +		struct hdlcdrv_channel_params cp; +		struct hdlcdrv_channel_state cs; +		struct hdlcdrv_old_channel_state ocs; +		unsigned int calibrate; +		unsigned char bits; +		char modename[128]; +		char drivername[32]; +	} data; +}; + +/* -------------------------------------------------------------------- */ + +/* + * ioctl values + */ +#define HDLCDRVCTL_GETMODEMPAR       0 +#define HDLCDRVCTL_SETMODEMPAR       1 +#define HDLCDRVCTL_MODEMPARMASK      2  /* not handled by hdlcdrv */ +#define HDLCDRVCTL_GETCHANNELPAR    10 +#define HDLCDRVCTL_SETCHANNELPAR    11 +#define HDLCDRVCTL_OLDGETSTAT       20 +#define HDLCDRVCTL_CALIBRATE        21 +#define HDLCDRVCTL_GETSTAT          22 + +/* + * these are mainly for debugging purposes + */ +#define HDLCDRVCTL_GETSAMPLES       30 +#define HDLCDRVCTL_GETBITS          31 + +/* + * not handled by hdlcdrv, but by its depending drivers + */ +#define HDLCDRVCTL_GETMODE          40 +#define HDLCDRVCTL_SETMODE          41 +#define HDLCDRVCTL_MODELIST         42 +#define HDLCDRVCTL_DRIVERNAME       43 + +/* + * mask of needed modem parameters, returned by HDLCDRVCTL_MODEMPARMASK + */ +#define HDLCDRV_PARMASK_IOBASE      (1<<0) +#define HDLCDRV_PARMASK_IRQ         (1<<1) +#define HDLCDRV_PARMASK_DMA         (1<<2) +#define HDLCDRV_PARMASK_DMA2        (1<<3) +#define HDLCDRV_PARMASK_SERIOBASE   (1<<4) +#define HDLCDRV_PARMASK_PARIOBASE   (1<<5) +#define HDLCDRV_PARMASK_MIDIIOBASE  (1<<6) + +/* -------------------------------------------------------------------- */ + +#ifdef __KERNEL__ + +#include <linux/netdevice.h> +#include <linux/if.h> +#include <linux/spinlock.h> + +#define HDLCDRV_MAGIC      0x5ac6e778 +#define HDLCDRV_HDLCBUFFER  32 /* should be a power of 2 for speed reasons */ +#define HDLCDRV_BITBUFFER  256 /* should be a power of 2 for speed reasons */ +#undef HDLCDRV_LOOPBACK  /* define for HDLC debugging purposes */ +#define HDLCDRV_DEBUG + +/* maximum packet length, excluding CRC */ +#define HDLCDRV_MAXFLEN             400	 + + +struct hdlcdrv_hdlcbuffer { +	spinlock_t lock; +	unsigned rd, wr; +	unsigned short buf[HDLCDRV_HDLCBUFFER]; +}; + +#ifdef HDLCDRV_DEBUG +struct hdlcdrv_bitbuffer { +	unsigned int rd; +	unsigned int wr; +	unsigned int shreg; +	unsigned char buffer[HDLCDRV_BITBUFFER]; +}; + +static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf,  +					 unsigned int bit) +{ +	unsigned char new; + +	new = buf->shreg & 1; +	buf->shreg >>= 1; +	buf->shreg |= (!!bit) << 7; +	if (new) { +		buf->buffer[buf->wr] = buf->shreg; +		buf->wr = (buf->wr+1) % sizeof(buf->buffer); +		buf->shreg = 0x80; +	} +} + +static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf,  +					      unsigned int bits) +{ +	buf->buffer[buf->wr] = bits & 0xff; +	buf->wr = (buf->wr+1) % sizeof(buf->buffer); +	buf->buffer[buf->wr] = (bits >> 8) & 0xff; +	buf->wr = (buf->wr+1) % sizeof(buf->buffer); + +} +#endif /* HDLCDRV_DEBUG */ + +/* -------------------------------------------------------------------- */ +/* + * Information that need to be kept for each driver.  + */ + +struct hdlcdrv_ops { +	/* +	 * first some informations needed by the hdlcdrv routines +	 */ +	const char *drvname; +	const char *drvinfo; +	/* +	 * the routines called by the hdlcdrv routines +	 */ +	int (*open)(struct net_device *); +	int (*close)(struct net_device *); +	int (*ioctl)(struct net_device *, struct ifreq *,  +		     struct hdlcdrv_ioctl *, int); +}; + +struct hdlcdrv_state { +	int magic; +	int opened; + +	const struct hdlcdrv_ops *ops; + +	struct { +		int bitrate; +	} par; + +	struct hdlcdrv_pttoutput { +		int dma2; +		int seriobase; +		int pariobase; +		int midiiobase; +		unsigned int flags; +	} ptt_out; + +	struct hdlcdrv_channel_params ch_params; + +	struct hdlcdrv_hdlcrx { +		struct hdlcdrv_hdlcbuffer hbuf; +		long in_hdlc_rx; +		/* 0 = sync hunt, != 0 receiving */ +		int rx_state;	 +		unsigned int bitstream; +		unsigned int bitbuf; +		int numbits; +		unsigned char dcd; +		 +		int len; +		unsigned char *bp; +		unsigned char buffer[HDLCDRV_MAXFLEN+2]; +	} hdlcrx; + +	struct hdlcdrv_hdlctx { +		struct hdlcdrv_hdlcbuffer hbuf; +		long in_hdlc_tx; +		/* +		 * 0 = send flags +		 * 1 = send txtail (flags) +		 * 2 = send packet +		 */ +		int tx_state;	 +		int numflags; +		unsigned int bitstream; +		unsigned char ptt; +		int calibrate; +		int slotcnt; + +		unsigned int bitbuf; +		int numbits; +		 +		int len; +		unsigned char *bp; +		unsigned char buffer[HDLCDRV_MAXFLEN+2]; +	} hdlctx; + +#ifdef HDLCDRV_DEBUG +	struct hdlcdrv_bitbuffer bitbuf_channel; +	struct hdlcdrv_bitbuffer bitbuf_hdlc; +#endif /* HDLCDRV_DEBUG */ + +	struct net_device_stats stats; +	int ptt_keyed; + +	/* queued skb for transmission */ +	struct sk_buff *skb; +}; + + +/* -------------------------------------------------------------------- */ + +static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb)  +{ +	unsigned long flags; +	int ret; +	 +	spin_lock_irqsave(&hb->lock, flags); +	ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER); +	spin_unlock_irqrestore(&hb->lock, flags); +	return ret; +} + +/* -------------------------------------------------------------------- */ + +static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb) +{ +	unsigned long flags; +	int ret; +	 +	spin_lock_irqsave(&hb->lock, flags); +	ret = (hb->rd == hb->wr); +	spin_unlock_irqrestore(&hb->lock, flags); +	return ret; +} + +/* -------------------------------------------------------------------- */ + +static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb) +{ +	unsigned long flags; +	unsigned short val; +	unsigned newr; + +	spin_lock_irqsave(&hb->lock, flags); +	if (hb->rd == hb->wr) +		val = 0; +	else { +		newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER; +		val = hb->buf[hb->rd]; +		hb->rd = newr; +	} +	spin_unlock_irqrestore(&hb->lock, flags); +	return val; +} + +/* -------------------------------------------------------------------- */ + +static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb,  +				    unsigned short val) +{ +	unsigned newp; +	unsigned long flags; +	 +	spin_lock_irqsave(&hb->lock, flags); +	newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER; +	if (newp != hb->rd) {  +		hb->buf[hb->wr] = val & 0xffff; +		hb->wr = newp; +	} +	spin_unlock_irqrestore(&hb->lock, flags); +} + +/* -------------------------------------------------------------------- */ + +static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits) +{ +	hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits); +} + +static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s) +{ +	unsigned int ret; + +	if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) { +		if (s->hdlctx.calibrate > 0) +			s->hdlctx.calibrate--; +		else +			s->hdlctx.ptt = 0; +		ret = 0; +	} else  +		ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf); +#ifdef HDLCDRV_LOOPBACK +	hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret); +#endif /* HDLCDRV_LOOPBACK */ +	return ret; +} + +static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit) +{ +#ifdef HDLCDRV_DEBUG +	hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit); +#endif /* HDLCDRV_DEBUG */ +} + +static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd) +{ +	s->hdlcrx.dcd = !!dcd; +} + +static inline int hdlcdrv_ptt(struct hdlcdrv_state *s) +{ +	return s->hdlctx.ptt || (s->hdlctx.calibrate > 0); +} + +/* -------------------------------------------------------------------- */ + +void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *); +void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *); +void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *); +struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops, +				    unsigned int privsize, const char *ifname, +				    unsigned int baseaddr, unsigned int irq,  +				    unsigned int dma); +void hdlcdrv_unregister(struct net_device *dev); + +/* -------------------------------------------------------------------- */ + + + +#endif /* __KERNEL__ */ + +/* -------------------------------------------------------------------- */ + +#endif /* _HDLCDRV_H */ + +/* -------------------------------------------------------------------- */  |