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 26 struct hdlcdrv_hdlcbuffer { 27 spinlock_t lock; 28 unsigned rd, wr; 29 unsigned short buf[HDLCDRV_HDLCBUFFER]; 30 }; 31 32 #ifdef HDLCDRV_DEBUG 33 struct hdlcdrv_bitbuffer { 34 unsigned int rd; 35 unsigned int wr; 36 unsigned int shreg; 37 unsigned char buffer[HDLCDRV_BITBUFFER]; 38 }; 39 40 static 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 55 static 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 71 struct 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 86 struct 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 158 static 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 171 static 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 184 static 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 204 static 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 221 static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits) 222 { 223 hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits); 224 } 225 226 static 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 244 static 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 251 static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd) 252 { 253 s->hdlcrx.dcd = !!dcd; 254 } 255 256 static inline int hdlcdrv_ptt(struct hdlcdrv_state *s) 257 { 258 return s->hdlctx.ptt || (s->hdlctx.calibrate > 0); 259 } 260 261 /* -------------------------------------------------------------------- */ 262 263 void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *); 264 void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *); 265 void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *); 266 struct 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); 270 void hdlcdrv_unregister(struct net_device *dev); 271 272 /* -------------------------------------------------------------------- */ 273 274 275 276 #endif /* _HDLCDRV_H */ 277
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.