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
   7#ifndef _HDLCDRV_H
   8#define _HDLCDRV_H
   9
  10/* -------------------------------------------------------------------- */
  11/*
  12 * structs for the IOCTL commands
  13 */
  14
  15struct hdlcdrv_params {
  16        int iobase;
  17        int irq;
  18        int dma;
  19        int dma2;
  20        int seriobase;
  21        int pariobase;
  22        int midiiobase;
  23};      
  24
  25struct hdlcdrv_channel_params {
  26        int tx_delay;  /* the transmitter keyup delay in 10ms units */
  27        int tx_tail;   /* the transmitter keyoff delay in 10ms units */
  28        int slottime;  /* the slottime in 10ms; usually 10 = 100ms */
  29        int ppersist;  /* the p-persistence 0..255 */
  30        int fulldup;   /* some driver do not support full duplex, setting */
  31                       /* this just makes them send even if DCD is on */
  32};      
  33
  34struct hdlcdrv_old_channel_state {
  35        int ptt;
  36        int dcd;
  37        int ptt_keyed;
  38};
  39
  40struct hdlcdrv_channel_state {
  41        int ptt;
  42        int dcd;
  43        int ptt_keyed;
  44        unsigned long tx_packets;
  45        unsigned long tx_errors;
  46        unsigned long rx_packets;
  47        unsigned long rx_errors;
  48};
  49
  50struct hdlcdrv_ioctl {
  51        int cmd;
  52        union {
  53                struct hdlcdrv_params mp;
  54                struct hdlcdrv_channel_params cp;
  55                struct hdlcdrv_channel_state cs;
  56                struct hdlcdrv_old_channel_state ocs;
  57                unsigned int calibrate;
  58                unsigned char bits;
  59                char modename[128];
  60                char drivername[32];
  61        } data;
  62};
  63
  64/* -------------------------------------------------------------------- */
  65
  66/*
  67 * ioctl values
  68 */
  69#define HDLCDRVCTL_GETMODEMPAR       0
  70#define HDLCDRVCTL_SETMODEMPAR       1
  71#define HDLCDRVCTL_MODEMPARMASK      2  /* not handled by hdlcdrv */
  72#define HDLCDRVCTL_GETCHANNELPAR    10
  73#define HDLCDRVCTL_SETCHANNELPAR    11
  74#define HDLCDRVCTL_OLDGETSTAT       20
  75#define HDLCDRVCTL_CALIBRATE        21
  76#define HDLCDRVCTL_GETSTAT          22
  77
  78/*
  79 * these are mainly for debugging purposes
  80 */
  81#define HDLCDRVCTL_GETSAMPLES       30
  82#define HDLCDRVCTL_GETBITS          31
  83
  84/*
  85 * not handled by hdlcdrv, but by its depending drivers
  86 */
  87#define HDLCDRVCTL_GETMODE          40
  88#define HDLCDRVCTL_SETMODE          41
  89#define HDLCDRVCTL_MODELIST         42
  90#define HDLCDRVCTL_DRIVERNAME       43
  91
  92/*
  93 * mask of needed modem parameters, returned by HDLCDRVCTL_MODEMPARMASK
  94 */
  95#define HDLCDRV_PARMASK_IOBASE      (1<<0)
  96#define HDLCDRV_PARMASK_IRQ         (1<<1)
  97#define HDLCDRV_PARMASK_DMA         (1<<2)
  98#define HDLCDRV_PARMASK_DMA2        (1<<3)
  99#define HDLCDRV_PARMASK_SERIOBASE   (1<<4)
 100#define HDLCDRV_PARMASK_PARIOBASE   (1<<5)
 101#define HDLCDRV_PARMASK_MIDIIOBASE  (1<<6)
 102
 103/* -------------------------------------------------------------------- */
 104
 105#ifdef __KERNEL__
 106
 107#include <linux/netdevice.h>
 108#include <linux/if.h>
 109#include <linux/spinlock.h>
 110
 111#define HDLCDRV_MAGIC      0x5ac6e778
 112#define HDLCDRV_HDLCBUFFER  32 /* should be a power of 2 for speed reasons */
 113#define HDLCDRV_BITBUFFER  256 /* should be a power of 2 for speed reasons */
 114#undef HDLCDRV_LOOPBACK  /* define for HDLC debugging purposes */
 115#define HDLCDRV_DEBUG
 116
 117/* maximum packet length, excluding CRC */
 118#define HDLCDRV_MAXFLEN             400 
 119
 120
 121struct hdlcdrv_hdlcbuffer {
 122        spinlock_t lock;
 123        unsigned rd, wr;
 124        unsigned short buf[HDLCDRV_HDLCBUFFER];
 125};
 126
 127#ifdef HDLCDRV_DEBUG
 128struct hdlcdrv_bitbuffer {
 129        unsigned int rd;
 130        unsigned int wr;
 131        unsigned int shreg;
 132        unsigned char buffer[HDLCDRV_BITBUFFER];
 133};
 134
 135static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf, 
 136                                         unsigned int bit)
 137{
 138        unsigned char new;
 139
 140        new = buf->shreg & 1;
 141        buf->shreg >>= 1;
 142        buf->shreg |= (!!bit) << 7;
 143        if (new) {
 144                buf->buffer[buf->wr] = buf->shreg;
 145                buf->wr = (buf->wr+1) % sizeof(buf->buffer);
 146                buf->shreg = 0x80;
 147        }
 148}
 149
 150static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf, 
 151                                              unsigned int bits)
 152{
 153        buf->buffer[buf->wr] = bits & 0xff;
 154        buf->wr = (buf->wr+1) % sizeof(buf->buffer);
 155        buf->buffer[buf->wr] = (bits >> 8) & 0xff;
 156        buf->wr = (buf->wr+1) % sizeof(buf->buffer);
 157
 158}
 159#endif /* HDLCDRV_DEBUG */
 160
 161/* -------------------------------------------------------------------- */
 162/*
 163 * Information that need to be kept for each driver. 
 164 */
 165
 166struct hdlcdrv_ops {
 167        /*
 168         * first some informations needed by the hdlcdrv routines
 169         */
 170        const char *drvname;
 171        const char *drvinfo;
 172        /*
 173         * the routines called by the hdlcdrv routines
 174         */
 175        int (*open)(struct net_device *);
 176        int (*close)(struct net_device *);
 177        int (*ioctl)(struct net_device *, struct ifreq *, 
 178                     struct hdlcdrv_ioctl *, int);
 179};
 180
 181struct hdlcdrv_state {
 182        int magic;
 183        int opened;
 184
 185        const struct hdlcdrv_ops *ops;
 186
 187        struct {
 188                int bitrate;
 189        } par;
 190
 191        struct hdlcdrv_pttoutput {
 192                int dma2;
 193                int seriobase;
 194                int pariobase;
 195                int midiiobase;
 196                unsigned int flags;
 197        } ptt_out;
 198
 199        struct hdlcdrv_channel_params ch_params;
 200
 201        struct hdlcdrv_hdlcrx {
 202                struct hdlcdrv_hdlcbuffer hbuf;
 203                unsigned long in_hdlc_rx;
 204                /* 0 = sync hunt, != 0 receiving */
 205                int rx_state;   
 206                unsigned int bitstream;
 207                unsigned int bitbuf;
 208                int numbits;
 209                unsigned char dcd;
 210                
 211                int len;
 212                unsigned char *bp;
 213                unsigned char buffer[HDLCDRV_MAXFLEN+2];
 214        } hdlcrx;
 215
 216        struct hdlcdrv_hdlctx {
 217                struct hdlcdrv_hdlcbuffer hbuf;
 218                unsigned long in_hdlc_tx;
 219                /*
 220                 * 0 = send flags
 221                 * 1 = send txtail (flags)
 222                 * 2 = send packet
 223                 */
 224                int tx_state;   
 225                int numflags;
 226                unsigned int bitstream;
 227                unsigned char ptt;
 228                int calibrate;
 229                int slotcnt;
 230
 231                unsigned int bitbuf;
 232                int numbits;
 233                
 234                int len;
 235                unsigned char *bp;
 236                unsigned char buffer[HDLCDRV_MAXFLEN+2];
 237        } hdlctx;
 238
 239#ifdef HDLCDRV_DEBUG
 240        struct hdlcdrv_bitbuffer bitbuf_channel;
 241        struct hdlcdrv_bitbuffer bitbuf_hdlc;
 242#endif /* HDLCDRV_DEBUG */
 243
 244        int ptt_keyed;
 245
 246        /* queued skb for transmission */
 247        struct sk_buff *skb;
 248};
 249
 250
 251/* -------------------------------------------------------------------- */
 252
 253static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb) 
 254{
 255        unsigned long flags;
 256        int ret;
 257        
 258        spin_lock_irqsave(&hb->lock, flags);
 259        ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER);
 260        spin_unlock_irqrestore(&hb->lock, flags);
 261        return ret;
 262}
 263
 264/* -------------------------------------------------------------------- */
 265
 266static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb)
 267{
 268        unsigned long flags;
 269        int ret;
 270        
 271        spin_lock_irqsave(&hb->lock, flags);
 272        ret = (hb->rd == hb->wr);
 273        spin_unlock_irqrestore(&hb->lock, flags);
 274        return ret;
 275}
 276
 277/* -------------------------------------------------------------------- */
 278
 279static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb)
 280{
 281        unsigned long flags;
 282        unsigned short val;
 283        unsigned newr;
 284
 285        spin_lock_irqsave(&hb->lock, flags);
 286        if (hb->rd == hb->wr)
 287                val = 0;
 288        else {
 289                newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER;
 290                val = hb->buf[hb->rd];
 291                hb->rd = newr;
 292        }
 293        spin_unlock_irqrestore(&hb->lock, flags);
 294        return val;
 295}
 296
 297/* -------------------------------------------------------------------- */
 298
 299static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb, 
 300                                    unsigned short val)
 301{
 302        unsigned newp;
 303        unsigned long flags;
 304        
 305        spin_lock_irqsave(&hb->lock, flags);
 306        newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER;
 307        if (newp != hb->rd) { 
 308                hb->buf[hb->wr] = val & 0xffff;
 309                hb->wr = newp;
 310        }
 311        spin_unlock_irqrestore(&hb->lock, flags);
 312}
 313
 314/* -------------------------------------------------------------------- */
 315
 316static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits)
 317{
 318        hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits);
 319}
 320
 321static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s)
 322{
 323        unsigned int ret;
 324
 325        if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) {
 326                if (s->hdlctx.calibrate > 0)
 327                        s->hdlctx.calibrate--;
 328                else
 329                        s->hdlctx.ptt = 0;
 330                ret = 0;
 331        } else 
 332                ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf);
 333#ifdef HDLCDRV_LOOPBACK
 334        hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret);
 335#endif /* HDLCDRV_LOOPBACK */
 336        return ret;
 337}
 338
 339static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit)
 340{
 341#ifdef HDLCDRV_DEBUG
 342        hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit);
 343#endif /* HDLCDRV_DEBUG */
 344}
 345
 346static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd)
 347{
 348        s->hdlcrx.dcd = !!dcd;
 349}
 350
 351static inline int hdlcdrv_ptt(struct hdlcdrv_state *s)
 352{
 353        return s->hdlctx.ptt || (s->hdlctx.calibrate > 0);
 354}
 355
 356/* -------------------------------------------------------------------- */
 357
 358void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *);
 359void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *);
 360void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *);
 361struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
 362                                    unsigned int privsize, const char *ifname,
 363                                    unsigned int baseaddr, unsigned int irq, 
 364                                    unsigned int dma);
 365void hdlcdrv_unregister(struct net_device *dev);
 366
 367/* -------------------------------------------------------------------- */
 368
 369
 370
 371#endif /* __KERNEL__ */
 372
 373/* -------------------------------------------------------------------- */
 374
 375#endif /* _HDLCDRV_H */
 376
 377/* -------------------------------------------------------------------- */
 378