xref: /OK3568_Linux_fs/kernel/include/linux/hdlcdrv.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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