1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/*
* fifo.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards
*
* Copyright (C) 2004 Daniele Orlandi
* Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
*
* Daniele "Vihai" Orlandi <daniele@orlandi.com>
*
* Major rewrite of the driver made by
* Klaus-Peter Junghanns <kpj@junghanns.net>
*
* This program is free software and may be modified and
* distributed under the terms of the GNU Public License.
*
*/
#ifndef _HFC_FIFO_H
#define _HFC_FIFO_H
#include "zaphfc.h"
static inline u16 *Z1_F1(struct hfc_chan_simplex *chan)
{
return chan->z1_base + (*chan->f1 * 4);
}
static inline u16 *Z2_F1(struct hfc_chan_simplex *chan)
{
return chan->z2_base + (*chan->f1 * 4);
}
static inline u16 *Z1_F2(struct hfc_chan_simplex *chan)
{
return chan->z1_base + (*chan->f2 * 4);
}
static inline u16 *Z2_F2(struct hfc_chan_simplex *chan)
{
return chan->z2_base + (*chan->f2 * 4);
}
static inline u16 Z_inc(struct hfc_chan_simplex *chan, u16 z, u16 inc)
{
/*
* declared as u32 in order to manage overflows
*/
u32 newz = z + inc;
if (newz > chan->z_max)
newz -= chan->fifo_size;
return newz;
}
static inline u8 F_inc(struct hfc_chan_simplex *chan, u8 f, u8 inc)
{
/*
* declared as u16 in order to manage overflows
*/
u16 newf = f + inc;
if (newf > chan->f_max)
newf -= chan->f_num;
return newf;
}
static inline u16 hfc_fifo_used_rx(struct hfc_chan_simplex *chan)
{
return (*Z1_F2(chan) - *Z2_F2(chan) +
chan->fifo_size) % chan->fifo_size;
}
static inline u16 hfc_fifo_get_frame_size(struct hfc_chan_simplex *chan)
{
/*
* This +1 is needed because in frame mode the available bytes are Z2-Z1+1
* while in transparent mode I wouldn't consider the byte pointed by Z2 to
* be available, otherwise, the FIFO would always contain one byte, even
* when Z1==Z2
*/
return hfc_fifo_used_rx(chan) + 1;
}
static inline u8 hfc_fifo_u8(struct hfc_chan_simplex *chan, u16 z)
{
return *((u8 *)(chan->z_base + z));
}
static inline u16 hfc_fifo_used_tx(struct hfc_chan_simplex *chan)
{
return (*Z1_F1(chan) - *Z2_F1(chan) +
chan->fifo_size) % chan->fifo_size;
}
static inline u16 hfc_fifo_free_rx(struct hfc_chan_simplex *chan)
{
u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan);
if (free_bytes > 0)
return free_bytes;
else
return free_bytes + chan->fifo_size;
}
static inline u16 hfc_fifo_free_tx(struct hfc_chan_simplex *chan)
{
u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan);
if (free_bytes > 0)
return free_bytes;
else
return free_bytes + chan->fifo_size;
}
static inline int hfc_fifo_has_frames(struct hfc_chan_simplex *chan)
{
return *chan->f1 != *chan->f2;
}
static inline u8 hfc_fifo_used_frames(struct hfc_chan_simplex *chan)
{
return (*chan->f1 - *chan->f2 + chan->f_num) % chan->f_num;
}
static inline u8 hfc_fifo_free_frames(struct hfc_chan_simplex *chan)
{
return (*chan->f2 - *chan->f1 + chan->f_num) % chan->f_num;
}
int hfc_fifo_get(struct hfc_chan_simplex *chan, void *data, int size);
void hfc_fifo_put(struct hfc_chan_simplex *chan, void *data, int size);
void hfc_fifo_drop(struct hfc_chan_simplex *chan, int size);
int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size);
void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan);
void hfc_fifo_put_frame(struct hfc_chan_simplex *chan, void *data, int size);
void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan);
void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan);
#endif
|