hdlcdrv.h (6468B)
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 *, void __user *, 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 */