asyncdata.c 15 KB

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