fifo.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * fifo.c - HFC FIFO management routines
  3. *
  4. * Copyright (C) 2006 headissue GmbH; Jens Wilke
  5. * Copyright (C) 2004 Daniele Orlandi
  6. * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
  7. *
  8. * Original author of this code is
  9. * Daniele "Vihai" Orlandi <daniele@orlandi.com>
  10. *
  11. * This program is free software and may be modified and
  12. * distributed under the terms of the GNU General Public License.
  13. *
  14. */
  15. #include <linux/kernel.h>
  16. #include <dahdi/kernel.h>
  17. #include "fifo.h"
  18. static void hfc_fifo_mem_read(struct hfc_chan_simplex *chan,
  19. int z_start,
  20. void *data, int size)
  21. {
  22. int bytes_to_boundary = chan->z_max - z_start + 1;
  23. if (bytes_to_boundary >= size) {
  24. memcpy(data,
  25. chan->z_base + z_start,
  26. size);
  27. } else {
  28. /*
  29. * Buffer wrap
  30. */
  31. memcpy(data,
  32. chan->z_base + z_start,
  33. bytes_to_boundary);
  34. memcpy(data + bytes_to_boundary,
  35. chan->fifo_base,
  36. size - bytes_to_boundary);
  37. }
  38. }
  39. static void hfc_fifo_mem_write(struct hfc_chan_simplex *chan,
  40. void *data, int size)
  41. {
  42. int bytes_to_boundary = chan->z_max - *Z1_F1(chan) + 1;
  43. if (bytes_to_boundary >= size) {
  44. memcpy(chan->z_base + *Z1_F1(chan),
  45. data,
  46. size);
  47. } else {
  48. /*
  49. * FIFO wrap
  50. */
  51. memcpy(chan->z_base + *Z1_F1(chan),
  52. data,
  53. bytes_to_boundary);
  54. memcpy(chan->fifo_base,
  55. data + bytes_to_boundary,
  56. size - bytes_to_boundary);
  57. }
  58. }
  59. int hfc_fifo_get(struct hfc_chan_simplex *chan,
  60. void *data, int size)
  61. {
  62. int available_bytes;
  63. /*
  64. * Some useless statistic
  65. */
  66. chan->bytes += size;
  67. available_bytes = hfc_fifo_used_rx(chan);
  68. if (available_bytes < size && !chan->fifo_underrun++) {
  69. /*
  70. * print the warning only once
  71. */
  72. printk(KERN_WARNING hfc_DRIVER_PREFIX
  73. "card %d: "
  74. "chan %s: "
  75. "RX FIFO not enough (%d) bytes to receive!\n",
  76. chan->chan->card->cardnum,
  77. chan->chan->name,
  78. available_bytes);
  79. return -1;
  80. }
  81. hfc_fifo_mem_read(chan, *Z2_F2(chan), data, size);
  82. *Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size);
  83. return available_bytes - size;
  84. }
  85. void hfc_fifo_put(struct hfc_chan_simplex *chan,
  86. void *data, int size)
  87. {
  88. struct hfc_card *card = chan->chan->card;
  89. int used_bytes = hfc_fifo_used_tx(chan);
  90. int free_bytes = hfc_fifo_free_tx(chan);
  91. if (!used_bytes && !chan->fifo_underrun++) {
  92. /*
  93. * print warning only once, to make timing not worse
  94. */
  95. printk(KERN_WARNING hfc_DRIVER_PREFIX
  96. "card %d: "
  97. "chan %s: "
  98. "TX FIFO has become empty\n",
  99. card->cardnum,
  100. chan->chan->name);
  101. }
  102. if (free_bytes < size) {
  103. printk(KERN_CRIT hfc_DRIVER_PREFIX
  104. "card %d: "
  105. "chan %s: "
  106. "TX FIFO full!\n",
  107. chan->chan->card->cardnum,
  108. chan->chan->name);
  109. chan->fifo_full++;
  110. hfc_clear_fifo_tx(chan);
  111. }
  112. hfc_fifo_mem_write(chan, data, size);
  113. chan->bytes += size;
  114. *Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size);
  115. }
  116. int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size)
  117. {
  118. int frame_size;
  119. u16 newz2 ;
  120. if (*chan->f1 == *chan->f2) {
  121. /*
  122. * nothing received, strange uh?
  123. */
  124. printk(KERN_WARNING hfc_DRIVER_PREFIX
  125. "card %d: "
  126. "chan %s: "
  127. "get_frame called with no frame in FIFO.\n",
  128. chan->chan->card->cardnum,
  129. chan->chan->name);
  130. return -1;
  131. }
  132. /*
  133. * frame_size includes CRC+CRC+STAT
  134. */
  135. frame_size = hfc_fifo_get_frame_size(chan);
  136. #ifdef DEBUG
  137. if (debug_level == 3) {
  138. printk(KERN_DEBUG hfc_DRIVER_PREFIX
  139. "card %d: "
  140. "chan %s: "
  141. "RX len %2d: ",
  142. chan->chan->card->cardnum,
  143. chan->chan->name,
  144. frame_size);
  145. } else if (debug_level >= 4) {
  146. printk(KERN_DEBUG hfc_DRIVER_PREFIX
  147. "card %d: "
  148. "chan %s: "
  149. "RX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
  150. chan->chan->card->cardnum,
  151. chan->chan->name,
  152. *chan->f1, *chan->f2, *Z1_F2(chan), *Z2_F2(chan),
  153. frame_size);
  154. }
  155. if (debug_level >= 3) {
  156. int i;
  157. for (i = 0; i < frame_size; i++) {
  158. printk("%02x", hfc_fifo_u8(chan,
  159. Z_inc(chan, *Z2_F2(chan), i)));
  160. }
  161. printk("\n");
  162. }
  163. #endif
  164. if (frame_size <= 0) {
  165. #ifdef DEBUG
  166. if (debug_level >= 2) {
  167. printk(KERN_DEBUG hfc_DRIVER_PREFIX
  168. "card %d: "
  169. "chan %s: "
  170. "invalid (empty) frame received.\n",
  171. chan->chan->card->cardnum,
  172. chan->chan->name);
  173. }
  174. #endif
  175. hfc_fifo_drop_frame(chan);
  176. return -1;
  177. }
  178. /*
  179. * STAT is not really received
  180. */
  181. chan->bytes += frame_size - 1;
  182. /*
  183. * Calculate beginning of the next frame
  184. */
  185. newz2 = Z_inc(chan, *Z2_F2(chan), frame_size);
  186. /*
  187. * We cannot use hfc_fifo_get because of different semantic of
  188. * "available bytes" and to avoid useless increment of Z2
  189. */
  190. hfc_fifo_mem_read(chan, *Z2_F2(chan), data,
  191. frame_size < max_size ? frame_size : max_size);
  192. if (hfc_fifo_u8(chan, Z_inc(chan, *Z2_F2(chan),
  193. frame_size - 1)) != 0x00) {
  194. /*
  195. * CRC not ok, frame broken, skipping
  196. */
  197. #ifdef DEBUG
  198. if (debug_level >= 2) {
  199. printk(KERN_WARNING hfc_DRIVER_PREFIX
  200. "card %d: "
  201. "chan %s: "
  202. "Received frame with wrong CRC\n",
  203. chan->chan->card->cardnum,
  204. chan->chan->name);
  205. }
  206. #endif
  207. chan->crc++;
  208. hfc_fifo_drop_frame(chan);
  209. return -1;
  210. }
  211. chan->frames++;
  212. *chan->f2 = F_inc(chan, *chan->f2, 1);
  213. /*
  214. * Set Z2 for the next frame we're going to receive
  215. */
  216. *Z2_F2(chan) = newz2;
  217. return frame_size;
  218. }
  219. void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan)
  220. {
  221. int available_bytes;
  222. u16 newz2;
  223. if (*chan->f1 == *chan->f2) {
  224. /*
  225. * nothing received, strange eh?
  226. */
  227. printk(KERN_WARNING hfc_DRIVER_PREFIX
  228. "card %d: "
  229. "chan %s: "
  230. "skip_frame called with no frame in FIFO.\n",
  231. chan->chan->card->cardnum,
  232. chan->chan->name);
  233. return;
  234. }
  235. available_bytes = hfc_fifo_used_rx(chan) + 1;
  236. /*
  237. * Calculate beginning of the next frame
  238. */
  239. newz2 = Z_inc(chan, *Z2_F2(chan), available_bytes);
  240. *chan->f2 = F_inc(chan, *chan->f2, 1);
  241. /*
  242. * Set Z2 for the next frame we're going to receive
  243. */
  244. *Z2_F2(chan) = newz2;
  245. }
  246. void hfc_fifo_put_frame(struct hfc_chan_simplex *chan,
  247. void *data, int size)
  248. {
  249. u16 newz1;
  250. int available_frames;
  251. #ifdef DEBUG
  252. if (debug_level == 3) {
  253. printk(KERN_DEBUG hfc_DRIVER_PREFIX
  254. "card %d: "
  255. "chan %s: "
  256. "TX len %2d: ",
  257. chan->chan->card->cardnum,
  258. chan->chan->name,
  259. size);
  260. } else if (debug_level >= 4) {
  261. printk(KERN_DEBUG hfc_DRIVER_PREFIX
  262. "card %d: "
  263. "chan %s: "
  264. "TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
  265. chan->chan->card->cardnum,
  266. chan->chan->name,
  267. *chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan),
  268. size);
  269. }
  270. if (debug_level >= 3) {
  271. int i;
  272. for (i = 0; i < size; i++)
  273. printk("%02x", ((u8 *)data)[i]);
  274. printk("\n");
  275. }
  276. #endif
  277. available_frames = hfc_fifo_free_frames(chan);
  278. if (available_frames >= chan->f_num) {
  279. printk(KERN_CRIT hfc_DRIVER_PREFIX
  280. "card %d: "
  281. "chan %s: "
  282. "TX FIFO total number of frames exceeded!\n",
  283. chan->chan->card->cardnum,
  284. chan->chan->name);
  285. chan->fifo_full++;
  286. return;
  287. }
  288. hfc_fifo_put(chan, data, size);
  289. newz1 = *Z1_F1(chan);
  290. *chan->f1 = F_inc(chan, *chan->f1, 1);
  291. *Z1_F1(chan) = newz1;
  292. chan->frames++;
  293. }
  294. void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan)
  295. {
  296. *chan->f2 = *chan->f1;
  297. *Z2_F2(chan) = *Z1_F2(chan);
  298. }
  299. void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan)
  300. {
  301. *chan->f1 = *chan->f2;
  302. *Z1_F1(chan) = *Z2_F1(chan);
  303. if (chan->chan->status == open_voice) {
  304. /*
  305. * Make sure that at least hfc_TX_FIFO_PRELOAD bytes are
  306. * present in the TX FIFOs
  307. * Create hfc_TX_FIFO_PRELOAD bytes of empty data
  308. * (0x7f is mute audio)
  309. */
  310. u8 empty_fifo[hfc_TX_FIFO_PRELOAD +
  311. DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD];
  312. memset(empty_fifo, 0x7f, sizeof(empty_fifo));
  313. hfc_fifo_put(chan, empty_fifo, sizeof(empty_fifo));
  314. }
  315. }