File Index
Files and directories
Sign in
FILE

hdlcdrv.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/hdlcdrv.h C
  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 */
~/ Read-only file preview.