• News
  • Idefisk
  • Tools
  • Tutorials
  • Forum
  • Reviews
  • VoIP Providers
  • Archives
  • Gallery
ZOIPER softphone
AsteriskGuru Archives
Mailing List Archives
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[svn-commits] trunk - r888 /trunk/wct4xxp.c

 
   AsteriskGuru Archives Forum Index -> Asterisk-CVS
View previous topic :: View next topic  
Author Message
svn-commits at lists.digi
Guest





PostPosted: Tue Jan 10, 2006 10:30 pm    Post subject: [svn-commits] trunk - r888 /trunk/wct4xxp.c

Author: mattf
Date: Tue Jan 10 16:08:10 2006
New Revision: 888

URL: http://svn.digium.com/view/zaptel?rev=888&view=rev
Log:
Add experimental support for Hardware HDLC for D-channels (#5313)

Modified:
trunk/wct4xxp.c

Modified: trunk/wct4xxp.c
URL: http://svn.digium.com/view/zaptel/trunk/wct4xxp.c?rev=888&r1=887&r2=888&view=diff
==============================================================================
--- trunk/wct4xxp.c (original)
+++ trunk/wct4xxp.c Tue Jan 10 16:08:10 2006
@@ -33,6 +33,8 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
#ifdef STANDALONE_ZAPATA
#include "zaptel.h"
#else
@@ -170,6 +172,7 @@
static int highestorder;
static int t1e1override = -1;
static int j1mode = 0;
+static int sigmode = FRMR_MODE_NO_ADDR_CMP;
static int loopback = 0;
static int alarmdebounce = 0;
#ifdef VPM_SUPPORT
@@ -252,6 +255,14 @@
unsigned char ec_chunk2[31][ZT_CHUNKSIZE]; /* second EC chunk buffer */
#endif
int irqmisses;
+
+ /* HDLC controller fields */
+ struct zt_chan *sigchan;
+ unsigned char sigmode;
+ int sigactive;
+ int frames_out;
+ int frames_in;
+
#ifdef VPM_SUPPORT
unsigned int dtmfactive;
unsigned int dtmfmask;
@@ -335,6 +346,7 @@
#ifdef SUPPORT_GEN1
static int t4_reset_dma(struct t4 *wc);
#endif
+static void t4_hdlc_hard_xmit(struct zt_chan *chan);
static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data);
static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan);
static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan);
@@ -350,11 +362,12 @@
/* #define WC_GPIO 5 */
#define WC_VERSION 6
#define WC_LEDS 7
-#define WC_ACTIVATE (1 << 12)
#define WC_GPIOCTL 8
#define WC_GPIO 9
#define WC_LADDR 10
#define WC_LDATA 11
+#define WC_LFRMR_CS (1 << 10) /* Framer's ChipSelect signal */
+#define WC_ACTIVATE (1 << 12)
#define WC_LREAD (1 << 15)
#define WC_LWRITE (1 << 16)

@@ -375,21 +388,22 @@
#define MAX_TDM_CHAN 32
#define MAX_DTMF_DET 16

+static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
+{
+ unsigned int res = le32_to_cpu(wc->membase[addr]);
+ return res;
+}
+
static inline void __t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
{
unsigned int tmp;
wc->membase[addr] = cpu_to_le32(value);
#if 1
- tmp = le32_to_cpu(wc->membase[addr]);
+ tmp = __t4_pci_in(wc, addr);
if ((value != tmp) && (addr != WC_LEDS) && (addr != WC_LDATA) &&
(addr != WC_GPIO) && (addr != WC_INTR))
printk("Tried to load %08x into %08x, but got %08x instead\n", value, addr, tmp);
#endif
-}
-
-static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
-{
- return le32_to_cpu(wc->membase[addr]);
}

static inline void t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
@@ -431,9 +445,9 @@
unsigned int ret;
unit &= 0x3;
__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
- __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | ( 1 << 10) | WC_LREAD);
+ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LREAD);
ret = __t4_pci_in(wc, WC_LDATA);
- __t4_pci_out(wc, WC_LADDR, 0);
+ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
return ret & 0xff;
}

