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 */
277