linux/include/linux/hdlcdrv.h
<<
>>
Prefs
   1/*
   2 * hdlcdrv.h  -- HDLC packet radio network driver.
   3 * The Linux soundcard driver for 1200 baud and 9600 baud packet radio
   4 * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
   5 */
   6#ifndef _HDLCDRV_H
   7#define _HDLCDRV_H
   8
   9
  10#include <linux/netdevice.h>
  11#include <linux/if.h>
  12#include <linux/spinlock.h>
  13#include <uapi/linux/hdlcdrv.h>
  14
  15#define HDLCDRV_MAGIC      0x5ac6e778
  16#define HDLCDRV_HDLCBUFFER  32 /* should be a power of 2 for speed reasons */
  17#define HDLCDRV_BITBUFFER  256 /* should be a power of 2 for speed reasons */
  18#undef HDLCDRV_LOOPBACK  /* define for HDLC debugging purposes */
  19#define HDLCDRV_DEBUG
  20
  21/* maximum packet length, excluding CRC */
  22#define HDLCDRV_MAXFLEN             400 
  23
  24
  25struct hdlcdrv_hdlcbuffer {
  26        spinlock_t lock;
  27        unsigned rd, wr;
  28        unsigned short buf[HDLCDRV_HDLCBUFFER];
  29};
  30
  31#ifdef HDLCDRV_DEBUG
  32struct hdlcdrv_bitbuffer {
  33        unsigned int rd;
  34        unsigned int wr;
  35        unsigned int shreg;
  36        unsigned char buffer[HDLCDRV_BITBUFFER];
  37};
  38
  39static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf, 
  40                                         unsigned int bit)
  41{
  42        unsigned char new;
  43
  44        new = buf->shreg & 1;
  45        buf->shreg >>= 1;
  46        buf->shreg |= (!!bit) << 7;
  47        if (new) {
  48                buf->buffer[buf->wr] = buf->shreg;
  49                buf->wr = (buf->wr+1) % sizeof(buf->buffer);
  50                buf->shreg = 0x80;
  51        }
  52}
  53
  54static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf, 
  55                                              unsigned int bits)
  56{
  57        buf->buffer[buf->wr] = bits & 0xff;
  58        buf->wr = (buf->wr+1) % sizeof(buf->buffer);
  59        buf->buffer[buf->wr] = (bits >> 8) & 0xff;
  60        buf->wr = (buf->wr+1) % sizeof(buf->buffer);
  61
  62}
  63#endif /* HDLCDRV_DEBUG */
  64
  65/* -------------------------------------------------------------------- */
  66/*
  67 * Information that need to be kept for each driver. 
  68 */
  69
  70struct hdlcdrv_ops {
  71        /*
  72         * first some informations needed by the hdlcdrv routines
  73         */
  74        const char *drvname;
  75        const char *drvinfo;
  76        /*
  77         * the routines called by the hdlcdrv routines
  78         */
  79        int (*open)(struct net_device *);
  80        int (*close)(struct net_device *);
  81        int (*ioctl)(struct net_device *, struct ifreq *, 
  82                     struct hdlcdrv_ioctl *, int);
  83};
  84
  85struct hdlcdrv_state {
  86        int magic;
  87        int opened;
  88
  89        const struct hdlcdrv_ops *ops;
  90
  91        struct {
  92                int bitrate;
  93        } par;
  94
  95        struct hdlcdrv_pttoutput {
  96                int dma2;
  97                int seriobase;
  98                int pariobase;
  99                int midiiobase;
 100                unsigned int flags;
 101        } ptt_out;
 102
 103        struct hdlcdrv_channel_params ch_params;
 104
 105        struct hdlcdrv_hdlcrx {
 106                struct hdlcdrv_hdlcbuffer hbuf;
 107                unsigned long in_hdlc_rx;
 108                /* 0 = sync hunt, != 0 receiving */
 109                int rx_state;   
 110                unsigned int bitstream;
 111                unsigned int bitbuf;
 112                int numbits;
 113                unsigned char dcd;
 114                
 115                int len;
 116                unsigned char *bp;
 117                unsigned char buffer[HDLCDRV_MAXFLEN+2];
 118        } hdlcrx;
 119
 120        struct hdlcdrv_hdlctx {
 121                struct hdlcdrv_hdlcbuffer hbuf;
 122                unsigned long in_hdlc_tx;
 123                /*
 124                 * 0 = send flags
 125                 * 1 = send txtail (flags)
 126                 * 2 = send packet
 127                 */
 128                int tx_state;   
 129                int numflags;
 130                unsigned int bitstream;
 131                unsigned char ptt;
 132                int calibrate;
 133                int slotcnt;
 134
 135                unsigned int bitbuf;
 136                int numbits;
 137                
 138                int len;
 139                unsigned char *bp;
 140                unsigned char buffer[HDLCDRV_MAXFLEN+2];
 141        } hdlctx;
 142
 143#ifdef HDLCDRV_DEBUG
 144        struct hdlcdrv_bitbuffer bitbuf_channel;
 145        struct hdlcdrv_bitbuffer bitbuf_hdlc;
 146#endif /* HDLCDRV_DEBUG */
 147
 148        int ptt_keyed;
 149
 150        /* queued skb for transmission */
 151        struct sk_buff *skb;
 152};
 153
 154
 155/* -------------------------------------------------------------------- */
 156
 157static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb) 
 158{
 159        unsigned long flags;
 160        int ret;
 161        
 162        spin_lock_irqsave(&hb->lock, flags);
 163        ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER);
 164        spin_unlock_irqrestore(&hb->lock, flags);
 165        return ret;
 166}
 167
 168/* -------------------------------------------------------------------- */
 169
 170static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb)
 171{
 172        unsigned long flags;
 173        int ret;
 174        
 175        spin_lock_irqsave(&hb->lock, flags);
 176        ret = (hb->rd == hb->wr);
 177        spin_unlock_irqrestore(&hb->lock, flags);
 178        return ret;
 179}
 180
 181/* -------------------------------------------------------------------- */
 182
 183static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb)
 184{
 185        unsigned long flags;
 186        unsigned short val;
 187        unsigned newr;
 188
 189        spin_lock_irqsave(&hb->lock, flags);
 190        if (hb->rd == hb->wr)
 191                val = 0;
 192        else {
 193                newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER;
 194                val = hb->buf[hb->rd];
 195                hb->rd = newr;
 196        }
 197        spin_unlock_irqrestore(&hb->lock, flags);
 198        return val;
 199}
 200
 201/* -------------------------------------------------------------------- */
 202
 203static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb, 
 204                                    unsigned short val)
 205{
 206        unsigned newp;
 207        unsigned long flags;
 208        
 209        spin_lock_irqsave(&hb->lock, flags);
 210        newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER;
 211        if (newp != hb->rd) { 
 212                hb->buf[hb->wr] = val & 0xffff;
 213                hb->wr = newp;
 214        }
 215        spin_unlock_irqrestore(&hb->lock, flags);
 216}
 217
 218/* -------------------------------------------------------------------- */
 219
 220static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits)
 221{
 222        hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits);
 223}
 224
 225static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s)
 226{
 227        unsigned int ret;
 228
 229        if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) {
 230                if (s->hdlctx.calibrate > 0)
 231                        s->hdlctx.calibrate--;
 232                else
 233                        s->hdlctx.ptt = 0;
 234                ret = 0;
 235        } else 
 236                ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf);
 237#ifdef HDLCDRV_LOOPBACK
 238        hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret);
 239#endif /* HDLCDRV_LOOPBACK */
 240        return ret;
 241}
 242
 243static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit)
 244{
 245#ifdef HDLCDRV_DEBUG
 246        hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit);
 247#endif /* HDLCDRV_DEBUG */
 248}
 249
 250static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd)
 251{
 252        s->hdlcrx.dcd = !!dcd;
 253}
 254
 255static inline int hdlcdrv_ptt(struct hdlcdrv_state *s)
 256{
 257        return s->hdlctx.ptt || (s->hdlctx.calibrate > 0);
 258}
 259
 260/* -------------------------------------------------------------------- */
 261
 262void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *);
 263void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *);
 264void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *);
 265struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
 266                                    unsigned int privsize, const char *ifname,
 267                                    unsigned int baseaddr, unsigned int irq, 
 268                                    unsigned int dma);
 269void hdlcdrv_unregister(struct net_device *dev);
 270
 271/* -------------------------------------------------------------------- */
 272
 273
 274
 275#endif /* _HDLCDRV_H */
 276
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.