asyncdata.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /*
  2. * Common data handling layer for ser_gigaset and usb_gigaset
  3. *
  4. * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
  5. * Hansjoerg Lipp <hjlipp@web.de>,
  6. * Stefan Eilers.
  7. *
  8. * =====================================================================
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. * =====================================================================
  14. */
  15. /* not set by Kbuild when building both ser_gigaset and usb_gigaset */
  16. #ifndef KBUILD_MODNAME
  17. #define KBUILD_MODNAME "asy_gigaset"
  18. #endif
  19. #include "gigaset.h"
  20. #include <linux/crc-ccitt.h>
  21. #include <linux/bitrev.h>
  22. //#define GIG_M10x_STUFF_VOICE_DATA
  23. /* check if byte must be stuffed/escaped
  24. * I'm not sure which data should be encoded.
  25. * Therefore I will go the hard way and decode every value
  26. * less than 0x20, the flag sequence and the control escape char.
  27. */
  28. static inline int muststuff(unsigned char c)
  29. {
  30. if (c < PPP_TRANS) return 1;
  31. if (c == PPP_FLAG) return 1;
  32. if (c == PPP_ESCAPE) return 1;
  33. /* other possible candidates: */
  34. /* 0x91: XON with parity set */
  35. /* 0x93: XOFF with parity set */
  36. return 0;
  37. }
  38. /* == data input =========================================================== */
  39. /* process a block of received bytes in command mode (modem response)
  40. * Return value:
  41. * number of processed bytes
  42. */
  43. static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
  44. struct inbuf_t *inbuf)
  45. {
  46. struct cardstate *cs = inbuf->cs;
  47. unsigned cbytes = cs->cbytes;
  48. int inputstate = inbuf->inputstate;
  49. int startbytes = numbytes;
  50. for (;;) {
  51. cs->respdata[cbytes] = c;
  52. if (c == 10 || c == 13) {
  53. gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
  54. __func__, cbytes);
  55. cs->cbytes = cbytes;
  56. gigaset_handle_modem_response(cs); /* can change
  57. cs->dle */
  58. cbytes = 0;
  59. if (cs->dle &&
  60. !(inputstate & INS_DLE_command)) {
  61. inputstate &= ~INS_command;
  62. break;
  63. }
  64. } else {
  65. /* advance in line buffer, checking for overflow */
  66. if (cbytes < MAX_RESP_SIZE - 1)
  67. cbytes++;
  68. else
  69. dev_warn(cs->dev, "response too large\n");
  70. }
  71. if (!numbytes)
  72. break;
  73. c = *src++;
  74. --numbytes;
  75. if (c == DLE_FLAG &&
  76. (cs->dle || inputstate & INS_DLE_command)) {
  77. inputstate |= INS_DLE_char;
  78. break;
  79. }
  80. }
  81. cs->cbytes = cbytes;
  82. inbuf->inputstate = inputstate;
  83. return startbytes - numbytes;
  84. }
  85. /* process a block of received bytes in lock mode (tty i/f)
  86. * Return value:
  87. * number of processed bytes
  88. */
  89. static inline int lock_loop(unsigned char *src, int numbytes,
  90. struct inbuf_t *inbuf)
  91. {
  92. struct cardstate *cs = inbuf->cs;
  93. gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
  94. numbytes, src);
  95. gigaset_if_receive(cs, src, numbytes);
  96. return numbytes;
  97. }
  98. /* process a block of received bytes in HDLC data mode
  99. * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes.
  100. * When a frame is complete, check the FCS and pass valid frames to the LL.
  101. * If DLE is encountered, return immediately to let the caller handle it.
  102. * Return value:
  103. * number of processed bytes
  104. * numbytes (all bytes processed) on error --FIXME
  105. */
  106. static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
  107. struct inbuf_t *inbuf)
  108. {
  109. struct cardstate *cs = inbuf->cs;
  110. struct bc_state *bcs = inbuf->bcs;
  111. int inputstate = bcs->inputstate;
  112. __u16 fcs = bcs->fcs;
  113. struct sk_buff *skb = bcs->skb;
  114. unsigned char error;
  115. struct sk_buff *compskb;
  116. int startbytes = numbytes;
  117. int l;
  118. if (unlikely(inputstate & INS_byte_stuff)) {
  119. inputstate &= ~INS_byte_stuff;
  120. goto byte_stuff;
  121. }
  122. for (;;) {
  123. if (unlikely(c == PPP_ESCAPE)) {
  124. if (unlikely(!numbytes)) {
  125. inputstate |= INS_byte_stuff;
  126. break;
  127. }
  128. c = *src++;
  129. --numbytes;
  130. if (unlikely(c == DLE_FLAG &&
  131. (cs->dle ||
  132. inbuf->inputstate & INS_DLE_command))) {
  133. inbuf->inputstate |= INS_DLE_char;
  134. inputstate |= INS_byte_stuff;
  135. break;
  136. }
  137. byte_stuff:
  138. c ^= PPP_TRANS;
  139. #ifdef CONFIG_GIGASET_DEBUG
  140. if (unlikely(!muststuff(c)))
  141. gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
  142. #endif
  143. } else if (unlikely(c == PPP_FLAG)) {
  144. if (unlikely(inputstate & INS_skip_frame)) {
  145. if (!(inputstate & INS_have_data)) { /* 7E 7E */
  146. #ifdef CONFIG_GIGASET_DEBUG
  147. ++bcs->emptycount;
  148. #endif
  149. } else
  150. gig_dbg(DEBUG_HDLC,
  151. "7e----------------------------");
  152. /* end of frame */
  153. error = 1;
  154. gigaset_rcv_error(NULL, cs, bcs);
  155. } else if (!(inputstate & INS_have_data)) { /* 7E 7E */
  156. #ifdef CONFIG_GIGASET_DEBUG
  157. ++bcs->emptycount;
  158. #endif
  159. break;
  160. } else {
  161. gig_dbg(DEBUG_HDLC,
  162. "7e----------------------------");
  163. /* end of frame */
  164. error = 0;
  165. if (unlikely(fcs != PPP_GOODFCS)) {
  166. dev_err(cs->dev,
  167. "Packet checksum at %lu failed, "
  168. "packet is corrupted (%u bytes)!\n",
  169. bcs->rcvbytes, skb->len);
  170. compskb = NULL;
  171. gigaset_rcv_error(compskb, cs, bcs);
  172. error = 1;
  173. } else {
  174. if (likely((l = skb->len) > 2)) {
  175. skb->tail -= 2;
  176. skb->len -= 2;
  177. } else {
  178. dev_kfree_skb(skb);
  179. skb = NULL;
  180. inputstate |= INS_skip_frame;
  181. if (l == 1) {
  182. dev_err(cs->dev,
  183. "invalid packet size (1)!\n");
  184. error = 1;
  185. gigaset_rcv_error(NULL,
  186. cs, bcs);
  187. }
  188. }
  189. if (likely(!(error ||
  190. (inputstate &
  191. INS_skip_frame)))) {
  192. gigaset_rcv_skb(skb, cs, bcs);
  193. }
  194. }
  195. }
  196. if (unlikely(error))
  197. if (skb)
  198. dev_kfree_skb(skb);
  199. fcs = PPP_INITFCS;
  200. inputstate &= ~(INS_have_data | INS_skip_frame);
  201. if (unlikely(bcs->ignore)) {
  202. inputstate |= INS_skip_frame;
  203. skb = NULL;
  204. } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
  205. skb_reserve(skb, HW_HDR_LEN);
  206. } else {
  207. dev_warn(cs->dev,
  208. "could not allocate new skb\n");
  209. inputstate |= INS_skip_frame;
  210. }
  211. break;
  212. #ifdef CONFIG_GIGASET_DEBUG
  213. } else if (unlikely(muststuff(c))) {
  214. /* Should not happen. Possible after ZDLE=1<CR><LF>. */
  215. gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c);
  216. #endif
  217. }
  218. /* add character */
  219. #ifdef CONFIG_GIGASET_DEBUG
  220. if (unlikely(!(inputstate & INS_have_data))) {
  221. gig_dbg(DEBUG_HDLC, "7e (%d x) ================",
  222. bcs->emptycount);
  223. bcs->emptycount = 0;
  224. }
  225. #endif
  226. inputstate |= INS_have_data;
  227. if (likely(!(inputstate & INS_skip_frame))) {
  228. if (unlikely(skb->len == SBUFSIZE)) {
  229. dev_warn(cs->dev, "received packet too long\n");
  230. dev_kfree_skb_any(skb);
  231. skb = NULL;
  232. inputstate |= INS_skip_frame;
  233. break;
  234. }
  235. *__skb_put(skb, 1) = c;
  236. fcs = crc_ccitt_byte(fcs, c);
  237. }
  238. if (unlikely(!numbytes))
  239. break;
  240. c = *src++;
  241. --numbytes;
  242. if (unlikely(c == DLE_FLAG &&
  243. (cs->dle ||
  244. inbuf->inputstate & INS_DLE_command))) {
  245. inbuf->inputstate |= INS_DLE_char;
  246. break;
  247. }
  248. }
  249. bcs->inputstate = inputstate;
  250. bcs->fcs = fcs;
  251. bcs->skb = skb;
  252. return startbytes - numbytes;
  253. }
  254. /* process a block of received bytes in transparent data mode
  255. * Invert bytes, undoing byte stuffing and watching for DLE escapes.
  256. * If DLE is encountered, return immediately to let the caller handle it.
  257. * Return value:
  258. * number of processed bytes
  259. * numbytes (all bytes processed) on error --FIXME
  260. */
  261. static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
  262. struct inbuf_t *inbuf)
  263. {
  264. struct cardstate *cs = inbuf->cs;
  265. struct bc_state *bcs = inbuf->bcs;
  266. int inputstate = bcs->inputstate;
  267. struct sk_buff *skb = bcs->skb;
  268. int startbytes = numbytes;
  269. for (;;) {
  270. /* add character */
  271. inputstate |= INS_have_data;
  272. if (likely(!(inputstate & INS_skip_frame))) {
  273. if (unlikely(skb->len == SBUFSIZE)) {
  274. //FIXME just pass skb up and allocate a new one
  275. dev_warn(cs->dev, "received packet too long\n");
  276. dev_kfree_skb_any(skb);
  277. skb = NULL;
  278. inputstate |= INS_skip_frame;
  279. break;
  280. }
  281. *__skb_put(skb, 1) = bitrev8(c);
  282. }
  283. if (unlikely(!numbytes))
  284. break;
  285. c = *src++;
  286. --numbytes;
  287. if (unlikely(c == DLE_FLAG &&
  288. (cs->dle ||
  289. inbuf->inputstate & INS_DLE_command))) {
  290. inbuf->inputstate |= INS_DLE_char;
  291. break;
  292. }
  293. }
  294. /* pass data up */
  295. if (likely(inputstate & INS_have_data)) {
  296. if (likely(!(inputstate & INS_skip_frame))) {
  297. gigaset_rcv_skb(skb, cs, bcs);
  298. }
  299. inputstate &= ~(INS_have_data | INS_skip_frame);
  300. if (unlikely(bcs->ignore)) {
  301. inputstate |= INS_skip_frame;
  302. skb = NULL;
  303. } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN))
  304. != NULL)) {
  305. skb_reserve(skb, HW_HDR_LEN);
  306. } else {
  307. dev_warn(cs->dev, "could not allocate new skb\n");
  308. inputstate |= INS_skip_frame;
  309. }
  310. }
  311. bcs->inputstate = inputstate;
  312. bcs->skb = skb;
  313. return startbytes - numbytes;
  314. }
  315. /* process a block of data received from the device
  316. */
  317. void gigaset_m10x_input(struct inbuf_t *inbuf)
  318. {
  319. struct cardstate *cs;
  320. unsigned tail, head, numbytes;
  321. unsigned char *src, c;
  322. int procbytes;
  323. head = atomic_read(&inbuf->head);
  324. tail = atomic_read(&inbuf->tail);
  325. gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
  326. if (head != tail) {
  327. cs = inbuf->cs;
  328. src = inbuf->data + head;
  329. numbytes = (head > tail ? RBUFSIZE : tail) - head;
  330. gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
  331. while (numbytes) {
  332. if (atomic_read(&cs->mstate) == MS_LOCKED) {
  333. procbytes = lock_loop(src, numbytes, inbuf);
  334. src += procbytes;
  335. numbytes -= procbytes;
  336. } else {
  337. c = *src++;
  338. --numbytes;
  339. if (c == DLE_FLAG && (cs->dle ||
  340. inbuf->inputstate & INS_DLE_command)) {
  341. if (!(inbuf->inputstate & INS_DLE_char)) {
  342. inbuf->inputstate |= INS_DLE_char;
  343. goto nextbyte;
  344. }
  345. /* <DLE> <DLE> => <DLE> in data stream */
  346. inbuf->inputstate &= ~INS_DLE_char;
  347. }
  348. if (!(inbuf->inputstate & INS_DLE_char)) {
  349. /* FIXME use function pointers? */
  350. if (inbuf->inputstate & INS_command)
  351. procbytes = cmd_loop(c, src, numbytes, inbuf);
  352. else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC)
  353. procbytes = hdlc_loop(c, src, numbytes, inbuf);
  354. else
  355. procbytes = iraw_loop(c, src, numbytes, inbuf);
  356. src += procbytes;
  357. numbytes -= procbytes;
  358. } else { /* DLE char */
  359. inbuf->inputstate &= ~INS_DLE_char;
  360. switch (c) {
  361. case 'X': /*begin of command*/
  362. #ifdef CONFIG_GIGASET_DEBUG
  363. if (inbuf->inputstate & INS_command)
  364. dev_err(cs->dev,
  365. "received <DLE> 'X' in command mode\n");
  366. #endif
  367. inbuf->inputstate |=
  368. INS_command | INS_DLE_command;
  369. break;
  370. case '.': /*end of command*/
  371. #ifdef CONFIG_GIGASET_DEBUG
  372. if (!(inbuf->inputstate & INS_command))
  373. dev_err(cs->dev,
  374. "received <DLE> '.' in hdlc mode\n");
  375. #endif
  376. inbuf->inputstate &= cs->dle ?
  377. ~(INS_DLE_command|INS_command)
  378. : ~INS_DLE_command;
  379. break;
  380. //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */
  381. default:
  382. dev_err(cs->dev,
  383. "received 0x10 0x%02x!\n",
  384. (int) c);
  385. /* FIXME: reset driver?? */
  386. }
  387. }
  388. }
  389. nextbyte:
  390. if (!numbytes) {
  391. /* end of buffer, check for wrap */
  392. if (head > tail) {
  393. head = 0;
  394. src = inbuf->data;
  395. numbytes = tail;
  396. } else {
  397. head = tail;
  398. break;
  399. }
  400. }
  401. }
  402. gig_dbg(DEBUG_INTR, "setting head to %u", head);
  403. atomic_set(&inbuf->head, head);
  404. }
  405. }
  406. /* == data output ========================================================== */
  407. /* Encoding of a PPP packet into an octet stuffed HDLC frame
  408. * with FCS, opening and closing flags.
  409. * parameters:
  410. * skb skb containing original packet (freed upon return)
  411. * head number of headroom bytes to allocate in result skb
  412. * tail number of tailroom bytes to allocate in result skb
  413. * Return value:
  414. * pointer to newly allocated skb containing the result frame
  415. */
  416. static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
  417. {
  418. struct sk_buff *hdlc_skb;
  419. __u16 fcs;
  420. unsigned char c;
  421. unsigned char *cp;
  422. int len;
  423. unsigned int stuf_cnt;
  424. stuf_cnt = 0;
  425. fcs = PPP_INITFCS;
  426. cp = skb->data;
  427. len = skb->len;
  428. while (len--) {
  429. if (muststuff(*cp))
  430. stuf_cnt++;
  431. fcs = crc_ccitt_byte(fcs, *cp++);
  432. }
  433. fcs ^= 0xffff; /* complement */
  434. /* size of new buffer: original size + number of stuffing bytes
  435. * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
  436. */
  437. hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head);
  438. if (!hdlc_skb) {
  439. dev_kfree_skb(skb);
  440. return NULL;
  441. }
  442. skb_reserve(hdlc_skb, head);
  443. /* Copy acknowledge request into new skb */
  444. memcpy(hdlc_skb->head, skb->head, 2);
  445. /* Add flag sequence in front of everything.. */
  446. *(skb_put(hdlc_skb, 1)) = PPP_FLAG;
  447. /* Perform byte stuffing while copying data. */
  448. while (skb->len--) {
  449. if (muststuff(*skb->data)) {
  450. *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
  451. *(skb_put(hdlc_skb, 1)) = (*skb->data++) ^ PPP_TRANS;
  452. } else
  453. *(skb_put(hdlc_skb, 1)) = *skb->data++;
  454. }
  455. /* Finally add FCS (byte stuffed) and flag sequence */
  456. c = (fcs & 0x00ff); /* least significant byte first */
  457. if (muststuff(c)) {
  458. *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
  459. c ^= PPP_TRANS;
  460. }
  461. *(skb_put(hdlc_skb, 1)) = c;
  462. c = ((fcs >> 8) & 0x00ff);
  463. if (muststuff(c)) {
  464. *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
  465. c ^= PPP_TRANS;
  466. }
  467. *(skb_put(hdlc_skb, 1)) = c;
  468. *(skb_put(hdlc_skb, 1)) = PPP_FLAG;
  469. dev_kfree_skb(skb);
  470. return hdlc_skb;
  471. }
  472. /* Encoding of a raw packet into an octet stuffed bit inverted frame
  473. * parameters:
  474. * skb skb containing original packet (freed upon return)
  475. * head number of headroom bytes to allocate in result skb
  476. * tail number of tailroom bytes to allocate in result skb
  477. * Return value:
  478. * pointer to newly allocated skb containing the result frame
  479. */
  480. static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
  481. {
  482. struct sk_buff *iraw_skb;
  483. unsigned char c;
  484. unsigned char *cp;
  485. int len;
  486. /* worst case: every byte must be stuffed */
  487. iraw_skb = dev_alloc_skb(2*skb->len + tail + head);
  488. if (!iraw_skb) {
  489. dev_kfree_skb(skb);
  490. return NULL;
  491. }
  492. skb_reserve(iraw_skb, head);
  493. cp = skb->data;
  494. len = skb->len;
  495. while (len--) {
  496. c = bitrev8(*cp++);
  497. if (c == DLE_FLAG)
  498. *(skb_put(iraw_skb, 1)) = c;
  499. *(skb_put(iraw_skb, 1)) = c;
  500. }
  501. dev_kfree_skb(skb);
  502. return iraw_skb;
  503. }
  504. /* gigaset_send_skb
  505. * called by common.c to queue an skb for sending
  506. * and start transmission if necessary
  507. * parameters:
  508. * B Channel control structure
  509. * skb
  510. * Return value:
  511. * number of bytes accepted for sending
  512. * (skb->len if ok, 0 if out of buffer space)
  513. * or error code (< 0, eg. -EINVAL)
  514. */
  515. int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
  516. {
  517. unsigned len = skb->len;
  518. unsigned long flags;
  519. if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
  520. skb = HDLC_Encode(skb, HW_HDR_LEN, 0);
  521. else
  522. skb = iraw_encode(skb, HW_HDR_LEN, 0);
  523. if (!skb) {
  524. err("unable to allocate memory for encoding!\n");
  525. return -ENOMEM;
  526. }
  527. skb_queue_tail(&bcs->squeue, skb);
  528. spin_lock_irqsave(&bcs->cs->lock, flags);
  529. if (bcs->cs->connected)
  530. tasklet_schedule(&bcs->cs->write_tasklet);
  531. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  532. return len; /* ok so far */
  533. }