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