1
2
3
4
5
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
18#define HDLCDRV_BITBUFFER 256
19#undef HDLCDRV_LOOPBACK
20#define HDLCDRV_DEBUG
21
22
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
65
66
67
68
69
70
71struct hdlcdrv_ops {
72
73
74
75 const char *drvname;
76 const char *drvinfo;
77
78
79
80 int (*open)(struct net_device *);
81 int (*close)(struct net_device *);
82 int (*ioctl)(struct net_device *, struct ifreq *,
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
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
126
127
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
148
149 int ptt_keyed;
150
151
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
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
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
277