summaryrefslogtreecommitdiff
path: root/tor2.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-12-11 23:16:06 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-12-11 23:16:06 +0000
commit321856cd083c77dbcbf71f12a6a6bc9691c81d57 (patch)
treebb4961cf6e40dc217cef6dddbfad203c0ef60d42 /tor2.c
parent9e4d29ff9c697b831782229bc26a53ee6ef9a7d5 (diff)
Version 0.1.4 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@42 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'tor2.c')
-rwxr-xr-xtor2.c501
1 files changed, 353 insertions, 148 deletions
diff --git a/tor2.c b/tor2.c
index 9f9f55b..902a785 100755
--- a/tor2.c
+++ b/tor2.c
@@ -1,5 +1,5 @@
/*
- * Tormenta 2 Quad-T1 PCI Driver version 0.1, 8/29/01
+ * Tormenta 2 Quad-T1 PCI Driver version 0.2, 12/11/01
*
* Written by Mark Spencer <markster@linux-support.net>
* Based on previous works, designs, and archetectures conceived and
@@ -46,6 +46,9 @@
#define FLAG_STARTED (1 << 0)
+#define TYPE_T1 1 /* is a T1 card */
+#define TYPE_E1 2 /* is an E1 card */
+
struct tor2_chan {
/* Private pointer for channel. We want to know our
channel and span */
@@ -81,9 +84,9 @@ struct tor2 {
volatile unsigned char *mem8; /* Virtual representation of 8 bit Xilinx memory area */
struct zt_span spans[4]; /* Spans */
struct tor2_span tspans[4]; /* Span data */
- struct zt_chan *chans[4]; /* Pointers to blocks of 24 contiguous zt_chans for each span */
- struct tor2_chan tchans[24 * 4];/* Channel user data */
- unsigned char txsigs[4][6]; /* Copy of tx sig registers */
+ struct zt_chan *chans[4]; /* Pointers to blocks of 24(30/31) contiguous zt_chans for each span */
+ struct tor2_chan tchans[32 * 4];/* Channel user data */
+ unsigned char txsigs[4][16]; /* Copy of tx sig registers */
int loopupcnt[4]; /* loop up code counter */
int loopdowncnt[4]; /* loop down code counter */
int spansstarted; /* number of spans started */
@@ -95,6 +98,8 @@ struct tor2 {
int taskletexec;
int txerrors;
struct tasklet_struct tor2_tlet;
+ int cardtype; /* card type, T1 or E1 */
+ unsigned int *datxlt; /* pointer to datxlt structure */
};
#define t1out(tor,span,reg,val) tor->mem8[((span - 1) * 0x100) + reg] = val
@@ -113,6 +118,7 @@ static void tor2_tasklet(unsigned long data);
#define INTENA (1 + ((loopback & 3) << 5))
#define OUTBIT (2 + ((loopback & 3) << 5))
+#define E1DIV 0x10
#define INTACK (0x80 + ((loopback & 3) << 5))
#define INTACTIVE 2
@@ -146,9 +152,14 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs);
/* translations of data channels for 24 channels in a 32 bit PCM highway */
-unsigned datxlt[] = {
+unsigned datxlt_t1[] = {
1 ,2 ,3 ,5 ,6 ,7 ,9 ,10,11,13,14,15,17,18,19,21,22,23,25,26,27,29,30,31 };
+/* translations of data channels for 30/31 channels in a 32 bit PCM highway */
+unsigned datxlt_e1[] = {
+ 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 };
+
static int tor2_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
{
int i;
@@ -186,6 +197,8 @@ static int tor2_chanconfig(struct zt_chan *chan, int sigtype)
else
printk("Tor2: Configured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype);
}
+ /* nothing more to do if an E1 */
+ if (p->tor->cardtype == TYPE_E1) return 0;
spin_lock_irqsave(&p->tor->lock, flags);
if (alreadyrunning)
set_clear(p->tor);
@@ -220,21 +233,25 @@ static void init_spans(struct tor2 *tor)
tor->spans[x].maint = tor2_maint;
tor->spans[x].open = tor2_open;
tor->spans[x].close = tor2_close;
- tor->spans[x].channels = 24;
+ if (tor->cardtype == TYPE_T1)
+ tor->spans[x].channels = 24;
+ else
+ tor->spans[x].channels = 31;
tor->spans[x].chans = tor->chans[x];
tor->spans[x].flags = ZT_FLAG_RBS;
tor->spans[x].linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF;
tor->spans[x].ioctl = tor2_ioctl;
tor->spans[x].pvt = &tor->tspans[x];
+ tor->spans[x].deflaw = ZT_LAW_MULAW;
tor->tspans[x].tor = tor;
tor->tspans[x].span = x;
init_waitqueue_head(&tor->spans[x].maintq);
- for (y=0;y<24;y++) {
+ for (y=0;y<tor->spans[x].channels;y++) {
struct zt_chan *mychans = tor->chans[x] + y;
sprintf(mychans->name, "Tor2/%d/%d/%d", tor->num, x + 1, y + 1);
mychans->sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS |
ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS;
- c = (x * 24) + y;
+ c = (x * tor->spans[x].channels) + y;
mychans->pvt = &tor->tchans[c];
mychans->chanpos = y + 1;
tor->tchans[c].span = x;
@@ -258,10 +275,10 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
return -ENOMEM;
memset(tor,0,sizeof(struct tor2));
for(x = 0; x < 4; x++) {
- tor->chans[x] = kmalloc(sizeof(struct zt_chan) * 24,GFP_KERNEL);
+ tor->chans[x] = kmalloc(sizeof(struct zt_chan) * 31,GFP_KERNEL);
if (!tor->chans[x])
return -ENOMEM;
- memset(tor->chans[x],0,sizeof(struct zt_chan) * 24);
+ memset(tor->chans[x],0,sizeof(struct zt_chan) * 31);
}
/* Load the resources */
tor->irq = pdev->irq;
@@ -272,7 +289,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
tor->plx_region = pci_resource_start(pdev, 0);
tor->plx_len = pci_resource_len(pdev, 0);
tor->plx = ioremap(tor->plx_region, tor->plx_len);
- /* We don't use the I/O space */
+ /* We don't use the I/O space, so we dont do anything with section 1 */
tor->xilinx32_region = pci_resource_start(pdev, 2);
tor->xilinx32_len = pci_resource_len(pdev, 2);
tor->mem32 = ioremap(tor->xilinx32_region, tor->xilinx32_len);
@@ -375,11 +392,20 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
tor->mem8[LEDREG] = 0;
for(x = 0; x < 256; x++) tor->mem32[x] = 0x7f7f7f7f;
- if (request_irq(tor->irq, tor2_intr, SA_INTERRUPT, "tor2", tor)) {
+ if (request_irq(tor->irq, tor2_intr, SA_INTERRUPT | SA_SHIRQ, "tor2", tor)) {
printk(KERN_ERR "Unable to request tormenta IRQ %d\n", tor->irq);
goto err_out_release_all;
}
+ if (t1in(tor,1,0xf) & 0x80) {
+ printk("Tormenta 2 Quad E1/PRA Card\n");
+ tor->cardtype = TYPE_E1;
+ tor->datxlt = datxlt_e1;
+ } else {
+ printk("Tormenta 2 Quad T1/PRI Card\n");
+ tor->cardtype = TYPE_T1;
+ tor->datxlt = datxlt_t1;
+ }
init_spans(tor);
if (zt_register(&tor->spans[0], 0)) {
@@ -511,6 +537,20 @@ static int tor2_rbsbits(struct zt_chan *chan, int bits)
#if 0
printk("Setting bits to %d on channel %s\n", bits, chan->name);
#endif
+ if (p->tor->cardtype == TYPE_E1) { /* do it E1 way */
+ if (chan->chanpos > 30) return 0; /* cant do this for chan 31 */
+ n = chan->chanpos - 1;
+ k = p->span;
+ b = (n % 15) + 1;
+ c = p->tor->txsigs[k][b];
+ m = (n / 15) * 4; /* nibble selector */
+ c &= (15 << m); /* keep the other nibble */
+ c |= (bits & 15) << (4 - m); /* put our new nibble here */
+ p->tor->txsigs[k][b] = c;
+ /* output them into the chip */
+ t1out(p->tor,k + 1,0x40 + b,c);
+ return 0;
+ }
n = chan->chanpos - 1;
k = p->span;
b = (n / 8); /* get byte number */
@@ -522,7 +562,6 @@ static int tor2_rbsbits(struct zt_chan *chan, int bits)
p->tor->txsigs[k][b] = c;
spin_lock_irqsave(&p->tor->lock, flags);
t1out(p->tor,k + 1,0x70 + b,c);
- t1out(p->tor,k + 1,0x76 + b,c);
b += 3; /* now points to b bit stuff */
/* get current signalling values */
c = p->tor->txsigs[k][b];
@@ -533,7 +572,26 @@ static int tor2_rbsbits(struct zt_chan *chan, int bits)
p->tor->txsigs[k][b] = c;
/* output them into the chip */
t1out(p->tor,k + 1,0x70 + b,c);
- t1out(p->tor,k + 1,0x76 + b,c);
+ b += 3; /* now points to c bit stuff */
+ /* get current signalling values */
+ c = p->tor->txsigs[k][b];
+ c &= ~m; /* clear mask bit */
+ /* set mask bit, if bit is to be set */
+ if (bits & ZT_CBIT) c |= m;
+ /* save new signalling values */
+ p->tor->txsigs[k][b] = c;
+ /* output them into the chip */
+ t1out(p->tor,k + 1,0x70 + b,c);
+ b += 3; /* now points to d bit stuff */
+ /* get current signalling values */
+ c = p->tor->txsigs[k][b];
+ c &= ~m; /* clear mask bit */
+ /* set mask bit, if bit is to be set */
+ if (bits & ZT_DBIT) c |= m;
+ /* save new signalling values */
+ p->tor->txsigs[k][b] = c;
+ /* output them into the chip */
+ t1out(p->tor,k + 1,0x70 + b,c);
spin_unlock_irqrestore(&p->tor->lock, flags);
return 0;
}
@@ -557,8 +615,13 @@ static int tor2_shutdown(struct zt_span *span)
span->flags &= ~ZT_FLAG_RUNNING;
/* Zero out all registers */
- for (i = 0; i < 160; i++)
- t1out(p->tor,tspan, i, 0);
+ if (p->tor->cardtype == TYPE_E1) {
+ for (i = 0; i < 192; i++)
+ t1out(p->tor,tspan, i, 0);
+ } else {
+ for (i = 0; i < 160; i++)
+ t1out(p->tor,tspan, i, 0);
+ }
if (wasrunning)
p->tor->spansstarted--;
spin_unlock_irqrestore(&p->tor->lock, flags);
@@ -582,6 +645,7 @@ static int tor2_startup(struct zt_span *span)
unsigned int flags;
char *coding;
char *framing;
+ char *crcing;
int alreadyrunning;
struct tor2_span *p = span->pvt;
@@ -596,82 +660,157 @@ static int tor2_startup(struct zt_span *span)
alreadyrunning = span->flags & ZT_FLAG_RUNNING;
- if (!alreadyrunning) {
- p->tor->mem8[SYNCREG] = SYNCSELF;
- p->tor->mem8[CTLREG] = 0;
- p->tor->mem8[LEDREG] = 0;
- /* Zero out all registers */
- for (i = 0; i < 160; i++)
- t1out(p->tor,tspan, i, 0);
-
- /* Set up for Interleaved Serial Bus operation in byte mode */
- if (tspan == 1) t1out(p->tor,tspan,0x94,9);
- else t1out(p->tor,tspan,0x94,8);
- /* Full-on Sync required (RCR1) */
- t1out(p->tor,tspan, 0x2b, 8);
- /* RSYNC is an input (RCR2) */
- t1out(p->tor,tspan, 0x2c, 8);
- /* RBS enable (TCR1) */
- t1out(p->tor,tspan, 0x35, 0x10);
- /* TSYNC to be output (TCR2) */
- t1out(p->tor,tspan, 0x36, 4);
- /* Tx & Rx Elastic store, sysclk(s) = 2.048 mhz, loopback controls (CCR1) */
- t1out(p->tor,tspan, 0x37, 0x9c);
- /* Set up received loopup and loopdown codes */
- t1out(p->tor,tspan, 0x12, 0x22);
- t1out(p->tor,tspan, 0x14, 0x80);
- t1out(p->tor,tspan, 0x15, 0x80);
- }
- /* Enable F bits pattern */
- i = 0x20;
- if (span->lineconfig & ZT_CONFIG_ESF)
- i = 0x88;
- if (span->lineconfig & ZT_CONFIG_B8ZS)
- i |= 0x44;
- t1out(p->tor,tspan, 0x38, i);
- if (i & 0x80)
- coding = "ESF";
- else
- coding = "SF";
- if (i & 0x40)
- framing = "B8ZS";
- else {
- framing = "AMI";
- t1out(p->tor,tspan,0x7e,0x1c); /* F bits pattern (0x1c) into FDL register */
- }
- t1out(p->tor,tspan, 0x7c, span->txlevel << 5);
+ if (p->tor->cardtype == TYPE_E1) { /* if this is an E1 card */
+ unsigned char tcr1,ccr1;
+ if (!alreadyrunning) {
+ p->tor->mem8[SYNCREG] = SYNCSELF;
+ p->tor->mem8[CTLREG] = E1DIV;
+ p->tor->mem8[LEDREG] = 0;
+ /* Zero out all registers */
+ for (i = 0; i < 192; i++)
+ t1out(p->tor,tspan, i, 0);
+
+ /* Set up for Interleaved Serial Bus operation in byte mode */
+ if (tspan == 1) t1out(p->tor,tspan,0xb5,9);
+ else t1out(p->tor,tspan,0xb5,8);
+ t1out(p->tor,tspan,0x1a,4); /* CCR2: set LOTCMC */
+ for(i = 0; i <= 8; i++) t1out(p->tor,tspan,i,0);
+ for(i = 0x10; i <= 0x4f; i++) if (i != 0x1a) t1out(p->tor,tspan,i,0);
+ t1out(p->tor,tspan,0x10,0x20); /* RCR1: Rsync as input */
+ t1out(p->tor,tspan,0x11,6); /* RCR2: Sysclk=2.048 Mhz */
+ t1out(p->tor,tspan,0x12,9); /* TCR1: TSiS mode */
+ }
+ ccr1 = 0;
+ crcing = "";
+ tcr1 = 9; /* base TCR1 value: TSis mode */
+ if (span->lineconfig & ZT_CONFIG_CCS) {
+ ccr1 |= 8; /* CCR1: Rx Sig mode: CCS */
+ coding = "CCS";
+ } else {
+ tcr1 |= 0x20;
+ coding = "CAS";
+ }
+ if (span->lineconfig & ZT_CONFIG_HDB3) {
+ ccr1 |= 0x44; /* CCR1: TX and RX HDB3 */
+ framing = "HDB3";
+ } else framing = "AMI";
+ if (span->lineconfig & ZT_CONFIG_CRC4) {
+ ccr1 |= 0x11; /* CCR1: TX and TX CRC4 */
+ crcing = "/CRC4";
+ }
+ t1out(p->tor,tspan,0x12,tcr1);
+ t1out(p->tor,tspan,0x14,ccr1);
+ t1out(p->tor,tspan, 0x18, 0x20); /* 120 Ohm, normal */
+
+ if (!alreadyrunning) {
+ t1out(p->tor,tspan,0x1b,0x8a); /* CCR3: LIRST & TSCLKM */
+ t1out(p->tor,tspan,0x20,0x1b); /* TAFR */
+ t1out(p->tor,tspan,0x21,0x5f); /* TNAFR */
+ t1out(p->tor,tspan,0x40,0xb); /* TSR1 */
+ for(i = 0x41; i <= 0x4f; i++) t1out(p->tor,tspan,i,0x55);
+ for(i = 0x22; i <= 0x25; i++) t1out(p->tor,tspan,i,0xff);
+ /* Wait 100 ms */
+ endjif = jiffies + 10;
+ spin_unlock_irqrestore(&p->tor->lock, flags);
+ while(jiffies < endjif); /* wait 100 ms */
+ spin_lock_irqsave(&p->tor->lock, flags);
+ t1out(p->tor,tspan,0x1b,0x9a); /* CCR3: set also ESR */
+ t1out(p->tor,tspan,0x1b,0x82); /* CCR3: TSCLKM only now */
+
+ span->flags |= ZT_FLAG_RUNNING;
+ p->tor->spansstarted++;
+
+ /* enable interrupts */
+ p->tor->mem8[CTLREG] = INTENA | E1DIV;
+ }
- if (!alreadyrunning) {
- /* LIRST to reset line interface */
- t1out(p->tor,tspan, 0x0a, 0x80);
+ spin_unlock_irqrestore(&p->tor->lock, flags);
- /* Wait 100 ms */
- endjif = jiffies + 10;
+ if (debug) {
+ if (alreadyrunning)
+ printk("Tor2: Reconfigured span %d (%s/%s%s) 120 Ohms\n", span->spanno, coding, framing, crcing);
+ else
+ printk("Tor2: Startup span %d (%s/%s%s) 120 Ohms\n", span->spanno, coding, framing, crcing);
+ }
+ } else { /* is a T1 card */
+
+ if (!alreadyrunning) {
+ p->tor->mem8[SYNCREG] = SYNCSELF;
+ p->tor->mem8[CTLREG] = 0;
+ p->tor->mem8[LEDREG] = 0;
+ /* Zero out all registers */
+ for (i = 0; i < 160; i++)
+ t1out(p->tor,tspan, i, 0);
+
+ /* Set up for Interleaved Serial Bus operation in byte mode */
+ if (tspan == 1) t1out(p->tor,tspan,0x94,9);
+ else t1out(p->tor,tspan,0x94,8);
+ /* Full-on Sync required (RCR1) */
+ t1out(p->tor,tspan, 0x2b, 8);
+ /* RSYNC is an input (RCR2) */
+ t1out(p->tor,tspan, 0x2c, 8);
+ /* RBS enable (TCR1) */
+ t1out(p->tor,tspan, 0x35, 0x10);
+ /* TSYNC to be output (TCR2) */
+ t1out(p->tor,tspan, 0x36, 4);
+ /* Tx & Rx Elastic store, sysclk(s) = 2.048 mhz, loopback controls (CCR1) */
+ t1out(p->tor,tspan, 0x37, 0x9c);
+ /* Set up received loopup and loopdown codes */
+ t1out(p->tor,tspan, 0x12, 0x22);
+ t1out(p->tor,tspan, 0x14, 0x80);
+ t1out(p->tor,tspan, 0x15, 0x80);
+ }
+ /* Enable F bits pattern */
+ i = 0x20;
+ if (span->lineconfig & ZT_CONFIG_ESF)
+ i = 0x88;
+ if (span->lineconfig & ZT_CONFIG_B8ZS)
+ i |= 0x44;
+ t1out(p->tor,tspan, 0x38, i);
+ if (i & 0x80)
+ coding = "ESF";
+ else
+ coding = "SF";
+ if (i & 0x40)
+ framing = "B8ZS";
+ else {
+ framing = "AMI";
+ t1out(p->tor,tspan,0x7e,0x1c); /* F bits pattern (0x1c) into FDL register */
+ }
+ t1out(p->tor,tspan, 0x7c, span->txlevel << 5);
+
+ if (!alreadyrunning) {
+ /* LIRST to reset line interface */
+ t1out(p->tor,tspan, 0x0a, 0x80);
+
+ /* Wait 100 ms */
+ endjif = jiffies + 10;
- spin_unlock_irqrestore(&p->tor->lock, flags);
+ spin_unlock_irqrestore(&p->tor->lock, flags);
- while(jiffies < endjif); /* wait 100 ms */
+ while(jiffies < endjif); /* wait 100 ms */
- spin_lock_irqsave(&p->tor->lock, flags);
+ spin_lock_irqsave(&p->tor->lock, flags);
- t1out(p->tor,tspan,0x0a,0x30); /* LIRST back to normal, Resetting elastic stores */
+ t1out(p->tor,tspan,0x0a,0x30); /* LIRST back to normal, Resetting elastic stores */
- span->flags |= ZT_FLAG_RUNNING;
- p->tor->spansstarted++;
+ span->flags |= ZT_FLAG_RUNNING;
+ p->tor->spansstarted++;
- /* enable interrupts */
- p->tor->mem8[CTLREG] = INTENA;
- }
+ /* enable interrupts */
+ p->tor->mem8[CTLREG] = INTENA;
+ }
- set_clear(p->tor);
+ set_clear(p->tor);
- spin_unlock_irqrestore(&p->tor->lock, flags);
+ spin_unlock_irqrestore(&p->tor->lock, flags);
- if (debug) {
- if (alreadyrunning)
- printk("Tor2: Reconfigured span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
- else
- printk("Tor2: Startup span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
+ if (debug) {
+ if (alreadyrunning)
+ printk("Tor2: Reconfigured span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
+ else
+ printk("Tor2: Startup span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
+ }
}
if (p->tor->syncs[0] == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno);
if (p->tor->syncs[1] == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
@@ -685,7 +824,29 @@ static int tor2_maint(struct zt_span *span, int cmd)
struct tor2_span *p = span->pvt;
int tspan = p->span + 1;
-
+
+ if (p->tor->cardtype == TYPE_E1)
+ {
+ switch(cmd) {
+ case ZT_MAINT_NONE:
+ t1out(p->tor,tspan,0xa8,0); /* no loops */
+ break;
+ case ZT_MAINT_LOCALLOOP:
+ t1out(p->tor,tspan,0xa8,0x40); /* local loop */
+ break;
+ case ZT_MAINT_REMOTELOOP:
+ t1out(p->tor,tspan,0xa8,0x80); /* remote loop */
+ break;
+ case ZT_MAINT_LOOPUP:
+ case ZT_MAINT_LOOPDOWN:
+ case ZT_MAINT_LOOPSTOP:
+ return -ENOSYS;
+ default:
+ printk("Tor2: Unknown maint command: %d\n", cmd);
+ break;
+ }
+ return 0;
+ }
switch(cmd) {
case ZT_MAINT_NONE:
t1out(p->tor,tspan,0x19,0); /* no local loop */
@@ -741,7 +902,7 @@ static void tor2_tasklet(unsigned long data)
static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
{
static unsigned int passno = 0;
- int n, i, j, k;
+ int n, i, j, k, x;
static unsigned long rxword,txword;
unsigned char c, rxc;
unsigned char abits, bbits;
@@ -753,8 +914,12 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
return;
}
- /* set outbit, interrupt enable, and ack interrupt */
- tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK;
+ if (tor->cardtype == TYPE_E1)
+ /* set outbit, interrupt enable, and ack interrupt */
+ tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | E1DIV;
+ else
+ /* set outbit, interrupt enable, and ack interrupt */
+ tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK;
#if 0
if (!passno)
@@ -762,7 +927,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
#endif
/* do the transmit output */
- for(n = 0; n < 24; n++) {
+ for(n = 0; n < tor->spans[0].channels; n++) {
for(i = 0; i < ZT_CHUNKSIZE; i++) {
/* span 1 */
txword = tor->spans[0].chans[n].writechunk[i] << 24;
@@ -773,15 +938,15 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
/* span 4 */
txword |= tor->spans[3].chans[n].writechunk[i];
/* write to part */
- tor->mem32[datxlt[n] + (32 * i)] = txword;
+ tor->mem32[tor->datxlt[n] + (32 * i)] = txword;
}
}
/* Do the receive input */
- for(n = 0; n < 24; n++) {
+ for(n = 0; n < tor->spans[0].channels; n++) {
for(i = 0; i < ZT_CHUNKSIZE; i++) {
/* read from */
- rxword = tor->mem32[datxlt[n] + (32 * i)];
+ rxword = tor->mem32[tor->datxlt[n] + (32 * i)];
/* span 1 */
tor->spans[0].chans[n].readchunk[i] = rxword >> 24;
/* span 2 */
@@ -792,9 +957,30 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
tor->spans[3].chans[n].readchunk[i] = rxword & 0xff;
}
}
-
i = passno & 63;
- if (i < 12) {
+ /* if an E1 card, do rx signalling for it */
+ if ((i < 3) && (tor->cardtype == TYPE_E1)) { /* if an E1 card */
+ for(j = (i * 3); j < (i * 3) + 5; j++)
+ {
+ for(k = 1,x = j; k <= 4; k++,x += tor->spans[0].channels) {
+ c = t1in(tor,k,0x31 + j);
+ rxc = c & 15;
+ if (rxc != tor->spans[k - 1].chans[x + 15].rxsig) {
+ /* Check for changes in received bits */
+ if (!(tor->spans[k - 1].chans[x + 15].sig & ZT_SIG_CLEAR))
+ zt_rbsbits(&tor->spans[k - 1].chans[x + 15], rxc);
+ }
+ rxc = c >> 4;
+ if (rxc != tor->spans[k - 1].chans[x].rxsig) {
+ /* Check for changes in received bits */
+ if (!(tor->spans[k - 1].chans[x].sig & ZT_SIG_CLEAR))
+ zt_rbsbits(&tor->spans[k - 1].chans[x], rxc);
+ }
+ }
+ }
+ }
+ /* if a T1, do the signalling */
+ if ((i < 12) && (tor->cardtype == TYPE_T1)) {
k = (i / 3); /* get span */
n = (i % 3); /* get base */
abits = t1in(tor,k + 1, 0x60 + n);
@@ -807,8 +993,9 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
if (bbits & (1 << j)) rxc |= ZT_BBIT;
if (tor->spans[k].chans[i].rxsig != rxc) {
/* Check for changes in received bits */
- if (!(tor->spans[k].chans[i].sig & ZT_SIG_CLEAR))
+ if (!(tor->spans[k].chans[i].sig & ZT_SIG_CLEAR)) {
zt_rbsbits(&tor->spans[k].chans[i], rxc);
+ }
}
}
}
@@ -819,7 +1006,10 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
if (!--tor->alarmtimer[i]) {
/* clear recover status */
tor->spans[i].alarms &= ~ZT_ALARM_RECOVER;
- t1out(tor,i + 1,0x35,0x10); /* turn off yel */
+ if (tor->cardtype == TYPE_E1)
+ t1out(tor,i + 1,0x21,0x5f); /* turn off yel */
+ else
+ t1out(tor,i + 1,0x35,0x10); /* turn off yel */
zt_alarm_notify(&tor->spans[i]); /* let them know */
}
}
@@ -830,42 +1020,55 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
{
j = 0; /* clear this alarm status */
i -= 50;
- c = t1in(tor,i + 1,0x31); /* get RIR2 */
- tor->spans[i].rxlevel = c >> 6; /* get rx level */
- t1out(tor,i + 1,0x20,0xff);
- c = t1in(tor,i + 1,0x20); /* get the status */
- /* detect the code, only if we are not sending one */
- if ((!tor->spans[i].mainttimer) && (c & 0x80)) /* if loop-up code detected */
- {
- /* set into remote loop, if not there already */
- if ((tor->loopupcnt[i]++ > 80) &&
- (tor->spans[i].maintstat != ZT_MAINT_REMOTELOOP))
+ if (tor->cardtype == TYPE_T1) {
+ c = t1in(tor,i + 1,0x31); /* get RIR2 */
+ tor->spans[i].rxlevel = c >> 6; /* get rx level */
+ t1out(tor,i + 1,0x20,0xff);
+ c = t1in(tor,i + 1,0x20); /* get the status */
+ /* detect the code, only if we are not sending one */
+ if ((!tor->spans[i].mainttimer) && (c & 0x80)) /* if loop-up code detected */
{
- t1out(tor,i + 1,0x1e,0); /* no local loop */
- t1out(tor,i + 1,0x0a,0x40); /* remote loop */
- tor->spans[i].maintstat = ZT_MAINT_REMOTELOOP;
+ /* set into remote loop, if not there already */
+ if ((tor->loopupcnt[i]++ > 80) &&
+ (tor->spans[i].maintstat != ZT_MAINT_REMOTELOOP))
+ {
+ t1out(tor,i + 1,0x1e,0); /* no local loop */
+ t1out(tor,i + 1,0x0a,0x40); /* remote loop */
+ tor->spans[i].maintstat = ZT_MAINT_REMOTELOOP;
+ }
+ } else tor->loopupcnt[i] = 0;
+ /* detect the code, only if we are not sending one */
+ if ((!tor->spans[i].mainttimer) && (c & 0x40)) /* if loop-down code detected */
+ {
+ /* if in remote loop, get out of it */
+ if ((tor->loopdowncnt[i]++ > 80) &&
+ (tor->spans[i].maintstat == ZT_MAINT_REMOTELOOP))
+ {
+ t1out(tor,i + 1,0x1e,0); /* no local loop */
+ t1out(tor,i + 1,0x0a,0); /* no remote loop */
+ tor->spans[i].maintstat = ZT_MAINT_NONE;
+ }
+ } else tor->loopdowncnt[i] = 0;
+ if (c & 3) /* if red alarm */
+ {
+ j |= ZT_ALARM_RED;
}
- } else tor->loopupcnt[i] = 0;
- /* detect the code, only if we are not sending one */
- if ((!tor->spans[i].mainttimer) && (c & 0x40)) /* if loop-down code detected */
- {
- /* if in remote loop, get out of it */
- if ((tor->loopdowncnt[i]++ > 80) &&
- (tor->spans[i].maintstat == ZT_MAINT_REMOTELOOP))
+ if (c & 8) /* if blue alarm */
{
- t1out(tor,i + 1,0x1e,0); /* no local loop */
- t1out(tor,i + 1,0x0a,0); /* no remote loop */
- tor->spans[i].maintstat = ZT_MAINT_NONE;
+ j |= ZT_ALARM_BLUE;
}
- } else tor->loopdowncnt[i] = 0;
- if (c & 3) /* if red alarm */
- {
- j |= ZT_ALARM_RED;
- }
- if (c & 8) /* if blue alarm */
- {
- j |= ZT_ALARM_BLUE;
- }
+ } else { /* its an E1 card */
+ t1out(tor,i + 1,6,0xff);
+ c = t1in(tor,i + 1,6); /* get the status */
+ if (c & 9) /* if red alarm */
+ {
+ j |= ZT_ALARM_RED;
+ }
+ if (c & 2) /* if blue alarm */
+ {
+ j |= ZT_ALARM_BLUE;
+ }
+ }
/* only consider previous carrier alarm state */
tor->spans[i].alarms &= (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_NOTOPEN);
n = 1; /* set to 1 so will not be in yellow alarm if we dont
@@ -874,7 +1077,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
if (tor->spans[i].lineconfig & ZT_CONFIG_NOTOPEN)
{
/* go thru all chans, and count # open */
- for(n = 0,k = 0; k < 24; k++)
+ for(n = 0,k = 0; k < tor->spans[i].channels; k++)
{
if (((tor->chans[i] + k)->flags & ZT_FLAG_OPEN) ||
((tor->chans[i] + k)->flags & ZT_FLAG_NETDEV)) n++;
@@ -889,16 +1092,24 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
if (tor->alarmtimer[i]) j |= ZT_ALARM_RECOVER;
/* if going into alarm state, set yellow alarm */
- if ((j) && (!tor->spans[i].alarms)) t1out(tor,i + 1,0x35,0x11);
+ if ((j) && (!tor->spans[i].alarms)) {
+ if (tor->cardtype == TYPE_E1)
+ t1out(tor,i + 1,0x21,0x7f);
+ else
+ t1out(tor,i + 1,0x35,0x11);
+ }
if (c & 4) /* if yellow alarm */
j |= ZT_ALARM_YELLOW;
if (tor->spans[i].maintstat || tor->spans[i].mainttimer) j |= ZT_ALARM_LOOPBACK;
tor->spans[i].alarms = j;
c = (LEDRED | LEDGREEN) << (2 * i);
tor->leds &= ~c; /* mask out bits for this span */
- if (j & ZT_ALARM_RED) tor->leds |= LEDRED << (2 * i);
- else if (j & ZT_ALARM_YELLOW) tor->leds |= (LEDRED | LEDGREEN) << (2 * i);
- else tor->leds |= LEDGREEN << (2 * i);
+ /* light LED's if span configured and running */
+ if (tor->spans[i].flags & ZT_FLAG_RUNNING) {
+ if (j & ZT_ALARM_RED) tor->leds |= LEDRED << (2 * i);
+ else if (j & ZT_ALARM_YELLOW) tor->leds |= (LEDRED | LEDGREEN) << (2 * i);
+ else tor->leds |= LEDGREEN << (2 * i);
+ }
tor->mem8[LEDREG] = tor->leds;
zt_alarm_notify(&tor->spans[i]);
}
@@ -907,8 +1118,12 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
/* do all spans */
for(i = 1; i <= 4; i++)
{
- /* add this second's BPV count to total one */
- tor->spans[i - 1].bpvcount += t1in(tor,i,0x24) + (t1in(tor,i,0x23) << 8);
+ if (tor->cardtype == TYPE_E1)
+ /* add this second's BPV count to total one */
+ tor->spans[i - 1].bpvcount += t1in(tor,i,1) + (t1in(tor,i,0) << 8);
+ else
+ /* add this second's BPV count to total one */
+ tor->spans[i - 1].bpvcount += t1in(tor,i,0x24) + (t1in(tor,i,0x23) << 8);
}
}
/* re-evaluate active sync src */
@@ -940,23 +1155,13 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
tor->txerrors++;
}
-#if 0
- for(i = 3; i >= 0; i--) {
- /* Process receive for this span */
- if (tor->spans[i].flags & ZT_FLAG_RUNNING)
- zt_receive(&tor->spans[i]);
- }
-
- for(i = 3; i >= 0; i--) {
- /* Prepare next set for transmission */
- if (tor->spans[i].flags & ZT_FLAG_RUNNING)
- zt_transmit(&tor->spans[i]);
- }
-#endif
-
passno++;
- /* clear OUTBIT and enable interrupts */
- tor->mem8[CTLREG] = INTENA;
+ if (tor->cardtype == TYPE_E1)
+ /* clear OUTBIT and enable interrupts */
+ tor->mem8[CTLREG] = INTENA | E1DIV;
+ else
+ /* clear OUTBIT and enable interrupts */
+ tor->mem8[CTLREG] = INTENA;
}