123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- * 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
- #include <linux/netdevice.h>
- #include <linux/if.h>
- #include <linux/spinlock.h>
- #include <uapi/linux/hdlcdrv.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;
- unsigned 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;
- unsigned 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 */
- 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 /* _HDLCDRV_H */
|