@@ -455,15 +469,13 @@
printk("Writing %02x to address %02x of unit %d\n", value, addr, unit);
__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
__t4_pci_out(wc, WC_LDATA, value);
- __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | (1 << 10));
- __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | (1 << 10) | WC_LWRITE);
- __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | (1 << 10));
+ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE);
__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
- __t4_pci_out(wc, WC_LADDR, 0);
if (debug & DEBUG_REGS) printk("Write complete\n");
#if 0
+ if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc))
{ unsigned int tmp;
- tmp = t4_framer_in(wc, unit, addr);
+ tmp = __t4_framer_in(wc, unit, addr);
if (tmp != value) {
printk("Expected %d from unit %d register %d but got %d instead\n", value, unit, addr, tmp);
} }
@@ -643,6 +655,112 @@
}
#endif

+static void __hdlc_stop(struct t4 *wc, unsigned int span)
+{
+ struct t4_span *t = wc->tspans[span];
+ unsigned char imr0, imr1, mode;
+ int i = 0;
+
+ /* Clear receive and transmit timeslots */
+ for (i = 0; i < 4; i++) {
+ __t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00);
+ __t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00);
+ }
+
+ imr0 = __t4_framer_in(wc, span, FRMR_IMR0);
+ imr1 = __t4_framer_in(wc, span, FRMR_IMR1);
+
+ /* Disable HDLC interrupts */
+ imr0 |= FRMR_IMR0_RME | FRMR_IMR0_RPF;
+ __t4_framer_out(wc, span, FRMR_IMR0, imr0);
+
+#if 0
+ imr1 |= FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR;
+#endif
+ imr1 |= FRMR_IMR1_XDU | FRMR_IMR1_XPR;
+ __t4_framer_out(wc, span, FRMR_IMR1, imr1);
+
+ mode = __t4_framer_in(wc, span, FRMR_MODE);
+ mode &= ~FRMR_MODE_HRAC;
+ __t4_framer_out(wc, span, FRMR_MODE, mode);
+
+ t->sigchan = NULL;
+ t->sigactive = 0;
+}
+
+static inline void __t4_framer_cmd(struct t4 *wc, unsigned int span, int cmd)
+{
+ __t4_framer_out(wc, span, FRMR_CMDR, cmd);
+}
+
+static inline void __t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd)
+{
+ int sis;
+ int loops = 0;
+
+ /* XXX could be time consuming XXX */
+ for (;;) {
+ sis = __t4_framer_in(wc, span, FRMR_SIS);
+ if (!(sis & 0x04))
+ break;
+ if (!loops++) {
+ printk("!!!SIS Waiting before cmd %02x\n", cmd);
+ }
+ }
+ if (loops)
+ printk("!!!SIS waited %d loops\n", loops);
+
+ __t4_framer_out(wc, span, FRMR_CMDR, cmd);
+}
+
+static int __hdlc_start(struct t4 *wc, unsigned int span, struct zt_chan *chan, unsigned char mode)
+{
+ struct t4_span *t = wc->tspans[span];
+ unsigned char imr0, imr1;
+ int offset = chan->chanpos;
+
+ if (debug & DEBUG_FRAMER) printk("Initializing signalling controller for channel %d span %d\n", chan->chanpos, chan->span->offset);
+
+ if (mode != FRMR_MODE_NO_ADDR_CMP)
+ return -1;
+
+ mode |= FRMR_MODE_HRAC;
+
+ /* Make sure we're in the right mode */
+ __t4_framer_out(wc, span, FRMR_MODE, mode);
+ __t4_framer_out(wc, span, FRMR_TSEO, 0x00);
+ __t4_framer_out(wc, span, FRMR_TSBS1, 0xff);
+
+ /* Set the interframe gaps, etc */
+ __t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
+
+ __t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
+
+ /* Set up the time slot that we want to tx/rx on */
+ __t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
+ __t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
+
+ imr0 = __t4_framer_in(wc, span, FRMR_IMR0);
+ imr1 = __t4_framer_in(wc, span, FRMR_IMR1);
+
+ /* Enable our interrupts again */
+ imr0 &= ~(FRMR_IMR0_RME | FRMR_IMR0_RPF);
+ __t4_framer_out(wc, span, FRMR_IMR0, imr0);
+
+#if 0
+ imr1 &= ~(FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR);
+#endif
+ imr1 &= ~(FRMR_IMR1_XDU | FRMR_IMR1_XPR);
+ __t4_framer_out(wc, span, FRMR_IMR1, imr1);
+
+ /* Reset the signaling controller */
+ __t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
+
+ t->sigchan = chan;
+ t->sigactive = 0;
+
+ return 0;
+}

