This source file includes following definitions.
- gigaset_isowbuf_init
- isowbuf_freebytes
- isowbuf_startwrite
- isowbuf_donewrite
- isowbuf_putbits
- isowbuf_putflag
- gigaset_isowbuf_getbytes
- dump_bytes
- hdlc_bitstuff_byte
- hdlc_buildframe
- trans_buildframe
- gigaset_isoc_buildframe
- hdlc_putbyte
- hdlc_flush
- hdlc_done
- hdlc_frag
- hdlc_unpack
- trans_receive
- gigaset_isoc_receive
- cmd_loop
- gigaset_isoc_input
- gigaset_isoc_send_skb
1
2
3
4
5
6
7
8
9
10
11
12 #include "gigaset.h"
13 #include <linux/crc-ccitt.h>
14 #include <linux/bitrev.h>
15
16
17
18
19
20
21 void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle)
22 {
23 iwb->read = 0;
24 iwb->nextread = 0;
25 iwb->write = 0;
26 atomic_set(&iwb->writesem, 1);
27 iwb->wbits = 0;
28 iwb->idle = idle;
29 memset(iwb->data + BAS_OUTBUFSIZE, idle, BAS_OUTBUFPAD);
30 }
31
32
33
34
35 static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
36 {
37 int read, write, freebytes;
38
39 read = iwb->read;
40 write = iwb->write;
41 freebytes = read - write;
42 if (freebytes > 0) {
43
44 return freebytes - BAS_OUTBUFPAD;
45 } else if (read < BAS_OUTBUFPAD) {
46
47 return BAS_OUTBUFSIZE - write;
48 } else {
49
50 return freebytes + BAS_OUTBUFSIZE - BAS_OUTBUFPAD;
51 }
52 }
53
54
55
56
57
58 static inline int isowbuf_startwrite(struct isowbuf_t *iwb)
59 {
60 if (!atomic_dec_and_test(&iwb->writesem)) {
61 atomic_inc(&iwb->writesem);
62 gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore",
63 __func__);
64 return -EBUSY;
65 }
66 gig_dbg(DEBUG_ISO,
67 "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d",
68 __func__, iwb->data[iwb->write], iwb->wbits);
69 return 0;
70 }
71
72
73
74
75
76 static inline int isowbuf_donewrite(struct isowbuf_t *iwb)
77 {
78 int write = iwb->write;
79 atomic_inc(&iwb->writesem);
80 return write;
81 }
82
83
84
85
86
87
88
89
90 static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits)
91 {
92 int write = iwb->write;
93 data <<= iwb->wbits;
94 data |= iwb->data[write];
95 nbits += iwb->wbits;
96 while (nbits >= 8) {
97 iwb->data[write++] = data & 0xff;
98 write %= BAS_OUTBUFSIZE;
99 data >>= 8;
100 nbits -= 8;
101 }
102 iwb->wbits = nbits;
103 iwb->data[write] = data & 0xff;
104 iwb->write = write;
105 }
106
107
108
109
110
111 static inline void isowbuf_putflag(struct isowbuf_t *iwb)
112 {
113 int write;
114
115
116 isowbuf_putbits(iwb, 0x7e7e, 8);
117
118 write = iwb->write;
119 iwb->idle = iwb->data[write];
120 gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle);
121
122 iwb->data[write] &= (1 << iwb->wbits) - 1;
123 }
124
125
126
127
128
129
130
131 int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
132 {
133 int read, write, limit, src, dst;
134 unsigned char pbyte;
135
136 read = iwb->nextread;
137 write = iwb->write;
138 if (likely(read == write)) {
139
140 return read < BAS_OUTBUFPAD ?
141 BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD;
142 }
143
144 limit = read + size;
145 gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d",
146 __func__, read, write, limit);
147 #ifdef CONFIG_GIGASET_DEBUG
148 if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) {
149 pr_err("invalid size %d\n", size);
150 return -EINVAL;
151 }
152 #endif
153
154 if (read < write) {
155
156 if (limit >= write) {
157
158 if (isowbuf_startwrite(iwb) < 0)
159 return -EBUSY;
160
161 write = iwb->write;
162 if (limit >= write) {
163 pbyte = iwb->data[write];
164
165 limit = write + BAS_OUTBUFPAD;
166 gig_dbg(DEBUG_STREAM,
167 "%s: filling %d->%d with %02x",
168 __func__, write, limit, iwb->idle);
169 if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE)
170 memset(iwb->data + write, iwb->idle,
171 BAS_OUTBUFPAD);
172 else {
173
174 memset(iwb->data + write, iwb->idle,
175 BAS_OUTBUFSIZE + BAS_OUTBUFPAD
176 - write);
177 limit = 0;
178 }
179 gig_dbg(DEBUG_STREAM,
180 "%s: restoring %02x at %d",
181 __func__, pbyte, limit);
182 iwb->data[limit] = pbyte;
183
184 iwb->write = limit;
185 }
186 isowbuf_donewrite(iwb);
187 }
188 } else {
189
190 if (limit >= BAS_OUTBUFSIZE) {
191
192 src = 0;
193 dst = BAS_OUTBUFSIZE;
194 while (dst < limit && src < write)
195 iwb->data[dst++] = iwb->data[src++];
196 if (dst <= limit) {
197
198 memset(iwb->data + dst, iwb->idle,
199 BAS_OUTBUFSIZE + BAS_OUTBUFPAD - dst);
200 }
201 limit = src;
202 }
203 }
204 iwb->nextread = limit;
205 return read;
206 }
207
208
209
210
211 static inline void dump_bytes(enum debuglevel level, const char *tag,
212 unsigned char *bytes, int count)
213 {
214 #ifdef CONFIG_GIGASET_DEBUG
215 unsigned char c;
216 static char dbgline[3 * 32 + 1];
217 int i = 0;
218
219 if (!(gigaset_debuglevel & level))
220 return;
221
222 while (count-- > 0) {
223 if (i > sizeof(dbgline) - 4) {
224 dbgline[i] = '\0';
225 gig_dbg(level, "%s:%s", tag, dbgline);
226 i = 0;
227 }
228 c = *bytes++;
229 dbgline[i] = (i && !(i % 12)) ? '-' : ' ';
230 i++;
231 dbgline[i++] = hex_asc_hi(c);
232 dbgline[i++] = hex_asc_lo(c);
233 }
234 dbgline[i] = '\0';
235 gig_dbg(level, "%s:%s", tag, dbgline);
236 #endif
237 }
238
239
240
241
242
243
244
245
246
247
248 static const u16 stufftab[5 * 256] = {
249
250 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
251 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
252 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
253 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f,
254 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
255 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f,
256 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
257 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df,
258 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
259 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f,
260 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
261 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f,
262 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf,
263 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f,
264 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
265 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
266
267
268 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
269 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
270 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
271 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f,
272 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f,
273 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af,
274 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf,
275 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef,
276 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f,
277 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f,
278 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f,
279 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f,
280 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f,
281 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af,
282 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
283 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
284
285
286 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
287 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
288 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
289 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077,
290 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097,
291 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7,
292 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7,
293 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7,
294 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517,
295 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537,
296 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557,
297 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577,
298 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997,
299 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7,
300 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
301 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
302
303
304 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
305 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
306 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
307 0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b,
308 0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b,
309 0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb,
310 0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db,
311 0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb,
312 0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b,
313 0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b,
314 0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b,
315 0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b,
316 0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b,
317 0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb,
318 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
319 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
320
321
322 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
323 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
324 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
325 0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d,
326 0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d,
327 0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd,
328 0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd,
329 0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d,
330 0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d,
331 0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d,
332 0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d,
333 0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d,
334 0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d,
335 0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd,
336 0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd,
337 0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d
338 };
339
340
341
342
343
344
345
346
347
348
349
350
351 static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin,
352 int ones)
353 {
354 u16 stuff;
355 int shiftinc, newones;
356
357
358
359
360
361
362 stuff = stufftab[256 * ones + cin];
363 shiftinc = (stuff >> 13) & 3;
364 newones = (stuff >> 10) & 7;
365 stuff &= 0x3ff;
366
367
368 isowbuf_putbits(iwb, stuff, 8 + shiftinc);
369 return newones;
370 }
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 static inline int hdlc_buildframe(struct isowbuf_t *iwb,
395 unsigned char *in, int count)
396 {
397 int ones;
398 u16 fcs;
399 int end;
400 unsigned char c;
401
402 if (isowbuf_freebytes(iwb) < count + count / 5 + 6 ||
403 isowbuf_startwrite(iwb) < 0) {
404 gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN",
405 __func__, isowbuf_freebytes(iwb));
406 return -EAGAIN;
407 }
408
409 dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
410
411
412 fcs = PPP_INITFCS;
413 ones = 0;
414 while (count-- > 0) {
415 c = *in++;
416 ones = hdlc_bitstuff_byte(iwb, c, ones);
417 fcs = crc_ccitt_byte(fcs, c);
418 }
419
420
421
422 fcs ^= 0xffff;
423 ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);
424 ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);
425
426
427 isowbuf_putflag(iwb);
428 end = isowbuf_donewrite(iwb);
429 return end;
430 }
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447 static inline int trans_buildframe(struct isowbuf_t *iwb,
448 unsigned char *in, int count)
449 {
450 int write;
451 unsigned char c;
452
453 if (unlikely(count <= 0))
454 return iwb->write;
455
456 if (isowbuf_freebytes(iwb) < count ||
457 isowbuf_startwrite(iwb) < 0) {
458 gig_dbg(DEBUG_ISO, "can't put %d bytes", count);
459 return -EAGAIN;
460 }
461
462 gig_dbg(DEBUG_STREAM, "put %d bytes", count);
463 dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
464
465 write = iwb->write;
466 do {
467 c = bitrev8(*in++);
468 iwb->data[write++] = c;
469 write %= BAS_OUTBUFSIZE;
470 } while (--count > 0);
471 iwb->write = write;
472 iwb->idle = c;
473
474 return isowbuf_donewrite(iwb);
475 }
476
477 int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len)
478 {
479 int result;
480
481 switch (bcs->proto2) {
482 case L2_HDLC:
483 result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);
484 gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",
485 __func__, len, result);
486 break;
487 default:
488 result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len);
489 gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d",
490 __func__, len, result);
491 }
492 return result;
493 }
494
495
496
497
498 static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs)
499 {
500 bcs->rx_fcs = crc_ccitt_byte(bcs->rx_fcs, c);
501 if (bcs->rx_skb == NULL)
502
503 return;
504 if (bcs->rx_skb->len >= bcs->rx_bufsize) {
505 dev_warn(bcs->cs->dev, "received oversized packet discarded\n");
506 bcs->hw.bas->giants++;
507 dev_kfree_skb_any(bcs->rx_skb);
508 bcs->rx_skb = NULL;
509 return;
510 }
511 __skb_put_u8(bcs->rx_skb, c);
512 }
513
514
515
516
517 static inline void hdlc_flush(struct bc_state *bcs)
518 {
519
520 if (bcs->rx_skb != NULL)
521 skb_trim(bcs->rx_skb, 0);
522 else
523 gigaset_new_rx_skb(bcs);
524
525
526 bcs->rx_fcs = PPP_INITFCS;
527 }
528
529
530
531
532 static inline void hdlc_done(struct bc_state *bcs)
533 {
534 struct cardstate *cs = bcs->cs;
535 struct sk_buff *procskb;
536 unsigned int len;
537
538 if (unlikely(bcs->ignore)) {
539 bcs->ignore--;
540 hdlc_flush(bcs);
541 return;
542 }
543 procskb = bcs->rx_skb;
544 if (procskb == NULL) {
545
546 gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
547 gigaset_isdn_rcv_err(bcs);
548 } else if (procskb->len < 2) {
549 dev_notice(cs->dev, "received short frame (%d octets)\n",
550 procskb->len);
551 bcs->hw.bas->runts++;
552 dev_kfree_skb_any(procskb);
553 gigaset_isdn_rcv_err(bcs);
554 } else if (bcs->rx_fcs != PPP_GOODFCS) {
555 dev_notice(cs->dev, "frame check error\n");
556 bcs->hw.bas->fcserrs++;
557 dev_kfree_skb_any(procskb);
558 gigaset_isdn_rcv_err(bcs);
559 } else {
560 len = procskb->len;
561 __skb_trim(procskb, len -= 2);
562 gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", __func__, len);
563 dump_bytes(DEBUG_STREAM_DUMP,
564 "rcv data", procskb->data, len);
565 bcs->hw.bas->goodbytes += len;
566 gigaset_skb_rcvd(bcs, procskb);
567 }
568 gigaset_new_rx_skb(bcs);
569 bcs->rx_fcs = PPP_INITFCS;
570 }
571
572
573
574
575 static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
576 {
577 if (unlikely(bcs->ignore)) {
578 bcs->ignore--;
579 hdlc_flush(bcs);
580 return;
581 }
582
583 dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
584 bcs->hw.bas->alignerrs++;
585 gigaset_isdn_rcv_err(bcs);
586 __skb_trim(bcs->rx_skb, 0);
587 bcs->rx_fcs = PPP_INITFCS;
588 }
589
590
591
592
593
594
595
596
597 static const unsigned char bitcounts[256] = {
598 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
599 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
600 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
601 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,
602 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
603 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
604 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
605 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,
606 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
607 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,
608 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
609 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,
610 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,
611 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,
612 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,
613 0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78
614 };
615
616
617
618
619
620
621
622
623
624
625
626
627 static inline void hdlc_unpack(unsigned char *src, unsigned count,
628 struct bc_state *bcs)
629 {
630 struct bas_bc_state *ubc = bcs->hw.bas;
631 int inputstate;
632 unsigned seqlen, inbyte, inbits;
633
634
635
636
637
638
639
640
641
642
643
644
645 inputstate = bcs->inputstate;
646 seqlen = ubc->seqlen;
647 inbyte = ubc->inbyte;
648 inbits = ubc->inbits;
649
650
651
652
653
654
655 while (count--) {
656 unsigned char c = *src++;
657 unsigned char tabentry = bitcounts[c];
658 unsigned lead1 = tabentry & 0x0f;
659 unsigned trail1 = (tabentry >> 4) & 0x0f;
660
661 seqlen += lead1;
662
663 if (unlikely(inputstate & INS_flag_hunt)) {
664 if (c == PPP_FLAG) {
665
666 inputstate &= ~(INS_flag_hunt | INS_have_data);
667 inbyte = 0;
668 inbits = 0;
669 } else if (seqlen == 6 && trail1 != 7) {
670
671 inputstate &= ~(INS_flag_hunt | INS_have_data);
672 inbyte = c >> (lead1 + 1);
673 inbits = 7 - lead1;
674 if (trail1 >= 8) {
675
676
677
678
679 inbits--;
680 switch (c) {
681 case 0xbe:
682 inbyte = 0x3f;
683 break;
684 }
685 }
686 }
687
688 } else if (likely(seqlen < 5 && trail1 < 7)) {
689
690 inbyte |= c << inbits;
691 hdlc_putbyte(inbyte & 0xff, bcs);
692 inputstate |= INS_have_data;
693 inbyte >>= 8;
694
695 } else if (likely(seqlen == 6 && inbits == 7 - lead1 &&
696 trail1 + 1 == inbits &&
697 !(inputstate & INS_have_data))) {
698
699 } else if (unlikely(seqlen > 6)) {
700
701 ubc->aborts++;
702 hdlc_flush(bcs);
703 inputstate |= INS_flag_hunt;
704 } else if (seqlen == 6) {
705
706
707 if (inbits > 7 - lead1) {
708 hdlc_frag(bcs, inbits + lead1 - 7);
709 inputstate &= ~INS_have_data;
710 } else {
711 if (inbits < 7 - lead1)
712 ubc->stolen0s++;
713 if (inputstate & INS_have_data) {
714 hdlc_done(bcs);
715 inputstate &= ~INS_have_data;
716 }
717 }
718
719 if (c == PPP_FLAG) {
720
721 ubc->shared0s++;
722 inbits = 0;
723 inbyte = 0;
724 } else if (trail1 != 7) {
725
726 inbyte = c >> (lead1 + 1);
727 inbits = 7 - lead1;
728 if (trail1 >= 8) {
729
730
731
732
733 inbits--;
734 switch (c) {
735 case 0xbe:
736 inbyte = 0x3f;
737 break;
738 }
739 }
740 } else {
741
742
743 ubc->aborts++;
744 inputstate |= INS_flag_hunt;
745 }
746 } else {
747
748 if (c == PPP_FLAG) {
749
750 if (seqlen == 5)
751 ubc->stolen0s++;
752 if (inbits) {
753 hdlc_frag(bcs, inbits);
754 inbits = 0;
755 inbyte = 0;
756 } else if (inputstate & INS_have_data)
757 hdlc_done(bcs);
758 inputstate &= ~INS_have_data;
759 } else if (trail1 == 7) {
760
761 ubc->aborts++;
762 hdlc_flush(bcs);
763 inputstate |= INS_flag_hunt;
764 } else {
765
766 if (trail1 < 7) {
767
768
769 unsigned char mask = (1 << lead1) - 1;
770 c = (c & mask) | ((c & ~mask) >> 1);
771 inbyte |= c << inbits;
772 inbits += 7;
773 } else if (seqlen < 5) {
774
775
776
777
778 switch (c) {
779 case 0xbe:
780 c = 0x7e;
781 break;
782 }
783 inbyte |= c << inbits;
784 inbits += 7;
785 } else {
786
787
788
789 switch (c) {
790 case 0x7d:
791 c = 0x3f;
792 break;
793 case 0xbe:
794 c = 0x3f;
795 break;
796 case 0x3e:
797 c = 0x1f;
798 break;
799 case 0x7c:
800 c = 0x3e;
801 break;
802 }
803 inbyte |= c << inbits;
804 inbits += 6;
805 }
806 if (inbits >= 8) {
807 inbits -= 8;
808 hdlc_putbyte(inbyte & 0xff, bcs);
809 inputstate |= INS_have_data;
810 inbyte >>= 8;
811 }
812 }
813 }
814 seqlen = trail1 & 7;
815 }
816
817
818 bcs->inputstate = inputstate;
819 ubc->seqlen = seqlen;
820 ubc->inbyte = inbyte;
821 ubc->inbits = inbits;
822 }
823
824
825
826
827
828
829
830
831
832
833 static inline void trans_receive(unsigned char *src, unsigned count,
834 struct bc_state *bcs)
835 {
836 struct sk_buff *skb;
837 int dobytes;
838 unsigned char *dst;
839
840 if (unlikely(bcs->ignore)) {
841 bcs->ignore--;
842 return;
843 }
844 skb = bcs->rx_skb;
845 if (skb == NULL) {
846 skb = gigaset_new_rx_skb(bcs);
847 if (skb == NULL)
848 return;
849 }
850 dobytes = bcs->rx_bufsize - skb->len;
851 while (count > 0) {
852 dst = skb_put(skb, count < dobytes ? count : dobytes);
853 while (count > 0 && dobytes > 0) {
854 *dst++ = bitrev8(*src++);
855 count--;
856 dobytes--;
857 }
858 if (dobytes == 0) {
859 dump_bytes(DEBUG_STREAM_DUMP,
860 "rcv data", skb->data, skb->len);
861 bcs->hw.bas->goodbytes += skb->len;
862 gigaset_skb_rcvd(bcs, skb);
863 skb = gigaset_new_rx_skb(bcs);
864 if (skb == NULL)
865 return;
866 dobytes = bcs->rx_bufsize;
867 }
868 }
869 }
870
871 void gigaset_isoc_receive(unsigned char *src, unsigned count,
872 struct bc_state *bcs)
873 {
874 switch (bcs->proto2) {
875 case L2_HDLC:
876 hdlc_unpack(src, count, bcs);
877 break;
878 default:
879 trans_receive(src, count, bcs);
880 }
881 }
882
883
884
885
886
887
888
889
890
891 static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
892 {
893 struct cardstate *cs = inbuf->cs;
894 unsigned cbytes = cs->cbytes;
895 unsigned char c;
896
897 while (numbytes--) {
898 c = *src++;
899 switch (c) {
900 case '\n':
901 if (cbytes == 0 && cs->respdata[0] == '\r') {
902
903 cs->respdata[0] = 0;
904 break;
905 }
906
907 case '\r':
908
909 if (cbytes >= MAX_RESP_SIZE) {
910 dev_warn(cs->dev, "response too large (%d)\n",
911 cbytes);
912 cbytes = MAX_RESP_SIZE;
913 }
914 cs->cbytes = cbytes;
915 gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
916 cbytes, cs->respdata);
917 gigaset_handle_modem_response(cs);
918 cbytes = 0;
919
920
921 cs->respdata[0] = c;
922 break;
923 default:
924
925 if (cbytes < MAX_RESP_SIZE)
926 cs->respdata[cbytes] = c;
927 cbytes++;
928 }
929 }
930
931
932 cs->cbytes = cbytes;
933 }
934
935
936
937
938 void gigaset_isoc_input(struct inbuf_t *inbuf)
939 {
940 struct cardstate *cs = inbuf->cs;
941 unsigned tail, head, numbytes;
942 unsigned char *src;
943
944 head = inbuf->head;
945 while (head != (tail = inbuf->tail)) {
946 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
947 if (head > tail)
948 tail = RBUFSIZE;
949 src = inbuf->data + head;
950 numbytes = tail - head;
951 gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
952
953 if (cs->mstate == MS_LOCKED) {
954 gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
955 numbytes, src);
956 gigaset_if_receive(inbuf->cs, src, numbytes);
957 } else {
958 cmd_loop(src, numbytes, inbuf);
959 }
960
961 head += numbytes;
962 if (head == RBUFSIZE)
963 head = 0;
964 gig_dbg(DEBUG_INTR, "setting head to %u", head);
965 inbuf->head = head;
966 }
967 }
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986 int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
987 {
988 int len = skb->len;
989 unsigned long flags;
990
991 spin_lock_irqsave(&bcs->cs->lock, flags);
992 if (!bcs->cs->connected) {
993 spin_unlock_irqrestore(&bcs->cs->lock, flags);
994 return -ENODEV;
995 }
996
997 skb_queue_tail(&bcs->squeue, skb);
998 gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
999 __func__, skb_queue_len(&bcs->squeue));
1000
1001
1002 tasklet_schedule(&bcs->hw.bas->sent_tasklet);
1003 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1004
1005 return len;
1006 }