asyncdata.c 15 KB

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