static void __set_clear(struct t4 *wc, int span)
{
@@ -825,6 +943,58 @@
return -ENOTTY;
}
return 0;
+}
+
+static void inline __t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts)
+{
+ int res, i, size = 32;
+ unsigned char buf[32];
+
+ res = zt_hdlc_getbuf(ts->sigchan, buf, &size);
+ if (debug & DEBUG_FRAMER) printk("Got buffer sized %d and res %d for %d\n", size, res, span);
+ if (size > 0) {
+ ts->sigactive = 1;
+
+ if (debug & DEBUG_FRAMER) {
+ printk("TX(");
+ for (i = 0; i < size; i++)
+ printk((i ? " %02x" : "%02x"), buf[i]);
+ printk(")\n");
+ }
+
+ for (i = 0; i < size; i++)
+ __t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]);
+
+ if (res) /* End of message */ {
+ if (debug & DEBUG_FRAMER) printk("transmiting XHF|XME\n");
+ __t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME);
+#if 0
+ ts->sigactive = (__t4_framer_in(wc, span, FRMR_SIS) & FRMR_SIS_XFW) ? 0 : 1;
+#endif
+ ++ts->frames_out;
+ if ((debug & DEBUG_FRAMER) && !(ts->frames_out & 0x0f))
+ printk("Transmitted %d frames on span %d\n", ts->frames_out, span);
+ } else { /* Still more to transmit */
+ if (debug & DEBUG_FRAMER) printk("transmiting XHF\n");
+ __t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF);
+ }
+ }
+ else if (res < 0)
+ ts->sigactive = 0;
+}
+
+static void t4_hdlc_hard_xmit(struct zt_chan *chan)
+{
+ struct t4 *wc = chan->pvt;
+ int span = chan->span->offset;
+ struct t4_span *ts = wc->tspans[span];
+ unsigned long flags;
+
+ spin_lock_irqsave(&wc->reglock, flags);
+ if (debug & DEBUG_FRAMER) printk("t4_hdlc_hard_xmit, sigactive=%d\n", ts->sigactive);
+ if ((ts->sigchan == chan) && !ts->sigactive)
+ __t4_hdlc_xmit_fifo(wc, span, ts);
+ spin_unlock_irqrestore(&wc->reglock, flags);
}

