summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Fredrickson <creslin@digium.com>2008-08-24 05:53:32 +0000
committerMatthew Fredrickson <creslin@digium.com>2008-08-24 05:53:32 +0000
commit2a54508b0817ef7d930e15b5995c666c191356fd (patch)
treec78479c070fdb5716def20ac5bdfb4822e20bd79
parentd2dc50fa62b6cb6c806abb9dc43662901034c4a7 (diff)
Add support for 56 KB HDLC as well as selectable rate via ioctl
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@4817 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/dahdi-base.c31
-rw-r--r--include/dahdi/fasthdlc.h51
-rw-r--r--include/dahdi/kernel.h2
-rw-r--r--include/dahdi/user.h3
4 files changed, 69 insertions, 18 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index c563d55..115a548 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -1515,8 +1515,8 @@ static int dahdi_net_open(hdlc_device *hdlc)
if (res)
return res;
- fasthdlc_init(&ms->rxhdlc);
- fasthdlc_init(&ms->txhdlc);
+ fasthdlc_init(&ms->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
+ fasthdlc_init(&ms->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
ms->infcs = PPP_INITFCS;
netif_start_queue(ztchan_to_dev(ms));
@@ -2373,8 +2373,8 @@ static int initialize_channel(struct dahdi_chan *chan)
chan->firstcadencepos = 0; /* By default loop back to first cadence position */
/* HDLC & FCS stuff */
- fasthdlc_init(&chan->rxhdlc);
- fasthdlc_init(&chan->txhdlc);
+ fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
+ fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
chan->infcs = PPP_INITFCS;
/* Timings for RBS */
@@ -5012,8 +5012,8 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
if (j) {
chan->flags |= DAHDI_FLAG_HDLC;
- fasthdlc_init(&chan->rxhdlc);
- fasthdlc_init(&chan->txhdlc);
+ fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
+ fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
}
break;
case DAHDI_HDLCFCSMODE:
@@ -5022,10 +5022,21 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
if (j) {
chan->flags |= DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS;
- fasthdlc_init(&chan->rxhdlc);
- fasthdlc_init(&chan->txhdlc);
+ fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
+ fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
}
break;
+ case DAHDI_HDLC_RATE:
+ get_user(j, (int *) data);
+ if (j == 56) {
+ chan->flags |= DAHDI_FLAG_HDLC56;
+ } else {
+ chan->flags &= ~DAHDI_FLAG_HDLC56;
+ }
+
+ fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
+ fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
+ break;
case DAHDI_ECHOCANCEL_PARAMS:
{
struct dahdi_echocanparams ecp;
@@ -5860,7 +5871,7 @@ static inline void __dahdi_getbuf_chunk(struct dahdi_chan *ss, unsigned char *tx
/* If this is an HDLC channel we only send a byte of
HDLC. */
for(x=0;x<left;x++) {
- if (ms->txhdlc.bits < 8)
+ if (fasthdlc_tx_need_data(&ms->txhdlc))
/* Load a byte of data only if needed */
fasthdlc_tx_load_nocheck(&ms->txhdlc, buf[ms->writeidx[ms->outwritebuf]++]);
*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
@@ -5971,7 +5982,7 @@ out in the later versions, and is put back now. */
} else if (ms->flags & DAHDI_FLAG_HDLC) {
for (x=0;x<bytes;x++) {
/* Okay, if we're HDLC, then transmit a flag by default */
- if (ms->txhdlc.bits < 8)
+ if (fasthdlc_tx_need_data(&ms->txhdlc))
fasthdlc_tx_frame_nocheck(&ms->txhdlc);
*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
}
diff --git a/include/dahdi/fasthdlc.h b/include/dahdi/fasthdlc.h
index 72d4d60..20beeb6 100644
--- a/include/dahdi/fasthdlc.h
+++ b/include/dahdi/fasthdlc.h
@@ -32,11 +32,17 @@
#ifndef _FASTHDLC_H
#define _FASTHDLC_H
+enum fasthdlc_mode {
+ FASTHDLC_MODE_64 = 0,
+ FASTHDLC_MODE_56,
+};
+
struct fasthdlc_state {
int state; /* What state we are in */
unsigned int data; /* Our current data queue */
int bits; /* Number of bits in our data queue */
int ones; /* Number of ones */
+ enum fasthdlc_mode mode;
};
#ifdef FAST_HDLC_NEED_TABLES
@@ -343,9 +349,10 @@ static inline void fasthdlc_precalc(void)
}
-static inline void fasthdlc_init(struct fasthdlc_state *h)
+static inline void fasthdlc_init(struct fasthdlc_state *h, enum fasthdlc_mode mode)
{
/* Initializes all states appropriately */
+ h->mode = mode;
h->state = 0;
h->bits = 0;
h->data = 0;
@@ -386,13 +393,36 @@ static inline int fasthdlc_tx_frame(struct fasthdlc_state *h)
return fasthdlc_tx_frame_nocheck(h);
}
+static inline int fasthdlc_tx_need_data(struct fasthdlc_state *h)
+{
+ if (h->mode == FASTHDLC_MODE_56) {
+ if (h->bits < 7)
+ return 1;
+ } else {
+ if (h->bits < 8)
+ return 1;
+ }
+
+ return 0;
+}
+
static inline int fasthdlc_tx_run_nocheck(struct fasthdlc_state *h)
{
unsigned char b;
- b = h->data >> 24;
- h->bits -= 8;
- h->data <<= 8;
- return b;
+ if (h->mode == FASTHDLC_MODE_56) {
+ b = h->data >> 25;
+ h->bits -= 7;
+ h->data <<= 7;
+
+ return b << 1;
+ } else {
+ b = h->data >> 24;
+ h->bits -= 8;
+ h->data <<= 8;
+
+ return b;
+ }
+
}
static inline int fasthdlc_tx_run(struct fasthdlc_state *h)
@@ -404,9 +434,14 @@ static inline int fasthdlc_tx_run(struct fasthdlc_state *h)
static inline int fasthdlc_rx_load_nocheck(struct fasthdlc_state *h, unsigned char b)
{
- /* Put the new byte in the data stream */
- h->data |= b << (24-h->bits);
- h->bits += 8;
+ if (h->mode == FASTHDLC_MODE_56) {
+ h->data |= (b >> 1) << (25-h->bits);
+ h->bits += 7;
+ } else {
+ /* Put the new byte in the data stream */
+ h->data |= b << (24-h->bits);
+ h->bits += 8;
+ }
return 0;
}
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index 1b165f9..e24e375 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -462,6 +462,7 @@ enum dahdi_rxsig {
#define DAHDI_FLAG_NOSTDTXRX (1 << 17) /*!< Do NOT do standard transmit and receive on every interrupt */
#define DAHDI_FLAG_LOOPED (1 << 18) /*!< Loopback the receive data from the channel to the transmit */
#define DAHDI_FLAG_MTP2 (1 << 19) /*!< Repeats last message in buffer and also discards repeating messages sent to us */
+#define DAHDI_FLAG_HDLC56 (1 << 20) /*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K */
/*! This is a redefinition of the flags from above to allow use of the kernel atomic bit testing and changing routines.
* See the above descriptions for DAHDI_FLAG_.... for documentation about function. */
@@ -486,6 +487,7 @@ enum {
DAHDI_FLAGBIT_NOSTDTXRX = 17,
DAHDI_FLAGBIT_LOOPED = 18,
DAHDI_FLAGBIT_MTP2 = 19,
+ DAHDI_FLAGBIT_HDLC56 = 20,
};
struct dahdi_span {
diff --git a/include/dahdi/user.h b/include/dahdi/user.h
index c71848b..ff86589 100644
--- a/include/dahdi/user.h
+++ b/include/dahdi/user.h
@@ -976,6 +976,9 @@ struct dahdi_hwgain {
#define DAHDI_STARTUP _IOW(DAHDI_CODE, 99, int)
#define DAHDI_SHUTDOWN _IOW(DAHDI_CODE, 100, int)
+
+#define DAHDI_HDLC_RATE _IOW(DAHDI_CODE, 101, int)
+
struct torisa_debug {
unsigned int txerrors;
unsigned int irqcount;