PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/net/irda/wrapper.c

https://bitbucket.org/Don2x/mod-kernel-m7-sources
C | 492 lines | 253 code | 47 blank | 192 comment | 20 complexity | 3ee91673d31aa3023728cf429fc2f955 MD5 | raw file
  1. /*********************************************************************
  2. *
  3. * Filename: wrapper.c
  4. * Version: 1.2
  5. * Description: IrDA SIR async wrapper layer
  6. * Status: Stable
  7. * Author: Dag Brattli <dagb@cs.uit.no>
  8. * Created at: Mon Aug 4 20:40:53 1997
  9. * Modified at: Fri Jan 28 13:21:09 2000
  10. * Modified by: Dag Brattli <dagb@cs.uit.no>
  11. * Modified at: Fri May 28 3:11 CST 1999
  12. * Modified by: Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
  13. *
  14. * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
  15. * All Rights Reserved.
  16. * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
  17. *
  18. * This program is free software; you can redistribute it and/or
  19. * modify it under the terms of the GNU General Public License as
  20. * published by the Free Software Foundation; either version 2 of
  21. * the License, or (at your option) any later version.
  22. *
  23. * Neither Dag Brattli nor University of Tromsø admit liability nor
  24. * provide warranty for any of this software. This material is
  25. * provided "AS-IS" and at no charge.
  26. *
  27. ********************************************************************/
  28. #include <linux/skbuff.h>
  29. #include <linux/string.h>
  30. #include <linux/module.h>
  31. #include <asm/byteorder.h>
  32. #include <net/irda/irda.h>
  33. #include <net/irda/wrapper.h>
  34. #include <net/irda/crc.h>
  35. #include <net/irda/irlap.h>
  36. #include <net/irda/irlap_frame.h>
  37. #include <net/irda/irda_device.h>
  38. /************************** FRAME WRAPPING **************************/
  39. /*
  40. * Unwrap and unstuff SIR frames
  41. *
  42. * Note : at FIR and MIR, HDLC framing is used and usually handled
  43. * by the controller, so we come here only for SIR... Jean II
  44. */
  45. /*
  46. * Function stuff_byte (byte, buf)
  47. *
  48. * Byte stuff one single byte and put the result in buffer pointed to by
  49. * buf. The buffer must at all times be able to have two bytes inserted.
  50. *
  51. * This is in a tight loop, better inline it, so need to be prior to callers.
  52. * (2000 bytes on P6 200MHz, non-inlined ~370us, inline ~170us) - Jean II
  53. */
  54. static inline int stuff_byte(__u8 byte, __u8 *buf)
  55. {
  56. switch (byte) {
  57. case BOF: /* FALLTHROUGH */
  58. case EOF: /* FALLTHROUGH */
  59. case CE:
  60. /* Insert transparently coded */
  61. buf[0] = CE; /* Send link escape */
  62. buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */
  63. return 2;
  64. /* break; */
  65. default:
  66. /* Non-special value, no transparency required */
  67. buf[0] = byte;
  68. return 1;
  69. /* break; */
  70. }
  71. }
  72. /*
  73. * Function async_wrap (skb, *tx_buff, buffsize)
  74. *
  75. * Makes a new buffer with wrapping and stuffing, should check that
  76. * we don't get tx buffer overflow.
  77. */
  78. int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
  79. {
  80. struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
  81. int xbofs;
  82. int i;
  83. int n;
  84. union {
  85. __u16 value;
  86. __u8 bytes[2];
  87. } fcs;
  88. /* Initialize variables */
  89. fcs.value = INIT_FCS;
  90. n = 0;
  91. /*
  92. * Send XBOF's for required min. turn time and for the negotiated
  93. * additional XBOFS
  94. */
  95. if (cb->magic != LAP_MAGIC) {
  96. /*
  97. * This will happen for all frames sent from user-space.
  98. * Nothing to worry about, but we set the default number of
  99. * BOF's
  100. */
  101. IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __func__);
  102. xbofs = 10;
  103. } else
  104. xbofs = cb->xbofs + cb->xbofs_delay;
  105. IRDA_DEBUG(4, "%s(), xbofs=%d\n", __func__, xbofs);
  106. /* Check that we never use more than 115 + 48 xbofs */
  107. if (xbofs > 163) {
  108. IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __func__,
  109. xbofs);
  110. xbofs = 163;
  111. }
  112. memset(tx_buff + n, XBOF, xbofs);
  113. n += xbofs;
  114. /* Start of packet character BOF */
  115. tx_buff[n++] = BOF;
  116. /* Insert frame and calc CRC */
  117. for (i=0; i < skb->len; i++) {
  118. /*
  119. * Check for the possibility of tx buffer overflow. We use
  120. * bufsize-5 since the maximum number of bytes that can be
  121. * transmitted after this point is 5.
  122. */
  123. if(n >= (buffsize-5)) {
  124. IRDA_ERROR("%s(), tx buffer overflow (n=%d)\n",
  125. __func__, n);
  126. return n;
  127. }
  128. n += stuff_byte(skb->data[i], tx_buff+n);
  129. fcs.value = irda_fcs(fcs.value, skb->data[i]);
  130. }
  131. /* Insert CRC in little endian format (LSB first) */
  132. fcs.value = ~fcs.value;
  133. #ifdef __LITTLE_ENDIAN
  134. n += stuff_byte(fcs.bytes[0], tx_buff+n);
  135. n += stuff_byte(fcs.bytes[1], tx_buff+n);
  136. #else /* ifdef __BIG_ENDIAN */
  137. n += stuff_byte(fcs.bytes[1], tx_buff+n);
  138. n += stuff_byte(fcs.bytes[0], tx_buff+n);
  139. #endif
  140. tx_buff[n++] = EOF;
  141. return n;
  142. }
  143. EXPORT_SYMBOL(async_wrap_skb);
  144. /************************* FRAME UNWRAPPING *************************/
  145. /*
  146. * Unwrap and unstuff SIR frames
  147. *
  148. * Complete rewrite by Jean II :
  149. * More inline, faster, more compact, more logical. Jean II
  150. * (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us)
  151. * (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us)
  152. * (for reference, 115200 b/s is 1 byte every 69 us)
  153. * And reduce wrapper.o by ~900B in the process ;-)
  154. *
  155. * Then, we have the addition of ZeroCopy, which is optional
  156. * (i.e. the driver must initiate it) and improve final processing.
  157. * (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us)
  158. *
  159. * Note : at FIR and MIR, HDLC framing is used and usually handled
  160. * by the controller, so we come here only for SIR... Jean II
  161. */
  162. /*
  163. * We can also choose where we want to do the CRC calculation. We can
  164. * do it "inline", as we receive the bytes, or "postponed", when
  165. * receiving the End-Of-Frame.
  166. * (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us)
  167. * (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us)
  168. * With ZeroCopy :
  169. * (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us)
  170. * Without ZeroCopy :
  171. * (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us)
  172. * (Note : numbers taken with irq disabled)
  173. *
  174. * From those numbers, it's not clear which is the best strategy, because
  175. * we end up running through a lot of data one way or another (i.e. cache
  176. * misses). I personally prefer to avoid the huge latency spike of the
  177. * "postponed" solution, because it come just at the time when we have
  178. * lot's of protocol processing to do and it will hurt our ability to
  179. * reach low link turnaround times... Jean II
  180. */
  181. //#define POSTPONE_RX_CRC
  182. /*
  183. * Function async_bump (buf, len, stats)
  184. *
  185. * Got a frame, make a copy of it, and pass it up the stack! We can try
  186. * to inline it since it's only called from state_inside_frame
  187. */
  188. static inline void
  189. async_bump(struct net_device *dev,
  190. struct net_device_stats *stats,
  191. iobuff_t *rx_buff)
  192. {
  193. struct sk_buff *newskb;
  194. struct sk_buff *dataskb;
  195. int docopy;
  196. /* Check if we need to copy the data to a new skb or not.
  197. * If the driver doesn't use ZeroCopy Rx, we have to do it.
  198. * With ZeroCopy Rx, the rx_buff already point to a valid
  199. * skb. But, if the frame is small, it is more efficient to
  200. * copy it to save memory (copy will be fast anyway - that's
  201. * called Rx-copy-break). Jean II */
  202. docopy = ((rx_buff->skb == NULL) ||
  203. (rx_buff->len < IRDA_RX_COPY_THRESHOLD));
  204. /* Allocate a new skb */
  205. newskb = dev_alloc_skb(docopy ? rx_buff->len + 1 : rx_buff->truesize);
  206. if (!newskb) {
  207. stats->rx_dropped++;
  208. /* We could deliver the current skb if doing ZeroCopy Rx,
  209. * but this would stall the Rx path. Better drop the
  210. * packet... Jean II */
  211. return;
  212. }
  213. /* Align IP header to 20 bytes (i.e. increase skb->data)
  214. * Note this is only useful with IrLAN, as PPP has a variable
  215. * header size (2 or 1 bytes) - Jean II */
  216. skb_reserve(newskb, 1);
  217. if(docopy) {
  218. /* Copy data without CRC (length already checked) */
  219. skb_copy_to_linear_data(newskb, rx_buff->data,
  220. rx_buff->len - 2);
  221. /* Deliver this skb */
  222. dataskb = newskb;
  223. } else {
  224. /* We are using ZeroCopy. Deliver old skb */
  225. dataskb = rx_buff->skb;
  226. /* And hook the new skb to the rx_buff */
  227. rx_buff->skb = newskb;
  228. rx_buff->head = newskb->data; /* NOT newskb->head */
  229. //printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb);
  230. }
  231. /* Set proper length on skb (without CRC) */
  232. skb_put(dataskb, rx_buff->len - 2);
  233. /* Feed it to IrLAP layer */
  234. dataskb->dev = dev;
  235. skb_reset_mac_header(dataskb);
  236. dataskb->protocol = htons(ETH_P_IRDA);
  237. netif_rx(dataskb);
  238. stats->rx_packets++;
  239. stats->rx_bytes += rx_buff->len;
  240. /* Clean up rx_buff (redundant with async_unwrap_bof() ???) */
  241. rx_buff->data = rx_buff->head;
  242. rx_buff->len = 0;
  243. }
  244. /*
  245. * Function async_unwrap_bof(dev, byte)
  246. *
  247. * Handle Beginning Of Frame character received within a frame
  248. *
  249. */
  250. static inline void
  251. async_unwrap_bof(struct net_device *dev,
  252. struct net_device_stats *stats,
  253. iobuff_t *rx_buff, __u8 byte)
  254. {
  255. switch(rx_buff->state) {
  256. case LINK_ESCAPE:
  257. case INSIDE_FRAME:
  258. /* Not supposed to happen, the previous frame is not
  259. * finished - Jean II */
  260. IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
  261. __func__);
  262. stats->rx_errors++;
  263. stats->rx_missed_errors++;
  264. irda_device_set_media_busy(dev, TRUE);
  265. break;
  266. case OUTSIDE_FRAME:
  267. case BEGIN_FRAME:
  268. default:
  269. /* We may receive multiple BOF at the start of frame */
  270. break;
  271. }
  272. /* Now receiving frame */
  273. rx_buff->state = BEGIN_FRAME;
  274. rx_buff->in_frame = TRUE;
  275. /* Time to initialize receive buffer */
  276. rx_buff->data = rx_buff->head;
  277. rx_buff->len = 0;
  278. rx_buff->fcs = INIT_FCS;
  279. }
  280. /*
  281. * Function async_unwrap_eof(dev, byte)
  282. *
  283. * Handle End Of Frame character received within a frame
  284. *
  285. */
  286. static inline void
  287. async_unwrap_eof(struct net_device *dev,
  288. struct net_device_stats *stats,
  289. iobuff_t *rx_buff, __u8 byte)
  290. {
  291. #ifdef POSTPONE_RX_CRC
  292. int i;
  293. #endif
  294. switch(rx_buff->state) {
  295. case OUTSIDE_FRAME:
  296. /* Probably missed the BOF */
  297. stats->rx_errors++;
  298. stats->rx_missed_errors++;
  299. irda_device_set_media_busy(dev, TRUE);
  300. break;
  301. case BEGIN_FRAME:
  302. case LINK_ESCAPE:
  303. case INSIDE_FRAME:
  304. default:
  305. /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
  306. * the fcs will most likely not match and generate an
  307. * error, as expected - Jean II */
  308. rx_buff->state = OUTSIDE_FRAME;
  309. rx_buff->in_frame = FALSE;
  310. #ifdef POSTPONE_RX_CRC
  311. /* If we haven't done the CRC as we receive bytes, we
  312. * must do it now... Jean II */
  313. for(i = 0; i < rx_buff->len; i++)
  314. rx_buff->fcs = irda_fcs(rx_buff->fcs,
  315. rx_buff->data[i]);
  316. #endif
  317. /* Test FCS and signal success if the frame is good */
  318. if (rx_buff->fcs == GOOD_FCS) {
  319. /* Deliver frame */
  320. async_bump(dev, stats, rx_buff);
  321. break;
  322. } else {
  323. /* Wrong CRC, discard frame! */
  324. irda_device_set_media_busy(dev, TRUE);
  325. IRDA_DEBUG(1, "%s(), crc error\n", __func__);
  326. stats->rx_errors++;
  327. stats->rx_crc_errors++;
  328. }
  329. break;
  330. }
  331. }
  332. /*
  333. * Function async_unwrap_ce(dev, byte)
  334. *
  335. * Handle Character Escape character received within a frame
  336. *
  337. */
  338. static inline void
  339. async_unwrap_ce(struct net_device *dev,
  340. struct net_device_stats *stats,
  341. iobuff_t *rx_buff, __u8 byte)
  342. {
  343. switch(rx_buff->state) {
  344. case OUTSIDE_FRAME:
  345. /* Activate carrier sense */
  346. irda_device_set_media_busy(dev, TRUE);
  347. break;
  348. case LINK_ESCAPE:
  349. IRDA_WARNING("%s: state not defined\n", __func__);
  350. break;
  351. case BEGIN_FRAME:
  352. case INSIDE_FRAME:
  353. default:
  354. /* Stuffed byte coming */
  355. rx_buff->state = LINK_ESCAPE;
  356. break;
  357. }
  358. }
  359. /*
  360. * Function async_unwrap_other(dev, byte)
  361. *
  362. * Handle other characters received within a frame
  363. *
  364. */
  365. static inline void
  366. async_unwrap_other(struct net_device *dev,
  367. struct net_device_stats *stats,
  368. iobuff_t *rx_buff, __u8 byte)
  369. {
  370. switch(rx_buff->state) {
  371. /* This is on the critical path, case are ordered by
  372. * probability (most frequent first) - Jean II */
  373. case INSIDE_FRAME:
  374. /* Must be the next byte of the frame */
  375. if (rx_buff->len < rx_buff->truesize) {
  376. rx_buff->data[rx_buff->len++] = byte;
  377. #ifndef POSTPONE_RX_CRC
  378. rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
  379. #endif
  380. } else {
  381. IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
  382. __func__);
  383. rx_buff->state = OUTSIDE_FRAME;
  384. }
  385. break;
  386. case LINK_ESCAPE:
  387. /*
  388. * Stuffed char, complement bit 5 of byte
  389. * following CE, IrLAP p.114
  390. */
  391. byte ^= IRDA_TRANS;
  392. if (rx_buff->len < rx_buff->truesize) {
  393. rx_buff->data[rx_buff->len++] = byte;
  394. #ifndef POSTPONE_RX_CRC
  395. rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
  396. #endif
  397. rx_buff->state = INSIDE_FRAME;
  398. } else {
  399. IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
  400. __func__);
  401. rx_buff->state = OUTSIDE_FRAME;
  402. }
  403. break;
  404. case OUTSIDE_FRAME:
  405. /* Activate carrier sense */
  406. if(byte != XBOF)
  407. irda_device_set_media_busy(dev, TRUE);
  408. break;
  409. case BEGIN_FRAME:
  410. default:
  411. rx_buff->data[rx_buff->len++] = byte;
  412. #ifndef POSTPONE_RX_CRC
  413. rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
  414. #endif
  415. rx_buff->state = INSIDE_FRAME;
  416. break;
  417. }
  418. }
  419. /*
  420. * Function async_unwrap_char (dev, rx_buff, byte)
  421. *
  422. * Parse and de-stuff frame received from the IrDA-port
  423. *
  424. * This is the main entry point for SIR drivers.
  425. */
  426. void async_unwrap_char(struct net_device *dev,
  427. struct net_device_stats *stats,
  428. iobuff_t *rx_buff, __u8 byte)
  429. {
  430. switch(byte) {
  431. case CE:
  432. async_unwrap_ce(dev, stats, rx_buff, byte);
  433. break;
  434. case BOF:
  435. async_unwrap_bof(dev, stats, rx_buff, byte);
  436. break;
  437. case EOF:
  438. async_unwrap_eof(dev, stats, rx_buff, byte);
  439. break;
  440. default:
  441. async_unwrap_other(dev, stats, rx_buff, byte);
  442. break;
  443. }
  444. }
  445. EXPORT_SYMBOL(async_unwrap_char);