static int t4_maint(struct zt_span *span, int cmd)
@@ -958,6 +1128,11 @@
span->flags &= ~ZT_FLAG_RUNNING;
if (wasrunning)
wc->spansstarted--;
+
+ /* Stop HDLC controller if runned */
+ if (ts->sigchan)
+ __hdlc_stop(wc, ts->sigchan->span->offset);
+
__t4_set_led(wc, span->offset, WC_OFF);
if (((wc->numspans == 4) &&
(!(wc->tspans[0]->span.flags & ZT_FLAG_RUNNING)) &&
@@ -1014,6 +1189,15 @@
wc->tspans[lc->sync - 1]->psync = span->offset + 1;
}
wc->checktiming = 1;
+ /* HDLC controller part */
+ if (ts->sigchan) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&wc->reglock, flags);
+ __hdlc_stop(wc, ts->sigchan->span->offset);
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ }
+
/* If we're already running, then go ahead and apply the changes */
if (span->flags & ZT_FLAG_RUNNING)
return t4_startup(span);
@@ -1026,17 +1210,36 @@
int alreadyrunning;
unsigned long flags;
struct t4 *wc = chan->pvt;
-
- alreadyrunning = wc->tspans[chan->span->offset]->span.flags & ZT_FLAG_RUNNING;
+ struct t4_span *ts = wc->tspans[chan->span->offset];
+
+ alreadyrunning = ts->span.flags & ZT_FLAG_RUNNING;
if (debug & DEBUG_MAIN) {
if (alreadyrunning)
printk("TE%dXXP: Reconfigured channel %d (%s) sigtype %d\n", wc->numspans, chan->channo, chan->name, sigtype);
else
printk("TE%dXXP: Configured channel %d (%s) sigtype %d\n", wc->numspans, chan->channo, chan->name, sigtype);
- }
+ }
+
spin_lock_irqsave(&wc->reglock, flags);
+
if (alreadyrunning)
__set_clear(wc, chan->span->offset);
+
+ if ((sigtype == ZT_SIG_HARDHDLC) && (ts->sigchan != chan)) {
+ if (alreadyrunning) {
+ if (ts->sigchan)
+ __hdlc_stop(wc, ts->sigchan->span->offset);
+ if (__hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
+ printk("Error initializing signalling controller\n");
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ return -1;
+ }
+ }
+ else {
+ ts->sigchan = chan;
+ ts->sigactive = 0;
+ }
+ }
spin_unlock_irqrestore(&wc->reglock, flags);
return 0;
}
@@ -1085,6 +1288,12 @@
ts->span.maint = t4_maint;
ts->span.open = t4_open;
ts->span.close = t4_close;
+
+ /* HDLC Specific init */
+ ts->sigchan = NULL;
+ ts->sigmode = sigmode;
+ ts->sigactive = 0;
+
if (ts->spantype == TYPE_T1 || ts->spantype == TYPE_J1) {
ts->span.channels = 24;
ts->span.deflaw = ZT_LAW_MULAW;
@@ -1096,6 +1305,7 @@
ts->span.flags = ZT_FLAG_RBS;
ts->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF;
ts->span.ioctl = t4_ioctl;
+ ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
if (gen2) {
#ifdef VPM_SUPPORT
ts->span.echocan = t4_echocan;
@@ -1111,7 +1321,7 @@
for (y=0;y<wc->tspans[x]->span.channels;y++) {
struct zt_chan *mychans = ts->chans + y;
sprintf(mychans->name, "TE%d/%d/%d/%d", wc->numspans, wc->num, x + 1, y + 1);
- mychans->sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS |
+ mychans->sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_HARDHDLC |
ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_EM_E1 | ZT_SIG_DACS_RBS;
c = (x * ts->span.channels) + y;
mychans->pvt = wc;
@@ -1144,26 +1354,26 @@
}

/* Configure interrupts */
- t4_framer_out(wc, unit, 0x46, 0x00); /* GCR: Interrupt on Activation/Deactivation of each */
+ t4_framer_out(wc, unit, FRMR_GCR, 0x00); /* GCR: Interrupt on Activation/Deactivation of each */

/* Configure system interface */
- t4_framer_out(wc, unit, 0x3e, 0xc2); /* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */
- t4_framer_out(wc, unit, 0x3f, 0x20 | (unit << 1)); /* SIC2: No FFS, no center receive eliastic buffer, phase */
- t4_framer_out(wc, unit, 0x40, 0x04); /* SIC3: Edges for capture */
- t4_framer_out(wc, unit, 0x45, 0x00); /* CMR2: We provide sync and clock for tx and rx. */
+ t4_framer_out(wc, unit, FRMR_SIC1, 0xc2); /* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */
+ t4_framer_out(wc, unit, FRMR_SIC2, 0x20 | (unit << 1)); /* SIC2: No FFS, no center receive eliastic buffer, phase */
+ t4_framer_out(wc, unit, FRMR_SIC3, 0x04); /* SIC3: Edges for capture */
+ t4_framer_out(wc, unit, FRMR_CMR2, 0x00); /* CMR2: We provide sync and clock for tx and rx. */
if (!wc->t1e1) { /* T1 mode */
- t4_framer_out(wc, unit, 0x22, 0x03); /* XC0: Normal operation of Sa-bits */
- t4_framer_out(wc, unit, 0x23, 0x84); /* XC1: 0 offset */
+ t4_framer_out(wc, unit, FRMR_XC0, 0x03); /* XC0: Normal operation of Sa-bits */
+ t4_framer_out(wc, unit, FRMR_XC1, 0x84); /* XC1: 0 offset */
if (wc->tspans[unit]->spantype == TYPE_J1)
- t4_framer_out(wc, unit, 0x24, 0x83); /* RC0: Just shy of 1023 */
+ t4_framer_out(wc, unit, FRMR_RC0, 0x83); /* RC0: Just shy of 1023 */
else
- t4_framer_out(wc, unit, 0x24, 0x03); /* RC0: Just shy of 1023 */
- t4_framer_out(wc, unit, 0x25, 0x84); /* RC1: The rest of RC0 */
+ t4_framer_out(wc, unit, FRMR_RC0, 0x03); /* RC0: Just shy of 1023 */
+ t4_framer_out(wc, unit, FRMR_RC1, 0x84); /* RC1: The rest of RC0 */
} else { /* E1 mode */
- t4_framer_out(wc, unit, 0x22, 0x00); /* XC0: Normal operation of Sa-bits */
- t4_framer_out(wc, unit, 0x23, 0x04); /* XC1: 0 offset */
- t4_framer_out(wc, unit, 0x24, 0x04); /* RC0: Just shy of 1023 */
- t4_framer_out(wc, unit, 0x25, 0x04); /* RC1: The rest of RC0 */
+ t4_framer_out(wc, unit, FRMR_XC0, 0x00); /* XC0: Normal operation of Sa-bits */
+ t4_framer_out(wc, unit, FRMR_XC1, 0x04); /* XC1: 0 offset */
+ t4_framer_out(wc, unit, FRMR_RC0, 0x04); /* RC0: Just shy of 1023 */
+ t4_framer_out(wc, unit, FRMR_RC1, 0x04); /* RC1: The rest of RC0 */
}

/* Configure ports */
@@ -1470,6 +1680,16 @@
__t4_check_alarms(wc, span->offset);
__t4_check_sigbits(wc, span->offset);
}
+ /* Startup HDLC controller too */
+ if (ts->sigchan) {
+ printk("Starting HDLC controller for channel %d span %d\n", ts->sigchan->channo, ts->sigchan->span->offset);
+ if (__hdlc_start(wc, ts->sigchan->span->offset, ts->sigchan, ts->sigmode)) {
+ printk("Error initializing signalling controller\n");
+ /* XXX Should de-initialize span XXX */
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ return -1;
+ }
+ }
}

