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