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 | |
26 | struct hdlcdrv_hdlcbuffer { |
27 | spinlock_t lock; |
28 | unsigned rd, wr; |
29 | unsigned short buf[HDLCDRV_HDLCBUFFER]; |
30 | }; |
31 | |
32 | #ifdef HDLCDRV_DEBUG |
33 | struct hdlcdrv_bitbuffer { |
34 | unsigned int rd; |
35 | unsigned int wr; |
36 | unsigned int shreg; |
37 | unsigned char buffer[HDLCDRV_BITBUFFER]; |
38 | }; |
39 | |
40 | static 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 | |
55 | static 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 | |
71 | struct 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 | |
86 | struct 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 | |
158 | static 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(lock: &hb->lock, flags); |
166 | return ret; |
167 | } |
168 | |
169 | /* -------------------------------------------------------------------- */ |
170 | |
171 | static 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(lock: &hb->lock, flags); |
179 | return ret; |
180 | } |
181 | |
182 | /* -------------------------------------------------------------------- */ |
183 | |
184 | static 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(lock: &hb->lock, flags); |
199 | return val; |
200 | } |
201 | |
202 | /* -------------------------------------------------------------------- */ |
203 | |
204 | static 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(lock: &hb->lock, flags); |
217 | } |
218 | |
219 | /* -------------------------------------------------------------------- */ |
220 | |
221 | static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits) |
222 | { |
223 | hdlcdrv_hbuf_put(hb: &s->hdlcrx.hbuf, val: bits); |
224 | } |
225 | |
226 | static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s) |
227 | { |
228 | unsigned int ret; |
229 | |
230 | if (hdlcdrv_hbuf_empty(hb: &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(hb: &s->hdlctx.hbuf); |
238 | #ifdef HDLCDRV_LOOPBACK |
239 | hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret); |
240 | #endif /* HDLCDRV_LOOPBACK */ |
241 | return ret; |
242 | } |
243 | |
244 | static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit) |
245 | { |
246 | #ifdef HDLCDRV_DEBUG |
247 | hdlcdrv_add_bitbuffer(buf: &s->bitbuf_channel, bit); |
248 | #endif /* HDLCDRV_DEBUG */ |
249 | } |
250 | |
251 | static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd) |
252 | { |
253 | s->hdlcrx.dcd = !!dcd; |
254 | } |
255 | |
256 | static inline int hdlcdrv_ptt(struct hdlcdrv_state *s) |
257 | { |
258 | return s->hdlctx.ptt || (s->hdlctx.calibrate > 0); |
259 | } |
260 | |
261 | /* -------------------------------------------------------------------- */ |
262 | |
263 | void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *); |
264 | void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *); |
265 | void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *); |
266 | struct 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); |
270 | void hdlcdrv_unregister(struct net_device *dev); |
271 | |
272 | /* -------------------------------------------------------------------- */ |
273 | |
274 | |
275 | |
276 | #endif /* _HDLCDRV_H */ |
277 | |