spin_unlock_irqrestore(&wc->reglock, flags);
@@ -1996,6 +2216,8 @@
#endif
}

+static inline void __t4_framer_interrupt(struct t4 *wc, int span);
+
#ifdef SUPPORT_GEN1
#ifdef LINUX26
static irqreturn_t t4_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -2008,9 +2230,7 @@
int x;

unsigned int status;
-#if 0
unsigned int status2;
-#endif

#if 0
if (wc->intcount < 20)
@@ -2021,6 +2241,17 @@
/* Make sure it's really for us */
status = t4_pci_in(wc, WC_INTR);
t4_pci_out(wc, WC_INTR, 0);
+
+ /* Process framer interrupts */
+ status2 = t4_framer_in(wc, 0, FRMR_CIS);
+ if (status2 & 0x0f) {
+ spin_lock_irqsave(&wc->reglock, flags);
+ for (x = 0; x < wc->numspans; ++x) {
+ if (status2 & (1 << x))
+ __t4_framer_interrupt(wc, x);
+ }
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ }

/* Ignore if it's not for us */
if (!status)
@@ -2052,10 +2283,10 @@

#if 0
if ((wc->intcount < 10) || !(wc->intcount % 1000)) {
- status2 = t4_framer_in(wc, 0, 0x6f);
+ status2 = t4_framer_in(wc, 0, FRMR_CIS);
printk("Status2: %04x\n", status2);
for (x = 0;x<4;x++) {
- status2 = t4_framer_in(wc, x, 0x4c);
+ status2 = t4_framer_in(wc, x, FRMR_FRS0);
printk("FRS0/%d: %04x\n", x, status2);
}
}
@@ -2094,64 +2325,135 @@
static inline void __t4_framer_interrupt(struct t4 *wc, int span)
{
/* Check interrupts for a given span */
- unsigned char gis, isr0=0, isr1=0, isr2=0, isr3=0, isr4;
- struct t4_span *ts;
+ unsigned char gis, isr0, isr1, isr2, isr3, isr4;
+ int readsize = -1;
+ struct t4_span *ts = wc->tspans[span];

if (debug & DEBUG_FRAMER)
printk("framer interrupt span %d:%d!\n", wc->num, span + 1);
- ts = wc->tspans[span];
-
- gis = __t4_framer_in(wc, span, 0x6e);
-
+
+ /* 1st gen cards isn't used interrupts */
+ gis = __t4_framer_in(wc, span, FRMR_GIS);
+ isr0 = (gis & FRMR_GIS_ISR0) ? __t4_framer_in(wc, span, FRMR_ISR0) : 0;
+ isr1 = (gis & FRMR_GIS_ISR1) ? __t4_framer_in(wc, span, FRMR_ISR1) : 0;
+ isr2 = (gis & FRMR_GIS_ISR2) ? __t4_framer_in(wc, span, FRMR_ISR2) : 0;
+ isr3 = (gis & FRMR_GIS_ISR3) ? __t4_framer_in(wc, span, FRMR_ISR3) : 0;
+ isr4 = (gis & FRMR_GIS_ISR4) ? __t4_framer_in(wc, span, FRMR_ISR4) : 0;
+
+ if (debug & DEBUG_FRAMER)
+ printk("gis: %02x, isr0: %02x, isr1: %02x, isr2: %02x, isr3: %02x, isr4: %02x\n", gis, isr0, isr1, isr2, isr3, isr4);
+
+ if (isr0)
+ __t4_check_sigbits(wc, span);
+
if (ts->spantype == TYPE_E1) {
/* E1 checks */
- if (gis & 0x1)
- isr0 = __t4_framer_in(wc, span, 0x68);
- if (gis & 0x2)
- isr1 = __t4_framer_in(wc, span, 0x69);
- if (gis & 0x4)
- isr2 = __t4_framer_in(wc, span, 0x6a);
- if (gis & 0x8)
- isr3 = __t4_framer_in(wc, span, 0x6b);
-
-
- if (isr0)
- __t4_check_sigbits(wc, span);
-
if ((isr3 & 0x38) || isr2 || isr1)
__t4_check_alarms(wc, span);
- if (debug & DEBUG_FRAMER)
- printk("gis: %02x, isr0: %02x, isr1: %02x, isr2: %02x, isr3: %02x\n", gis, isr0, isr1, isr2, isr3);
} else {
/* T1 checks */
- if (gis & 0x1)
- isr0 = __t4_framer_in(wc, span, 0x68);
- if (gis & 0x4)
- isr2 = __t4_framer_in(wc, span, 0x6a);
- if (gis & 0x8)
- isr3 = __t4_framer_in(wc, span, 0x6b);
-
- if (isr0)
- __t4_check_sigbits(wc, span);
if (isr2 || (isr3 & 0x08))
__t4_check_alarms(wc, span);
- if (debug & DEBUG_FRAMER)
- printk("gis: %02x, isr0: %02x, isr1: %02x, irs2: %02x, isr3: %02x\n", gis, isr0, isr1, isr2, isr3);
}
if (debugslips && !ts->span.alarms) {
if (isr3 & 0x02)
printk("TE%d10P: RECEIVE slip NEGATIVE on span %d\n", wc->numspans, span + 1);
if (isr3 & 0x01)
printk("TE%d10P: RECEIVE slip POSITIVE on span %d\n", wc->numspans, span + 1);
- if (gis & 0x10)
- isr4 = __t4_framer_in(wc, span, 0x6c);
- else
- isr4 = 0;
if (isr4 & 0x80)
printk("TE%dXXP: TRANSMIT slip POSITIVE on span %d\n", wc->numspans, span + 1);
if (isr4 & 0x40)
printk("TE%d10P: TRANSMIT slip NEGATIVE on span %d\n", wc->numspans, span + 1);
}
+
+ /* HDLC controller checks - receive side */
+ if (!wc->tspans[span]->sigchan)
+ return;
+
+ if (isr0 & FRMR_ISR0_RME) {
+ readsize = (__t4_framer_in(wc, span, FRMR_RBCH) << 8) | __t4_framer_in(wc, span, FRMR_RBCL);
+ if (debug & DEBUG_FRAMER) printk("Received data length is %d (%d)\n", readsize, readsize & FRMR_RBCL_MAX_SIZE);
+ /* RPF isn't set on last part of frame */
+ if ((readsize > 0) && ((readsize &= FRMR_RBCL_MAX_SIZE) == 0))
+ readsize = 32;
+ } else if (isr0 & FRMR_ISR0_RPF)
+ readsize = 32;
+
+ if (readsize > 0) {
+ struct zt_chan *sigchan = ts->sigchan;
+ int i;
+ unsigned char readbuf[FRMR_RBCL_MAX_SIZE];
+
+ if (debug & DEBUG_FRAMER) printk("Framer %d: Got RPF/RME! readsize is %d\n", sigchan->span->offset, readsize);
+
+ for (i = 0; i < readsize; i++)
+ readbuf[i] = __t4_framer_in(wc, span, FRMR_RXFIFO);
+
+ /* Tell the framer to clear the RFIFO */
+ __t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC);
+
+ if (debug & DEBUG_FRAMER) {
+ printk("RX(");
+ for (i = 0; i < readsize; i++)
+ printk((i ? " %02x" : "%02x"), readbuf[i]);
+ printk(")\n");
+ }
+
+ if (isr0 & FRMR_ISR0_RME) {
+ /* Do checks for HDLC problems */
+ unsigned char rsis = readbuf[readsize-1];
+ unsigned int olddebug = debug;
+ unsigned char rsis_reg = __t4_framer_in(wc, span, FRMR_RSIS);
+
+#if 0
+ if ((rsis != 0xA2) || (rsis != rsis_reg))
+ debug |= DEBUG_FRAMER;
+#endif
+
+ ++ts->frames_in;
+ if ((debug & DEBUG_FRAMER) && !(ts->frames_in & 0x0f))
+ printk("Received %d frames on span %d\n", ts->frames_in, span);
+ if (debug & DEBUG_FRAMER) printk("Received HDLC frame %d. RSIS = 0x%x (%x)\n", ts->frames_in, rsis, rsis_reg);
+ if (!(rsis & FRMR_RSIS_CRC16)) {
+ if (debug & DEBUG_FRAMER) printk("CRC check failed %d\n", span);
+ zt_hdlc_abort(sigchan, ZT_EVENT_BADFCS);
+ } else if (rsis & FRMR_RSIS_RAB) {
+ if (debug & DEBUG_FRAMER) printk("ABORT of current frame due to overflow %d\n", span);
+ zt_hdlc_abort(sigchan, ZT_EVENT_ABORT);
+ } else if (rsis & FRMR_RSIS_RDO) {
+ if (debug & DEBUG_FRAMER) printk("HDLC overflow occured %d\n", span);
+ zt_hdlc_abort(sigchan, ZT_EVENT_OVERRUN);
+ } else if (!(rsis & FRMR_RSIS_VFR)) {
+ if (debug & DEBUG_FRAMER) printk("Valid Frame check failed on span %d\n", span);
+ zt_hdlc_abort(sigchan, ZT_EVENT_ABORT);
+ } else {
+ zt_hdlc_putbuf(sigchan, readbuf, readsize - 1);
+ zt_hdlc_finish(sigchan);
+ if (debug & DEBUG_FRAMER) printk("Received valid HDLC frame on span %d\n", span);
+ }
+ debug = olddebug;
+ } else if (isr0 & FRMR_ISR0_RPF)
+ zt_hdlc_putbuf(sigchan, readbuf, readsize);
+ }
+
+ /* Transmit side */
+ if (isr1 & FRMR_ISR1_XDU) {
+ if (debug & DEBUG_FRAMER) printk("XDU: Resetting signal controler!\n");
+ __t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
+ } else if (isr1 & FRMR_ISR1_XPR) {
+ struct zt_chan *sigchan = ts->sigchan;
+
+ if (debug & DEBUG_FRAMER)
+ printk("Sigchan %d is %p\n", sigchan->chanpos, sigchan);
+
+ if (debug & DEBUG_FRAMER) printk("Framer %d: Got XPR!\n", sigchan->span->offset);
+ __t4_hdlc_xmit_fifo(wc, span, ts);
+ }
+
+ if (isr1 & FRMR_ISR1_ALLS) {
+ if (debug & DEBUG_FRAMER) printk("ALLS received\n");
+ }
+
}

