2
* fifo.c - HFC FIFO management routines
4
* Copyright (C) 2006 headissue GmbH; Jens Wilke
5
* Copyright (C) 2004 Daniele Orlandi
6
* Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
8
* Original author of this code is
9
* Daniele "Vihai" Orlandi <daniele@orlandi.com>
11
* This program is free software and may be modified and
12
* distributed under the terms of the GNU Public License.
16
#include <linux/kernel.h>
18
#include "../zaptel.h"
22
static void hfc_fifo_mem_read(struct hfc_chan_simplex *chan,
26
int bytes_to_boundary = chan->z_max - z_start + 1;
27
if (bytes_to_boundary >= size) {
29
chan->z_base + z_start,
34
chan->z_base + z_start,
37
memcpy(data + bytes_to_boundary,
39
size - bytes_to_boundary);
43
static void hfc_fifo_mem_write(struct hfc_chan_simplex *chan,
46
int bytes_to_boundary = chan->z_max - *Z1_F1(chan) + 1;
47
if (bytes_to_boundary >= size) {
48
memcpy(chan->z_base + *Z1_F1(chan),
54
memcpy(chan->z_base + *Z1_F1(chan),
58
memcpy(chan->fifo_base,
59
data + bytes_to_boundary,
60
size - bytes_to_boundary);
64
int hfc_fifo_get(struct hfc_chan_simplex *chan,
69
// Some useless statistic
72
available_bytes = hfc_fifo_used_rx(chan);
74
if (available_bytes < size && !chan->fifo_underrun++) {
75
// print the warning only once
76
printk(KERN_WARNING hfc_DRIVER_PREFIX
79
"RX FIFO not enough (%d) bytes to receive!\n",
80
chan->chan->card->cardnum,
86
hfc_fifo_mem_read(chan, *Z2_F2(chan), data, size);
87
*Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size);
88
return available_bytes - size;
92
static void hfc_fifo_drop(struct hfc_chan_simplex *chan, int size)
94
int available_bytes = hfc_fifo_used_rx(chan);
95
if (available_bytes + 1 < size) {
96
printk(KERN_WARNING hfc_DRIVER_PREFIX
99
"RX FIFO not enough (%d) bytes to drop!\n",
100
chan->chan->card->cardnum,
107
*Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size);
111
void hfc_fifo_put(struct hfc_chan_simplex *chan,
112
void *data, int size)
114
struct hfc_card *card = chan->chan->card;
115
int used_bytes = hfc_fifo_used_tx(chan);
116
int free_bytes = hfc_fifo_free_tx(chan);
118
if (!used_bytes && !chan->fifo_underrun++) {
119
// print warning only once, to make timing not worse
120
printk(KERN_WARNING hfc_DRIVER_PREFIX
123
"TX FIFO has become empty\n",
127
if (free_bytes < size) {
128
printk(KERN_CRIT hfc_DRIVER_PREFIX
132
chan->chan->card->cardnum,
135
hfc_clear_fifo_tx(chan);
138
hfc_fifo_mem_write(chan, data, size);
140
*Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size);
143
int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size)
148
if (*chan->f1 == *chan->f2) {
149
// nothing received, strange uh?
150
printk(KERN_WARNING hfc_DRIVER_PREFIX
153
"get_frame called with no frame in FIFO.\n",
154
chan->chan->card->cardnum,
160
// frame_size includes CRC+CRC+STAT
161
frame_size = hfc_fifo_get_frame_size(chan);
164
if(debug_level == 3) {
165
printk(KERN_DEBUG hfc_DRIVER_PREFIX
169
chan->chan->card->cardnum,
172
} else if(debug_level >= 4) {
173
printk(KERN_DEBUG hfc_DRIVER_PREFIX
176
"RX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
177
chan->chan->card->cardnum,
179
*chan->f1, *chan->f2, *Z1_F2(chan), *Z2_F2(chan),
183
if(debug_level >= 3) {
185
for (i=0; i < frame_size; i++) {
186
printk("%02x", hfc_fifo_u8(chan,
187
Z_inc(chan, *Z2_F2(chan), i)));
194
if (frame_size <= 0) {
196
if (debug_level >= 2) {
197
printk(KERN_DEBUG hfc_DRIVER_PREFIX
200
"invalid (empty) frame received.\n",
201
chan->chan->card->cardnum,
206
hfc_fifo_drop_frame(chan);
210
// STAT is not really received
211
chan->bytes += frame_size - 1;
213
// Calculate beginning of the next frame
214
newz2 = Z_inc(chan, *Z2_F2(chan), frame_size);
216
// We cannot use hfc_fifo_get because of different semantic of
217
// "available bytes" and to avoid useless increment of Z2
218
hfc_fifo_mem_read(chan, *Z2_F2(chan), data,
219
frame_size < max_size ? frame_size : max_size);
221
if (hfc_fifo_u8(chan, Z_inc(chan, *Z2_F2(chan),
222
frame_size - 1)) != 0x00) {
223
// CRC not ok, frame broken, skipping
225
if(debug_level >= 2) {
226
printk(KERN_WARNING hfc_DRIVER_PREFIX
229
"Received frame with wrong CRC\n",
230
chan->chan->card->cardnum,
236
chan->chan->net_device_stats.rx_errors++;
238
hfc_fifo_drop_frame(chan);
244
*chan->f2 = F_inc(chan, *chan->f2, 1);
246
// Set Z2 for the next frame we're going to receive
247
*Z2_F2(chan) = newz2;
252
void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan)
257
if (*chan->f1 == *chan->f2) {
258
// nothing received, strange eh?
259
printk(KERN_WARNING hfc_DRIVER_PREFIX
262
"skip_frame called with no frame in FIFO.\n",
263
chan->chan->card->cardnum,
271
available_bytes = hfc_fifo_used_rx(chan) + 1;
273
// Calculate beginning of the next frame
274
newz2 = Z_inc(chan, *Z2_F2(chan), available_bytes);
276
*chan->f2 = F_inc(chan, *chan->f2, 1);
278
// Set Z2 for the next frame we're going to receive
279
*Z2_F2(chan) = newz2;
282
void hfc_fifo_put_frame(struct hfc_chan_simplex *chan,
283
void *data, int size)
286
int available_frames;
289
if (debug_level == 3) {
290
printk(KERN_DEBUG hfc_DRIVER_PREFIX
294
chan->chan->card->cardnum,
297
} else if (debug_level >= 4) {
298
printk(KERN_DEBUG hfc_DRIVER_PREFIX
301
"TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
302
chan->chan->card->cardnum,
304
*chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan),
308
if (debug_level >= 3) {
310
for (i=0; i<size; i++)
311
printk("%02x",((u8 *)data)[i]);
317
available_frames = hfc_fifo_free_frames(chan);
319
if (available_frames >= chan->f_num) {
320
printk(KERN_CRIT hfc_DRIVER_PREFIX
323
"TX FIFO total number of frames exceeded!\n",
324
chan->chan->card->cardnum,
332
hfc_fifo_put(chan, data, size);
334
newz1 = *Z1_F1(chan);
336
*chan->f1 = F_inc(chan, *chan->f1, 1);
338
*Z1_F1(chan) = newz1;
343
void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan)
345
*chan->f2 = *chan->f1;
346
*Z2_F2(chan) = *Z1_F2(chan);
349
void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan)
351
*chan->f1 = *chan->f2;
352
*Z1_F1(chan) = *Z2_F1(chan);
354
if (chan->chan->status == open_voice) {
355
// Make sure that at least hfc_TX_FIFO_PRELOAD bytes are
356
// present in the TX FIFOs
358
// Create hfc_TX_FIFO_PRELOAD bytes of empty data
359
// (0x7f is mute audio)
360
u8 empty_fifo[hfc_TX_FIFO_PRELOAD + ZT_CHUNKSIZE + hfc_RX_FIFO_PRELOAD];
361
memset(empty_fifo, 0x7f, sizeof(empty_fifo));
363
hfc_fifo_put(chan, empty_fifo, sizeof(empty_fifo));