1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * hdlcdrv.h -- HDLC packet radio network driver.
4*4882a593Smuzhiyun * The Linux soundcard driver for 1200 baud and 9600 baud packet radio
5*4882a593Smuzhiyun * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun #ifndef _HDLCDRV_H
8*4882a593Smuzhiyun #define _HDLCDRV_H
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/netdevice.h>
12*4882a593Smuzhiyun #include <linux/if.h>
13*4882a593Smuzhiyun #include <linux/spinlock.h>
14*4882a593Smuzhiyun #include <uapi/linux/hdlcdrv.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define HDLCDRV_MAGIC 0x5ac6e778
17*4882a593Smuzhiyun #define HDLCDRV_HDLCBUFFER 32 /* should be a power of 2 for speed reasons */
18*4882a593Smuzhiyun #define HDLCDRV_BITBUFFER 256 /* should be a power of 2 for speed reasons */
19*4882a593Smuzhiyun #undef HDLCDRV_LOOPBACK /* define for HDLC debugging purposes */
20*4882a593Smuzhiyun #define HDLCDRV_DEBUG
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /* maximum packet length, excluding CRC */
23*4882a593Smuzhiyun #define HDLCDRV_MAXFLEN 400
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun struct hdlcdrv_hdlcbuffer {
27*4882a593Smuzhiyun spinlock_t lock;
28*4882a593Smuzhiyun unsigned rd, wr;
29*4882a593Smuzhiyun unsigned short buf[HDLCDRV_HDLCBUFFER];
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #ifdef HDLCDRV_DEBUG
33*4882a593Smuzhiyun struct hdlcdrv_bitbuffer {
34*4882a593Smuzhiyun unsigned int rd;
35*4882a593Smuzhiyun unsigned int wr;
36*4882a593Smuzhiyun unsigned int shreg;
37*4882a593Smuzhiyun unsigned char buffer[HDLCDRV_BITBUFFER];
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun
hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer * buf,unsigned int bit)40*4882a593Smuzhiyun static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf,
41*4882a593Smuzhiyun unsigned int bit)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun unsigned char new;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun new = buf->shreg & 1;
46*4882a593Smuzhiyun buf->shreg >>= 1;
47*4882a593Smuzhiyun buf->shreg |= (!!bit) << 7;
48*4882a593Smuzhiyun if (new) {
49*4882a593Smuzhiyun buf->buffer[buf->wr] = buf->shreg;
50*4882a593Smuzhiyun buf->wr = (buf->wr+1) % sizeof(buf->buffer);
51*4882a593Smuzhiyun buf->shreg = 0x80;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun
hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer * buf,unsigned int bits)55*4882a593Smuzhiyun static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf,
56*4882a593Smuzhiyun unsigned int bits)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun buf->buffer[buf->wr] = bits & 0xff;
59*4882a593Smuzhiyun buf->wr = (buf->wr+1) % sizeof(buf->buffer);
60*4882a593Smuzhiyun buf->buffer[buf->wr] = (bits >> 8) & 0xff;
61*4882a593Smuzhiyun buf->wr = (buf->wr+1) % sizeof(buf->buffer);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun #endif /* HDLCDRV_DEBUG */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
67*4882a593Smuzhiyun /*
68*4882a593Smuzhiyun * Information that need to be kept for each driver.
69*4882a593Smuzhiyun */
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun struct hdlcdrv_ops {
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * first some informations needed by the hdlcdrv routines
74*4882a593Smuzhiyun */
75*4882a593Smuzhiyun const char *drvname;
76*4882a593Smuzhiyun const char *drvinfo;
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun * the routines called by the hdlcdrv routines
79*4882a593Smuzhiyun */
80*4882a593Smuzhiyun int (*open)(struct net_device *);
81*4882a593Smuzhiyun int (*close)(struct net_device *);
82*4882a593Smuzhiyun int (*ioctl)(struct net_device *, struct ifreq *,
83*4882a593Smuzhiyun struct hdlcdrv_ioctl *, int);
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun struct hdlcdrv_state {
87*4882a593Smuzhiyun int magic;
88*4882a593Smuzhiyun int opened;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun const struct hdlcdrv_ops *ops;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun struct {
93*4882a593Smuzhiyun int bitrate;
94*4882a593Smuzhiyun } par;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun struct hdlcdrv_pttoutput {
97*4882a593Smuzhiyun int dma2;
98*4882a593Smuzhiyun int seriobase;
99*4882a593Smuzhiyun int pariobase;
100*4882a593Smuzhiyun int midiiobase;
101*4882a593Smuzhiyun unsigned int flags;
102*4882a593Smuzhiyun } ptt_out;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun struct hdlcdrv_channel_params ch_params;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun struct hdlcdrv_hdlcrx {
107*4882a593Smuzhiyun struct hdlcdrv_hdlcbuffer hbuf;
108*4882a593Smuzhiyun unsigned long in_hdlc_rx;
109*4882a593Smuzhiyun /* 0 = sync hunt, != 0 receiving */
110*4882a593Smuzhiyun int rx_state;
111*4882a593Smuzhiyun unsigned int bitstream;
112*4882a593Smuzhiyun unsigned int bitbuf;
113*4882a593Smuzhiyun int numbits;
114*4882a593Smuzhiyun unsigned char dcd;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun int len;
117*4882a593Smuzhiyun unsigned char *bp;
118*4882a593Smuzhiyun unsigned char buffer[HDLCDRV_MAXFLEN+2];
119*4882a593Smuzhiyun } hdlcrx;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun struct hdlcdrv_hdlctx {
122*4882a593Smuzhiyun struct hdlcdrv_hdlcbuffer hbuf;
123*4882a593Smuzhiyun unsigned long in_hdlc_tx;
124*4882a593Smuzhiyun /*
125*4882a593Smuzhiyun * 0 = send flags
126*4882a593Smuzhiyun * 1 = send txtail (flags)
127*4882a593Smuzhiyun * 2 = send packet
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun int tx_state;
130*4882a593Smuzhiyun int numflags;
131*4882a593Smuzhiyun unsigned int bitstream;
132*4882a593Smuzhiyun unsigned char ptt;
133*4882a593Smuzhiyun int calibrate;
134*4882a593Smuzhiyun int slotcnt;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun unsigned int bitbuf;
137*4882a593Smuzhiyun int numbits;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun int len;
140*4882a593Smuzhiyun unsigned char *bp;
141*4882a593Smuzhiyun unsigned char buffer[HDLCDRV_MAXFLEN+2];
142*4882a593Smuzhiyun } hdlctx;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun #ifdef HDLCDRV_DEBUG
145*4882a593Smuzhiyun struct hdlcdrv_bitbuffer bitbuf_channel;
146*4882a593Smuzhiyun struct hdlcdrv_bitbuffer bitbuf_hdlc;
147*4882a593Smuzhiyun #endif /* HDLCDRV_DEBUG */
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun int ptt_keyed;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* queued skb for transmission */
152*4882a593Smuzhiyun struct sk_buff *skb;
153*4882a593Smuzhiyun };
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
157*4882a593Smuzhiyun
hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer * hb)158*4882a593Smuzhiyun static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun unsigned long flags;
161*4882a593Smuzhiyun int ret;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun spin_lock_irqsave(&hb->lock, flags);
164*4882a593Smuzhiyun ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER);
165*4882a593Smuzhiyun spin_unlock_irqrestore(&hb->lock, flags);
166*4882a593Smuzhiyun return ret;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
170*4882a593Smuzhiyun
hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer * hb)171*4882a593Smuzhiyun static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun unsigned long flags;
174*4882a593Smuzhiyun int ret;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun spin_lock_irqsave(&hb->lock, flags);
177*4882a593Smuzhiyun ret = (hb->rd == hb->wr);
178*4882a593Smuzhiyun spin_unlock_irqrestore(&hb->lock, flags);
179*4882a593Smuzhiyun return ret;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
183*4882a593Smuzhiyun
hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer * hb)184*4882a593Smuzhiyun static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun unsigned long flags;
187*4882a593Smuzhiyun unsigned short val;
188*4882a593Smuzhiyun unsigned newr;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun spin_lock_irqsave(&hb->lock, flags);
191*4882a593Smuzhiyun if (hb->rd == hb->wr)
192*4882a593Smuzhiyun val = 0;
193*4882a593Smuzhiyun else {
194*4882a593Smuzhiyun newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER;
195*4882a593Smuzhiyun val = hb->buf[hb->rd];
196*4882a593Smuzhiyun hb->rd = newr;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun spin_unlock_irqrestore(&hb->lock, flags);
199*4882a593Smuzhiyun return val;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
203*4882a593Smuzhiyun
hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer * hb,unsigned short val)204*4882a593Smuzhiyun static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb,
205*4882a593Smuzhiyun unsigned short val)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun unsigned newp;
208*4882a593Smuzhiyun unsigned long flags;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun spin_lock_irqsave(&hb->lock, flags);
211*4882a593Smuzhiyun newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER;
212*4882a593Smuzhiyun if (newp != hb->rd) {
213*4882a593Smuzhiyun hb->buf[hb->wr] = val & 0xffff;
214*4882a593Smuzhiyun hb->wr = newp;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun spin_unlock_irqrestore(&hb->lock, flags);
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
220*4882a593Smuzhiyun
hdlcdrv_putbits(struct hdlcdrv_state * s,unsigned int bits)221*4882a593Smuzhiyun static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
hdlcdrv_getbits(struct hdlcdrv_state * s)226*4882a593Smuzhiyun static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun unsigned int ret;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) {
231*4882a593Smuzhiyun if (s->hdlctx.calibrate > 0)
232*4882a593Smuzhiyun s->hdlctx.calibrate--;
233*4882a593Smuzhiyun else
234*4882a593Smuzhiyun s->hdlctx.ptt = 0;
235*4882a593Smuzhiyun ret = 0;
236*4882a593Smuzhiyun } else
237*4882a593Smuzhiyun ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf);
238*4882a593Smuzhiyun #ifdef HDLCDRV_LOOPBACK
239*4882a593Smuzhiyun hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret);
240*4882a593Smuzhiyun #endif /* HDLCDRV_LOOPBACK */
241*4882a593Smuzhiyun return ret;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
hdlcdrv_channelbit(struct hdlcdrv_state * s,unsigned int bit)244*4882a593Smuzhiyun static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun #ifdef HDLCDRV_DEBUG
247*4882a593Smuzhiyun hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit);
248*4882a593Smuzhiyun #endif /* HDLCDRV_DEBUG */
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun
hdlcdrv_setdcd(struct hdlcdrv_state * s,int dcd)251*4882a593Smuzhiyun static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun s->hdlcrx.dcd = !!dcd;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
hdlcdrv_ptt(struct hdlcdrv_state * s)256*4882a593Smuzhiyun static inline int hdlcdrv_ptt(struct hdlcdrv_state *s)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun return s->hdlctx.ptt || (s->hdlctx.calibrate > 0);
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *);
264*4882a593Smuzhiyun void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *);
265*4882a593Smuzhiyun void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *);
266*4882a593Smuzhiyun struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
267*4882a593Smuzhiyun unsigned int privsize, const char *ifname,
268*4882a593Smuzhiyun unsigned int baseaddr, unsigned int irq,
269*4882a593Smuzhiyun unsigned int dma);
270*4882a593Smuzhiyun void hdlcdrv_unregister(struct net_device *dev);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* -------------------------------------------------------------------- */
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun #endif /* _HDLCDRV_H */
277