#ifdef LINUX26
@@ -2202,7 +2504,7 @@
wc->intcount++;
#if 1
if (wc->intcount < 20)
- printk("2G: Got interrupt, status = %08x, GIS = %04x\n", status, __t4_framer_in(wc, 0, 0x6f));
+ printk("2G: Got interrupt, status = %08x, CIS = %04x\n", status, __t4_framer_in(wc, 0, FRMR_CIS));
#endif

if (status & 0x2) {
@@ -2254,14 +2556,14 @@
break;
}
} else if (status & 0x1) {
- cis = __t4_framer_in(wc, 0, 0x6f);
- if (cis & 0x1)
+ cis = __t4_framer_in(wc, 0, FRMR_CIS);
+ if (cis & FRMR_CIS_GIS1)
__t4_framer_interrupt(wc, 0);
- if (cis & 0x2)
+ if (cis & FRMR_CIS_GIS2)
__t4_framer_interrupt(wc, 1);
- if (cis & 0x4)
+ if (cis & FRMR_CIS_GIS3)
__t4_framer_interrupt(wc, 2);
- if (cis & 0x8)
+ if (cis & FRMR_CIS_GIS4)
__t4_framer_interrupt(wc, 3);
}
#ifdef VPM_SUPPORT
@@ -3024,6 +3326,7 @@
module_param(t1e1override, int, 0600);
module_param(alarmdebounce, int, 0600);
module_param(j1mode, int, 0600);
+module_param(sigmode, int, 0600);
#ifdef VPM_SUPPORT
module_param(vpmsupport, int, 0600);
module_param(vpmdtmfsupport, int, 0600);
@@ -3040,6 +3343,7 @@
MODULE_PARM(t1e1override, "i");
MODULE_PARM(alarmdebounce, "i");
MODULE_PARM(j1mode, "i");
+MODULE_PARM(sigmode, "i");
#ifdef VPM_SUPPORT
MODULE_PARM(vpmsupport, "i");
MODULE_PARM(vpmdtmfsupport, "i");

_______________________________________________
--Bandwidth and Colocation provided by Easynews.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/svn-commits
Back to top
Display posts from previous:   
   AsteriskGuru Archives Forum Index -> Asterisk-CVS All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
contact us at: support@asteriskguru.com - asterisKGuru.com © all rights reserved   |   *asterisk is registered trademark of © Digium™