From 321856cd083c77dbcbf71f12a6a6bc9691c81d57 Mon Sep 17 00:00:00 2001 From: markster Date: Tue, 11 Dec 2001 23:16:06 +0000 Subject: Version 0.1.4 from FTP git-svn-id: http://svn.digium.com/svn/zaptel/trunk@42 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- tor2.c | 501 ++++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 353 insertions(+), 148 deletions(-) (limited to 'tor2.c') 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 * 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;yspans[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; } -- cgit v1.2.3