isocdata.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. /*
  2. * Common data handling layer for bas_gigaset
  3. *
  4. * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
  5. * Hansjoerg Lipp <hjlipp@web.de>.
  6. *
  7. * =====================================================================
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. * =====================================================================
  13. */
  14. #include "gigaset.h"
  15. #include <linux/crc-ccitt.h>
  16. #include <linux/bitrev.h>
  17. /* access methods for isowbuf_t */
  18. /* ============================ */
  19. /* initialize buffer structure
  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. /* compute number of bytes which can be appended to buffer
  32. * so that there is still room to append a maximum frame of flags
  33. */
  34. static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
  35. {
  36. int read, write, freebytes;
  37. read = iwb->read;
  38. write = iwb->write;
  39. if ((freebytes = read - write) > 0) {
  40. /* no wraparound: need padding space within regular area */
  41. return freebytes - BAS_OUTBUFPAD;
  42. } else if (read < BAS_OUTBUFPAD) {
  43. /* wraparound: can use space up to end of regular area */
  44. return BAS_OUTBUFSIZE - write;
  45. } else {
  46. /* following the wraparound yields more space */
  47. return freebytes + BAS_OUTBUFSIZE - BAS_OUTBUFPAD;
  48. }
  49. }
  50. /* compare two offsets within the buffer
  51. * The buffer is seen as circular, with the read position as start
  52. * returns -1/0/1 if position a </=/> position b without crossing 'read'
  53. */
  54. static inline int isowbuf_poscmp(struct isowbuf_t *iwb, int a, int b)
  55. {
  56. int read;
  57. if (a == b)
  58. return 0;
  59. read = iwb->read;
  60. if (a < b) {
  61. if (a < read && read <= b)
  62. return +1;
  63. else
  64. return -1;
  65. } else {
  66. if (b < read && read <= a)
  67. return -1;
  68. else
  69. return +1;
  70. }
  71. }
  72. /* start writing
  73. * acquire the write semaphore
  74. * return true if acquired, false if busy
  75. */
  76. static inline int isowbuf_startwrite(struct isowbuf_t *iwb)
  77. {
  78. if (!atomic_dec_and_test(&iwb->writesem)) {
  79. atomic_inc(&iwb->writesem);
  80. gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore",
  81. __func__);
  82. return 0;
  83. }
  84. gig_dbg(DEBUG_ISO,
  85. "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d",
  86. __func__, iwb->data[iwb->write], iwb->wbits);
  87. return 1;
  88. }
  89. /* finish writing
  90. * release the write semaphore
  91. * returns the current write position
  92. */
  93. static inline int isowbuf_donewrite(struct isowbuf_t *iwb)
  94. {
  95. int write = iwb->write;
  96. atomic_inc(&iwb->writesem);
  97. return write;
  98. }
  99. /* append bits to buffer without any checks
  100. * - data contains bits to append, starting at LSB
  101. * - nbits is number of bits to append (0..24)
  102. * must be called with the write semaphore held
  103. * If more than nbits bits are set in data, the extraneous bits are set in the
  104. * buffer too, but the write position is only advanced by nbits.
  105. */
  106. static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits)
  107. {
  108. int write = iwb->write;
  109. data <<= iwb->wbits;
  110. data |= iwb->data[write];
  111. nbits += iwb->wbits;
  112. while (nbits >= 8) {
  113. iwb->data[write++] = data & 0xff;
  114. write %= BAS_OUTBUFSIZE;
  115. data >>= 8;
  116. nbits -= 8;
  117. }
  118. iwb->wbits = nbits;
  119. iwb->data[write] = data & 0xff;
  120. iwb->write = write;
  121. }
  122. /* put final flag on HDLC bitstream
  123. * also sets the idle fill byte to the correspondingly shifted flag pattern
  124. * must be called with the write semaphore held
  125. */
  126. static inline void isowbuf_putflag(struct isowbuf_t *iwb)
  127. {
  128. int write;
  129. /* add two flags, thus reliably covering one byte */
  130. isowbuf_putbits(iwb, 0x7e7e, 8);
  131. /* recover the idle flag byte */
  132. write = iwb->write;
  133. iwb->idle = iwb->data[write];
  134. gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle);
  135. /* mask extraneous bits in buffer */
  136. iwb->data[write] &= (1 << iwb->wbits) - 1;
  137. }
  138. /* retrieve a block of bytes for sending
  139. * The requested number of bytes is provided as a contiguous block.
  140. * If necessary, the frame is filled to the requested number of bytes
  141. * with the idle value.
  142. * returns offset to frame, < 0 on busy or error
  143. */
  144. int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
  145. {
  146. int read, write, limit, src, dst;
  147. unsigned char pbyte;
  148. read = iwb->nextread;
  149. write = iwb->write;
  150. if (likely(read == write)) {
  151. /* return idle frame */
  152. return read < BAS_OUTBUFPAD ?
  153. BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD;
  154. }
  155. limit = read + size;
  156. gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d",
  157. __func__, read, write, limit);
  158. #ifdef CONFIG_GIGASET_DEBUG
  159. if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) {
  160. pr_err("invalid size %d\n", size);
  161. return -EINVAL;
  162. }
  163. #endif
  164. if (read < write) {
  165. /* no wraparound in valid data */
  166. if (limit >= write) {
  167. /* append idle frame */
  168. if (!isowbuf_startwrite(iwb))
  169. return -EBUSY;
  170. /* write position could have changed */
  171. write = iwb->write;
  172. if (limit >= write) {
  173. pbyte = iwb->data[write]; /* save
  174. partial byte */
  175. limit = write + BAS_OUTBUFPAD;
  176. gig_dbg(DEBUG_STREAM,
  177. "%s: filling %d->%d with %02x",
  178. __func__, write, limit, iwb->idle);
  179. if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE)
  180. memset(iwb->data + write, iwb->idle,
  181. BAS_OUTBUFPAD);
  182. else {
  183. /* wraparound, fill entire pad area */
  184. memset(iwb->data + write, iwb->idle,
  185. BAS_OUTBUFSIZE + BAS_OUTBUFPAD
  186. - write);
  187. limit = 0;
  188. }
  189. gig_dbg(DEBUG_STREAM,
  190. "%s: restoring %02x at %d",
  191. __func__, pbyte, limit);
  192. iwb->data[limit] = pbyte; /* restore
  193. partial byte */
  194. iwb->write = limit;
  195. }
  196. isowbuf_donewrite(iwb);
  197. }
  198. } else {
  199. /* valid data wraparound */
  200. if (limit >= BAS_OUTBUFSIZE) {
  201. /* copy wrapped part into pad area */
  202. src = 0;
  203. dst = BAS_OUTBUFSIZE;
  204. while (dst < limit && src < write)
  205. iwb->data[dst++] = iwb->data[src++];
  206. if (dst <= limit) {
  207. /* fill pad area with idle byte */
  208. memset(iwb->data + dst, iwb->idle,
  209. BAS_OUTBUFSIZE + BAS_OUTBUFPAD - dst);
  210. }
  211. limit = src;
  212. }
  213. }
  214. iwb->nextread = limit;
  215. return read;
  216. }
  217. /* dump_bytes
  218. * write hex bytes to syslog for debugging
  219. */
  220. static inline void dump_bytes(enum debuglevel level, const char *tag,
  221. unsigned char *bytes, int count)
  222. {
  223. #ifdef CONFIG_GIGASET_DEBUG
  224. unsigned char c;
  225. static char dbgline[3 * 32 + 1];
  226. int i = 0;
  227. if (!(gigaset_debuglevel & level))
  228. return;
  229. while (count-- > 0) {
  230. if (i > sizeof(dbgline) - 4) {
  231. dbgline[i] = '\0';
  232. gig_dbg(level, "%s:%s", tag, dbgline);
  233. i = 0;
  234. }
  235. c = *bytes++;
  236. dbgline[i] = (i && !(i % 12)) ? '-' : ' ';
  237. i++;
  238. dbgline[i++] = hex_asc_hi(c);
  239. dbgline[i++] = hex_asc_lo(c);
  240. }
  241. dbgline[i] = '\0';
  242. gig_dbg(level, "%s:%s", tag, dbgline);
  243. #endif
  244. }
  245. /*============================================================================*/
  246. /* bytewise HDLC bitstuffing via table lookup
  247. * lookup table: 5 subtables for 0..4 preceding consecutive '1' bits
  248. * index: 256*(number of preceding '1' bits) + (next byte to stuff)
  249. * value: bit 9.. 0 = result bits
  250. * bit 12..10 = number of trailing '1' bits in result
  251. * bit 14..13 = number of bits added by stuffing
  252. */
  253. static const u16 stufftab[5 * 256] = {
  254. // previous 1s = 0:
  255. 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
  256. 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
  257. 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
  258. 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f,
  259. 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
  260. 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f,
  261. 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
  262. 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df,
  263. 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
  264. 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f,
  265. 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
  266. 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f,
  267. 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf,
  268. 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f,
  269. 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
  270. 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
  271. // previous 1s = 1:
  272. 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
  273. 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
  274. 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
  275. 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f,
  276. 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f,
  277. 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af,
  278. 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf,
  279. 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef,
  280. 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f,
  281. 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f,
  282. 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f,
  283. 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f,
  284. 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f,
  285. 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af,
  286. 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
  287. 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
  288. // previous 1s = 2:
  289. 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
  290. 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
  291. 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
  292. 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077,
  293. 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097,
  294. 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7,
  295. 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7,
  296. 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7,
  297. 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517,
  298. 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537,
  299. 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557,
  300. 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577,
  301. 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997,
  302. 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7,
  303. 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
  304. 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
  305. // previous 1s = 3:
  306. 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
  307. 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
  308. 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
  309. 0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b,
  310. 0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b,
  311. 0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb,
  312. 0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db,
  313. 0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb,
  314. 0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b,
  315. 0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b,
  316. 0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b,
  317. 0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b,
  318. 0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b,
  319. 0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb,
  320. 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
  321. 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
  322. // previous 1s = 4:
  323. 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
  324. 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
  325. 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
  326. 0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d,
  327. 0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d,
  328. 0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd,
  329. 0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd,
  330. 0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d,
  331. 0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d,
  332. 0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d,
  333. 0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d,
  334. 0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d,
  335. 0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d,
  336. 0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd,
  337. 0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd,
  338. 0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d
  339. };
  340. /* hdlc_bitstuff_byte
  341. * perform HDLC bitstuffing for one input byte (8 bits, LSB first)
  342. * parameters:
  343. * cin input byte
  344. * ones number of trailing '1' bits in result before this step
  345. * iwb pointer to output buffer structure (write semaphore must be held)
  346. * return value:
  347. * number of trailing '1' bits in result after this step
  348. */
  349. static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin,
  350. int ones)
  351. {
  352. u16 stuff;
  353. int shiftinc, newones;
  354. /* get stuffing information for input byte
  355. * value: bit 9.. 0 = result bits
  356. * bit 12..10 = number of trailing '1' bits in result
  357. * bit 14..13 = number of bits added by stuffing
  358. */
  359. stuff = stufftab[256 * ones + cin];
  360. shiftinc = (stuff >> 13) & 3;
  361. newones = (stuff >> 10) & 7;
  362. stuff &= 0x3ff;
  363. /* append stuffed byte to output stream */
  364. isowbuf_putbits(iwb, stuff, 8 + shiftinc);
  365. return newones;
  366. }
  367. /* hdlc_buildframe
  368. * Perform HDLC framing with bitstuffing on a byte buffer
  369. * The input buffer is regarded as a sequence of bits, starting with the least
  370. * significant bit of the first byte and ending with the most significant bit
  371. * of the last byte. A 16 bit FCS is appended as defined by RFC 1662.
  372. * Whenever five consecutive '1' bits appear in the resulting bit sequence, a
  373. * '0' bit is inserted after them.
  374. * The resulting bit string and a closing flag pattern (PPP_FLAG, '01111110')
  375. * are appended to the output buffer starting at the given bit position, which
  376. * is assumed to already contain a leading flag.
  377. * The output buffer must have sufficient length; count + count/5 + 6 bytes
  378. * starting at *out are safe and are verified to be present.
  379. * parameters:
  380. * in input buffer
  381. * count number of bytes in input buffer
  382. * iwb pointer to output buffer structure (write semaphore must be held)
  383. * return value:
  384. * position of end of packet in output buffer on success,
  385. * -EAGAIN if write semaphore busy or buffer full
  386. */
  387. static inline int hdlc_buildframe(struct isowbuf_t *iwb,
  388. unsigned char *in, int count)
  389. {
  390. int ones;
  391. u16 fcs;
  392. int end;
  393. unsigned char c;
  394. if (isowbuf_freebytes(iwb) < count + count / 5 + 6 ||
  395. !isowbuf_startwrite(iwb)) {
  396. gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN",
  397. __func__, isowbuf_freebytes(iwb));
  398. return -EAGAIN;
  399. }
  400. dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
  401. /* bitstuff and checksum input data */
  402. fcs = PPP_INITFCS;
  403. ones = 0;
  404. while (count-- > 0) {
  405. c = *in++;
  406. ones = hdlc_bitstuff_byte(iwb, c, ones);
  407. fcs = crc_ccitt_byte(fcs, c);
  408. }
  409. /* bitstuff and append FCS (complemented, least significant byte first) */
  410. fcs ^= 0xffff;
  411. ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);
  412. ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);
  413. /* put closing flag and repeat byte for flag idle */
  414. isowbuf_putflag(iwb);
  415. end = isowbuf_donewrite(iwb);
  416. return end;
  417. }
  418. /* trans_buildframe
  419. * Append a block of 'transparent' data to the output buffer,
  420. * inverting the bytes.
  421. * The output buffer must have sufficient length; count bytes
  422. * starting at *out are safe and are verified to be present.
  423. * parameters:
  424. * in input buffer
  425. * count number of bytes in input buffer
  426. * iwb pointer to output buffer structure (write semaphore must be held)
  427. * return value:
  428. * position of end of packet in output buffer on success,
  429. * -EAGAIN if write semaphore busy or buffer full
  430. */
  431. static inline int trans_buildframe(struct isowbuf_t *iwb,
  432. unsigned char *in, int count)
  433. {
  434. int write;
  435. unsigned char c;
  436. if (unlikely(count <= 0))
  437. return iwb->write;
  438. if (isowbuf_freebytes(iwb) < count ||
  439. !isowbuf_startwrite(iwb)) {
  440. gig_dbg(DEBUG_ISO, "can't put %d bytes", count);
  441. return -EAGAIN;
  442. }
  443. gig_dbg(DEBUG_STREAM, "put %d bytes", count);
  444. dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
  445. write = iwb->write;
  446. do {
  447. c = bitrev8(*in++);
  448. iwb->data[write++] = c;
  449. write %= BAS_OUTBUFSIZE;
  450. } while (--count > 0);
  451. iwb->write = write;
  452. iwb->idle = c;
  453. return isowbuf_donewrite(iwb);
  454. }
  455. int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len)
  456. {
  457. int result;
  458. switch (bcs->proto2) {
  459. case ISDN_PROTO_L2_HDLC:
  460. result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);
  461. gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",
  462. __func__, len, result);
  463. break;
  464. default: /* assume transparent */
  465. result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len);
  466. gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d",
  467. __func__, len, result);
  468. }
  469. return result;
  470. }
  471. /* hdlc_putbyte
  472. * append byte c to current skb of B channel structure *bcs, updating fcs
  473. */
  474. static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs)
  475. {
  476. bcs->fcs = crc_ccitt_byte(bcs->fcs, c);
  477. if (unlikely(bcs->skb == NULL)) {
  478. /* skipping */
  479. return;
  480. }
  481. if (unlikely(bcs->skb->len == SBUFSIZE)) {
  482. dev_warn(bcs->cs->dev, "received oversized packet discarded\n");
  483. bcs->hw.bas->giants++;
  484. dev_kfree_skb_any(bcs->skb);
  485. bcs->skb = NULL;
  486. return;
  487. }
  488. *__skb_put(bcs->skb, 1) = c;
  489. }
  490. /* hdlc_flush
  491. * drop partial HDLC data packet
  492. */
  493. static inline void hdlc_flush(struct bc_state *bcs)
  494. {
  495. /* clear skb or allocate new if not skipping */
  496. if (likely(bcs->skb != NULL))
  497. skb_trim(bcs->skb, 0);
  498. else if (!bcs->ignore) {
  499. if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
  500. skb_reserve(bcs->skb, HW_HDR_LEN);
  501. else
  502. dev_err(bcs->cs->dev, "could not allocate skb\n");
  503. }
  504. /* reset packet state */
  505. bcs->fcs = PPP_INITFCS;
  506. }
  507. /* hdlc_done
  508. * process completed HDLC data packet
  509. */
  510. static inline void hdlc_done(struct bc_state *bcs)
  511. {
  512. struct sk_buff *procskb;
  513. if (unlikely(bcs->ignore)) {
  514. bcs->ignore--;
  515. hdlc_flush(bcs);
  516. return;
  517. }
  518. if ((procskb = bcs->skb) == NULL) {
  519. /* previous error */
  520. gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
  521. gigaset_rcv_error(NULL, bcs->cs, bcs);
  522. } else if (procskb->len < 2) {
  523. dev_notice(bcs->cs->dev, "received short frame (%d octets)\n",
  524. procskb->len);
  525. bcs->hw.bas->runts++;
  526. gigaset_rcv_error(procskb, bcs->cs, bcs);
  527. } else if (bcs->fcs != PPP_GOODFCS) {
  528. dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n",
  529. bcs->fcs);
  530. bcs->hw.bas->fcserrs++;
  531. gigaset_rcv_error(procskb, bcs->cs, bcs);
  532. } else {
  533. procskb->len -= 2; /* subtract FCS */
  534. procskb->tail -= 2;
  535. gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)",
  536. __func__, procskb->len);
  537. dump_bytes(DEBUG_STREAM_DUMP,
  538. "rcv data", procskb->data, procskb->len);
  539. bcs->hw.bas->goodbytes += procskb->len;
  540. gigaset_rcv_skb(procskb, bcs->cs, bcs);
  541. }
  542. if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
  543. skb_reserve(bcs->skb, HW_HDR_LEN);
  544. else
  545. dev_err(bcs->cs->dev, "could not allocate skb\n");
  546. bcs->fcs = PPP_INITFCS;
  547. }
  548. /* hdlc_frag
  549. * drop HDLC data packet with non-integral last byte
  550. */
  551. static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
  552. {
  553. if (unlikely(bcs->ignore)) {
  554. bcs->ignore--;
  555. hdlc_flush(bcs);
  556. return;
  557. }
  558. dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
  559. bcs->hw.bas->alignerrs++;
  560. gigaset_rcv_error(bcs->skb, bcs->cs, bcs);
  561. if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
  562. skb_reserve(bcs->skb, HW_HDR_LEN);
  563. else
  564. dev_err(bcs->cs->dev, "could not allocate skb\n");
  565. bcs->fcs = PPP_INITFCS;
  566. }
  567. /* bit counts lookup table for HDLC bit unstuffing
  568. * index: input byte
  569. * value: bit 0..3 = number of consecutive '1' bits starting from LSB
  570. * bit 4..6 = number of consecutive '1' bits starting from MSB
  571. * (replacing 8 by 7 to make it fit; the algorithm won't care)
  572. * bit 7 set if there are 5 or more "interior" consecutive '1' bits
  573. */
  574. static const unsigned char bitcounts[256] = {
  575. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
  576. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
  577. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
  578. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,
  579. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
  580. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
  581. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
  582. 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,
  583. 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
  584. 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,
  585. 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
  586. 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,
  587. 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,
  588. 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,
  589. 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,
  590. 0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78
  591. };
  592. /* hdlc_unpack
  593. * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation)
  594. * on a sequence of received data bytes (8 bits each, LSB first)
  595. * pass on successfully received, complete frames as SKBs via gigaset_rcv_skb
  596. * notify of errors via gigaset_rcv_error
  597. * tally frames, errors etc. in BC structure counters
  598. * parameters:
  599. * src received data
  600. * count number of received bytes
  601. * bcs receiving B channel structure
  602. */
  603. static inline void hdlc_unpack(unsigned char *src, unsigned count,
  604. struct bc_state *bcs)
  605. {
  606. struct bas_bc_state *ubc = bcs->hw.bas;
  607. int inputstate;
  608. unsigned seqlen, inbyte, inbits;
  609. /* load previous state:
  610. * inputstate = set of flag bits:
  611. * - INS_flag_hunt: no complete opening flag received since connection setup or last abort
  612. * - INS_have_data: at least one complete data byte received since last flag
  613. * seqlen = number of consecutive '1' bits in last 7 input stream bits (0..7)
  614. * inbyte = accumulated partial data byte (if !INS_flag_hunt)
  615. * inbits = number of valid bits in inbyte, starting at LSB (0..6)
  616. */
  617. inputstate = bcs->inputstate;
  618. seqlen = ubc->seqlen;
  619. inbyte = ubc->inbyte;
  620. inbits = ubc->inbits;
  621. /* bit unstuffing a byte a time
  622. * Take your time to understand this; it's straightforward but tedious.
  623. * The "bitcounts" lookup table is used to speed up the counting of
  624. * leading and trailing '1' bits.
  625. */
  626. while (count--) {
  627. unsigned char c = *src++;
  628. unsigned char tabentry = bitcounts[c];
  629. unsigned lead1 = tabentry & 0x0f;
  630. unsigned trail1 = (tabentry >> 4) & 0x0f;
  631. seqlen += lead1;
  632. if (unlikely(inputstate & INS_flag_hunt)) {
  633. if (c == PPP_FLAG) {
  634. /* flag-in-one */
  635. inputstate &= ~(INS_flag_hunt | INS_have_data);
  636. inbyte = 0;
  637. inbits = 0;
  638. } else if (seqlen == 6 && trail1 != 7) {
  639. /* flag completed & not followed by abort */
  640. inputstate &= ~(INS_flag_hunt | INS_have_data);
  641. inbyte = c >> (lead1 + 1);
  642. inbits = 7 - lead1;
  643. if (trail1 >= 8) {
  644. /* interior stuffing: omitting the MSB handles most cases */
  645. inbits--;
  646. /* correct the incorrectly handled cases individually */
  647. switch (c) {
  648. case 0xbe:
  649. inbyte = 0x3f;
  650. break;
  651. }
  652. }
  653. }
  654. /* else: continue flag-hunting */
  655. } else if (likely(seqlen < 5 && trail1 < 7)) {
  656. /* streamlined case: 8 data bits, no stuffing */
  657. inbyte |= c << inbits;
  658. hdlc_putbyte(inbyte & 0xff, bcs);
  659. inputstate |= INS_have_data;
  660. inbyte >>= 8;
  661. /* inbits unchanged */
  662. } else if (likely(seqlen == 6 && inbits == 7 - lead1 &&
  663. trail1 + 1 == inbits &&
  664. !(inputstate & INS_have_data))) {
  665. /* streamlined case: flag idle - state unchanged */
  666. } else if (unlikely(seqlen > 6)) {
  667. /* abort sequence */
  668. ubc->aborts++;
  669. hdlc_flush(bcs);
  670. inputstate |= INS_flag_hunt;
  671. } else if (seqlen == 6) {
  672. /* closing flag, including (6 - lead1) '1's and one '0' from inbits */
  673. if (inbits > 7 - lead1) {
  674. hdlc_frag(bcs, inbits + lead1 - 7);
  675. inputstate &= ~INS_have_data;
  676. } else {
  677. if (inbits < 7 - lead1)
  678. ubc->stolen0s ++;
  679. if (inputstate & INS_have_data) {
  680. hdlc_done(bcs);
  681. inputstate &= ~INS_have_data;
  682. }
  683. }
  684. if (c == PPP_FLAG) {
  685. /* complete flag, LSB overlaps preceding flag */
  686. ubc->shared0s ++;
  687. inbits = 0;
  688. inbyte = 0;
  689. } else if (trail1 != 7) {
  690. /* remaining bits */
  691. inbyte = c >> (lead1 + 1);
  692. inbits = 7 - lead1;
  693. if (trail1 >= 8) {
  694. /* interior stuffing: omitting the MSB handles most cases */
  695. inbits--;
  696. /* correct the incorrectly handled cases individually */
  697. switch (c) {
  698. case 0xbe:
  699. inbyte = 0x3f;
  700. break;
  701. }
  702. }
  703. } else {
  704. /* abort sequence follows, skb already empty anyway */
  705. ubc->aborts++;
  706. inputstate |= INS_flag_hunt;
  707. }
  708. } else { /* (seqlen < 6) && (seqlen == 5 || trail1 >= 7) */
  709. if (c == PPP_FLAG) {
  710. /* complete flag */
  711. if (seqlen == 5)
  712. ubc->stolen0s++;
  713. if (inbits) {
  714. hdlc_frag(bcs, inbits);
  715. inbits = 0;
  716. inbyte = 0;
  717. } else if (inputstate & INS_have_data)
  718. hdlc_done(bcs);
  719. inputstate &= ~INS_have_data;
  720. } else if (trail1 == 7) {
  721. /* abort sequence */
  722. ubc->aborts++;
  723. hdlc_flush(bcs);
  724. inputstate |= INS_flag_hunt;
  725. } else {
  726. /* stuffed data */
  727. if (trail1 < 7) { /* => seqlen == 5 */
  728. /* stuff bit at position lead1, no interior stuffing */
  729. unsigned char mask = (1 << lead1) - 1;
  730. c = (c & mask) | ((c & ~mask) >> 1);
  731. inbyte |= c << inbits;
  732. inbits += 7;
  733. } else if (seqlen < 5) { /* trail1 >= 8 */
  734. /* interior stuffing: omitting the MSB handles most cases */
  735. /* correct the incorrectly handled cases individually */
  736. switch (c) {
  737. case 0xbe:
  738. c = 0x7e;
  739. break;
  740. }
  741. inbyte |= c << inbits;
  742. inbits += 7;
  743. } else { /* seqlen == 5 && trail1 >= 8 */
  744. /* stuff bit at lead1 *and* interior stuffing */
  745. switch (c) { /* unstuff individually */
  746. case 0x7d:
  747. c = 0x3f;
  748. break;
  749. case 0xbe:
  750. c = 0x3f;
  751. break;
  752. case 0x3e:
  753. c = 0x1f;
  754. break;
  755. case 0x7c:
  756. c = 0x3e;
  757. break;
  758. }
  759. inbyte |= c << inbits;
  760. inbits += 6;
  761. }
  762. if (inbits >= 8) {
  763. inbits -= 8;
  764. hdlc_putbyte(inbyte & 0xff, bcs);
  765. inputstate |= INS_have_data;
  766. inbyte >>= 8;
  767. }
  768. }
  769. }
  770. seqlen = trail1 & 7;
  771. }
  772. /* save new state */
  773. bcs->inputstate = inputstate;
  774. ubc->seqlen = seqlen;
  775. ubc->inbyte = inbyte;
  776. ubc->inbits = inbits;
  777. }
  778. /* trans_receive
  779. * pass on received USB frame transparently as SKB via gigaset_rcv_skb
  780. * invert bytes
  781. * tally frames, errors etc. in BC structure counters
  782. * parameters:
  783. * src received data
  784. * count number of received bytes
  785. * bcs receiving B channel structure
  786. */
  787. static inline void trans_receive(unsigned char *src, unsigned count,
  788. struct bc_state *bcs)
  789. {
  790. struct sk_buff *skb;
  791. int dobytes;
  792. unsigned char *dst;
  793. if (unlikely(bcs->ignore)) {
  794. bcs->ignore--;
  795. hdlc_flush(bcs);
  796. return;
  797. }
  798. if (unlikely((skb = bcs->skb) == NULL)) {
  799. bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
  800. if (!skb) {
  801. dev_err(bcs->cs->dev, "could not allocate skb\n");
  802. return;
  803. }
  804. skb_reserve(skb, HW_HDR_LEN);
  805. }
  806. bcs->hw.bas->goodbytes += skb->len;
  807. dobytes = TRANSBUFSIZE - skb->len;
  808. while (count > 0) {
  809. dst = skb_put(skb, count < dobytes ? count : dobytes);
  810. while (count > 0 && dobytes > 0) {
  811. *dst++ = bitrev8(*src++);
  812. count--;
  813. dobytes--;
  814. }
  815. if (dobytes == 0) {
  816. dump_bytes(DEBUG_STREAM_DUMP,
  817. "rcv data", skb->data, skb->len);
  818. gigaset_rcv_skb(skb, bcs->cs, bcs);
  819. bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
  820. if (!skb) {
  821. dev_err(bcs->cs->dev,
  822. "could not allocate skb\n");
  823. return;
  824. }
  825. skb_reserve(bcs->skb, HW_HDR_LEN);
  826. dobytes = TRANSBUFSIZE;
  827. }
  828. }
  829. }
  830. void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs)
  831. {
  832. switch (bcs->proto2) {
  833. case ISDN_PROTO_L2_HDLC:
  834. hdlc_unpack(src, count, bcs);
  835. break;
  836. default: /* assume transparent */
  837. trans_receive(src, count, bcs);
  838. }
  839. }
  840. /* == data input =========================================================== */
  841. static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
  842. {
  843. struct cardstate *cs = inbuf->cs;
  844. unsigned cbytes = cs->cbytes;
  845. while (numbytes--) {
  846. /* copy next character, check for end of line */
  847. switch (cs->respdata[cbytes] = *src++) {
  848. case '\r':
  849. case '\n':
  850. /* end of line */
  851. gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
  852. __func__, cbytes);
  853. if (cbytes >= MAX_RESP_SIZE - 1)
  854. dev_warn(cs->dev, "response too large\n");
  855. cs->cbytes = cbytes;
  856. gigaset_handle_modem_response(cs);
  857. cbytes = 0;
  858. break;
  859. default:
  860. /* advance in line buffer, checking for overflow */
  861. if (cbytes < MAX_RESP_SIZE - 1)
  862. cbytes++;
  863. }
  864. }
  865. /* save state */
  866. cs->cbytes = cbytes;
  867. }
  868. /* process a block of data received through the control channel
  869. */
  870. void gigaset_isoc_input(struct inbuf_t *inbuf)
  871. {
  872. struct cardstate *cs = inbuf->cs;
  873. unsigned tail, head, numbytes;
  874. unsigned char *src;
  875. head = inbuf->head;
  876. while (head != (tail = inbuf->tail)) {
  877. gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
  878. if (head > tail)
  879. tail = RBUFSIZE;
  880. src = inbuf->data + head;
  881. numbytes = tail - head;
  882. gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
  883. if (cs->mstate == MS_LOCKED) {
  884. gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
  885. numbytes, src);
  886. gigaset_if_receive(inbuf->cs, src, numbytes);
  887. } else {
  888. gigaset_dbg_buffer(DEBUG_CMD, "received response",
  889. numbytes, src);
  890. cmd_loop(src, numbytes, inbuf);
  891. }
  892. head += numbytes;
  893. if (head == RBUFSIZE)
  894. head = 0;
  895. gig_dbg(DEBUG_INTR, "setting head to %u", head);
  896. inbuf->head = head;
  897. }
  898. }
  899. /* == data output ========================================================== */
  900. /**
  901. * gigaset_isoc_send_skb() - queue an skb for sending
  902. * @bcs: B channel descriptor structure.
  903. * @skb: data to send.
  904. *
  905. * Called by i4l.c to queue an skb for sending, and start transmission if
  906. * necessary.
  907. *
  908. * Return value:
  909. * number of bytes accepted for sending (skb->len) if ok,
  910. * error code < 0 (eg. -ENODEV) on error
  911. */
  912. int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
  913. {
  914. int len = skb->len;
  915. unsigned long flags;
  916. spin_lock_irqsave(&bcs->cs->lock, flags);
  917. if (!bcs->cs->connected) {
  918. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  919. return -ENODEV;
  920. }
  921. skb_queue_tail(&bcs->squeue, skb);
  922. gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
  923. __func__, skb_queue_len(&bcs->squeue));
  924. /* tasklet submits URB if necessary */
  925. tasklet_schedule(&bcs->hw.bas->sent_tasklet);
  926. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  927. return len; /* ok so far */
  928. }