asyncdata.c 17 KB

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