summaryrefslogtreecommitdiff
path: root/tor2.c
diff options
context:
space:
mode:
authorsteveu <steveu@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-07-18 18:54:03 +0000
committersteveu <steveu@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-07-18 18:54:03 +0000
commita901d40f99dcf6e30c4db59568c365a96d92bac2 (patch)
tree1ab0eb4bc40a5e5ff69524ae642ef09f6ffd786a /tor2.c
parent935f1f3b043752834411a7a21514e2f7aaf98dd5 (diff)
Added logging of CRC4 and other errors (Only bipolar violations were counted before). This affects other files, to changed the data structures, and provide
places to store the new values. If only 1 to 3 of the spans were configured the cards could misbehave. The driver now sets up interleaved bus operation for all four spans when any span is configured. This seems to fix the problem. SPANS_PER_CARD is now defined as 4, and used wherever appropriate. It made a few things easier for me to follow when debugging. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@218 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'tor2.c')
-rwxr-xr-xtor2.c166
1 files changed, 97 insertions, 69 deletions
diff --git a/tor2.c b/tor2.c
index 7ed300d..84a7f4d 100755
--- a/tor2.c
+++ b/tor2.c
@@ -1,5 +1,5 @@
/*
- * Tormenta 2 Quad-T1 PCI Driver version 0.2, 12/11/01
+ * Tormenta 2 Quad-T1 PCI Driver
*
* Written by Mark Spencer <markster@linux-support.net>
* Based on previous works, designs, and archetectures conceived and
@@ -24,6 +24,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
+ * $Id$
*/
#include <linux/kernel.h>
@@ -52,7 +53,8 @@
/* #define ENABLE_TASKLETS */
-#define MAX_SPANS 16
+#define SPANS_PER_CARD 4
+#define MAX_SPANS 16
#define FLAG_STARTED (1 << 0)
@@ -78,15 +80,15 @@ struct tor2 {
struct pci_dev *pci; /* Pointer to PCI device */
int num; /* Which card we are */
int syncsrc; /* active sync source */
- int syncs[4]; /* sync sources */
- int psyncs[4]; /* span-relative sync sources */
- int alarmtimer[4]; /* Alarm timer */
+ int syncs[SPANS_PER_CARD]; /* sync sources */
+ int psyncs[SPANS_PER_CARD]; /* span-relative sync sources */
+ int alarmtimer[SPANS_PER_CARD]; /* Alarm timer */
char *type; /* Type of tormenta 2 card */
int irq; /* IRQ used by device */
int order; /* Order */
int flags; /* Device flags */
- int syncpos[4]; /* span-relative sync sources */
- int master; /* Are we master */
+ int syncpos[SPANS_PER_CARD]; /* span-relative sync sources */
+ int master; /* Are we master */
unsigned long plx_region; /* phy addr of PCI9030 registers */
unsigned long plx_len; /* length of PLX window */
volatile unsigned short *plx; /* Virtual representation of local space */
@@ -96,18 +98,18 @@ struct tor2 {
unsigned long xilinx8_region; /* 8 bit Region allocated to Xilinx */
unsigned long xilinx8_len; /* Length of 8 bit Xilinx region */
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(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 */
+ struct zt_span spans[SPANS_PER_CARD]; /* Spans */
+ struct tor2_span tspans[SPANS_PER_CARD]; /* Span data */
+ struct zt_chan *chans[SPANS_PER_CARD]; /* Pointers to blocks of 24(30/31) contiguous zt_chans for each span */
+ struct tor2_chan tchans[32 * SPANS_PER_CARD]; /* Channel user data */
+ unsigned char txsigs[SPANS_PER_CARD][16]; /* Copy of tx sig registers */
+ int loopupcnt[SPANS_PER_CARD]; /* loop up code counter */
+ int loopdowncnt[SPANS_PER_CARD];/* loop down code counter */
int spansstarted; /* number of spans started */
spinlock_t lock; /* lock context */
unsigned char leds; /* copy of LED register */
- unsigned char ec_chunk1[4][32][ZT_CHUNKSIZE]; /* first EC chunk buffer */
- unsigned char ec_chunk2[4][32][ZT_CHUNKSIZE]; /* second EC chunk buffer */
+ unsigned char ec_chunk1[SPANS_PER_CARD][32][ZT_CHUNKSIZE]; /* first EC chunk buffer */
+ unsigned char ec_chunk2[SPANS_PER_CARD][32][ZT_CHUNKSIZE]; /* second EC chunk buffer */
#ifdef ENABLE_TASKLETS
int taskletrun;
int taskletsched;
@@ -205,14 +207,14 @@ static int tor2_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
span->syncsrc = p->tor->syncsrc;
/* remove this span number from the current sync sources, if there */
- for(i = 0; i < 3; i++) {
+ for (i = 0; i < SPANS_PER_CARD; i++) {
if (p->tor->syncs[i] == span->spanno) {
p->tor->syncs[i] = 0;
p->tor->psyncs[i] = 0;
}
}
p->tor->syncpos[p->span] = lc->sync;
- /* if a sync src, put it in proper place */
+ /* if a sync src, put it in the proper place */
if (lc->sync) {
p->tor->syncs[lc->sync - 1] = span->spanno;
p->tor->psyncs[lc->sync - 1] = p->span + 1;
@@ -259,11 +261,17 @@ static int tor2_close(struct zt_chan *chan)
static void init_spans(struct tor2 *tor)
{
- int x,y,c;
- for (x=0;x<4;x++) {
- sprintf(tor->spans[x].name, "Tor2/%d/%d",
- tor->num, x + 1);
- sprintf(tor->spans[x].desc, "Tormenta 2 (PCI) Card %d Span %d", tor->num, x+1);
+ int x, y, c;
+ for (x = 0; x < SPANS_PER_CARD; x++) {
+ sprintf(tor->spans[x].name,
+ "Tor2/%d/%d",
+ tor->num,
+ x + 1);
+ sprintf(tor->spans[x].desc,
+ "Tormenta 2 (PCI) Quad %s Card %d Span %d",
+ (tor->cardtype == TYPE_T1) ? "T1" : "E1",
+ tor->num,
+ x + 1);
tor->spans[x].spanconfig = tor2_spanconfig;
tor->spans[x].chanconfig = tor2_chanconfig;
tor->spans[x].startup = tor2_startup;
@@ -305,7 +313,7 @@ static int __devinit tor2_launch(struct tor2 *tor)
{
if (tor->spans[0].flags & ZT_FLAG_REGISTERED)
return 0;
- printk("tor2: Launching card: %d\n", tor->order);
+ printk("Tor2: Launching card: %d\n", tor->order);
if (zt_register(&tor->spans[0], 0)) {
printk(KERN_ERR "Unable to register span %s\n", tor->spans[0].name);
return -1;
@@ -351,7 +359,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
return -ENOMEM;
memset(tor,0,sizeof(struct tor2));
spin_lock_init(&tor->lock);
- for(x = 0; x < 4; x++) {
+ for (x = 0; x < SPANS_PER_CARD; x++) {
tor->chans[x] = kmalloc(sizeof(struct zt_chan) * 31,GFP_KERNEL);
if (!tor->chans[x])
return -ENOMEM;
@@ -411,7 +419,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
printk("Detected %s at 0x%lx/0x%lx irq %d\n", tor->type,
tor->xilinx32_region, tor->xilinx8_region,tor->irq);
- for(x = 0; x < MAX_TOR_CARDS; x++) {
+ for (x = 0; x < MAX_TOR_CARDS; x++) {
if (!cards[x]) break;
}
if (x >= MAX_TOR_CARDS) {
@@ -454,7 +462,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
/* assert WRITE signal */
gpdata &= ~GPIO_WRITE;
*gpdata_io = cpu_to_le32(gpdata);
- for(x = 0; x < sizeof(tor2fw); x++)
+ for (x = 0; x < sizeof(tor2fw); x++)
{
/* write the byte */
*tor->mem8 = tor2fw[x];
@@ -466,7 +474,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
if (debug) printk("fwload: Transferred %d bytes into chip\n",x);
/* Wait for FIFO to clear */
endjif = jiffies + 2;
- while(jiffies < endjif); /* wait */
+ while (jiffies < endjif); /* wait */
/* de-assert write signal */
gpdata |= GPIO_WRITE;
*gpdata_io = cpu_to_le32(gpdata);
@@ -474,7 +482,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
/* Wait for FIFO to clear */
endjif = jiffies + 2;
- while(jiffies < endjif); /* wait */
+ while (jiffies < endjif); /* wait */
if (!(le32_to_cpu(*gpdata_io) & GPIO_INIT))
{
printk("Drove Init low!! CRC Error!!!\n");
@@ -500,7 +508,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
tor->mem8[CTLREG1] = NONREVA;
}
#endif
- for(x = 0; x < 256; x++) tor->mem32[x] = 0x7f7f7f7f;
+ for (x = 0; x < 256; x++) tor->mem32[x] = 0x7f7f7f7f;
if (request_irq(tor->irq, tor2_intr, SA_INTERRUPT | SA_SHIRQ, "tor2", tor)) {
@@ -524,7 +532,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
/* Launch cards as appropriate */
x = 0;
- for(;;) {
+ for (;;) {
/* Find a card to activate */
f = 0;
for (x=0;cards[x];x++) {
@@ -553,7 +561,7 @@ err_out_free_tor:
if (tor->mem8) iounmap((void *)tor->mem8);
if (tor->mem32) iounmap((void *)tor->mem32);
if (tor) {
- for(x = 0; x < 3; x++) kfree(tor->chans[x]);
+ for (x = 0; x < 3; x++) kfree(tor->chans[x]);
kfree(tor);
}
return -NODEV;
@@ -590,7 +598,7 @@ static void __devexit tor2_remove(struct pci_dev *pdev)
cards[tor->num] = 0;
pci_set_drvdata(pdev, NULL);
- for(x = 0; x < 3; x++)
+ for (x = 0; x < 3; x++)
if (tor->chans[x])
kfree(tor->chans[x]);
kfree(tor);
@@ -619,8 +627,8 @@ static void set_clear(struct tor2 *tor)
{
int i,j,s;
unsigned short val=0;
- for (s=0;s<4;s++) {
- for (i=0;i<24;i++) {
+ for (s = 0; s < SPANS_PER_CARD; s++) {
+ for (i = 0; i < 24; i++) {
j = (i/8);
if (tor->spans[s].chans[i].flags & ZT_FLAG_CLEAR)
val |= 1 << (i % 8);
@@ -737,10 +745,10 @@ static int tor2_shutdown(struct zt_span *span)
if (wasrunning)
p->tor->spansstarted--;
spin_unlock_irqrestore(&p->tor->lock, flags);
- if ((!p->tor->spans[0].flags & ZT_FLAG_RUNNING) &&
- (!p->tor->spans[1].flags & ZT_FLAG_RUNNING) &&
- (!p->tor->spans[2].flags & ZT_FLAG_RUNNING) &&
- (!p->tor->spans[3].flags & ZT_FLAG_RUNNING))
+ if (!(p->tor->spans[0].flags & ZT_FLAG_RUNNING) &&
+ !(p->tor->spans[1].flags & ZT_FLAG_RUNNING) &&
+ !(p->tor->spans[2].flags & ZT_FLAG_RUNNING) &&
+ !(p->tor->spans[3].flags & ZT_FLAG_RUNNING))
/* No longer in use, disable interrupts */
p->tor->mem8[CTLREG] = 0;
if (debug)
@@ -772,14 +780,14 @@ static int tor2_startup(struct zt_span *span)
alreadyrunning = span->flags & ZT_FLAG_RUNNING;
/* initialize the start value for the entire chunk of last ec buffer */
- for(i = 0; i < span->channels; i++)
+ for (i = 0; i < span->channels; i++)
{
memset(p->tor->ec_chunk1[p->span][i],
ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE);
memset(p->tor->ec_chunk2[p->span][i],
ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE);
}
- /* Force re-evaluation fo timing source */
+ /* Force re-evaluation of the timing source */
if (timingcable)
p->tor->syncsrc = -1;
@@ -795,11 +803,17 @@ static int tor2_startup(struct zt_span *span)
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);
+ /* Set up all the spans every time, so we are sure they are
+ in a consistent state. If we don't, a card without all
+ its spans configured misbehaves in strange ways. */
+ t1out(p->tor,1,0xb5,9);
+ t1out(p->tor,2,0xb5,8);
+ t1out(p->tor,3,0xb5,8);
+ t1out(p->tor,4,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);
+ 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 */
@@ -831,12 +845,12 @@ static int tor2_startup(struct zt_span *span)
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);
+ 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 */
+ 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 */
@@ -867,8 +881,13 @@ static int tor2_startup(struct zt_span *span)
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);
+ /* Set up all the spans every time, so we are sure they are
+ in a consistent state. If we don't, a card without all
+ its spans configured misbehaves in strange ways. */
+ t1out(p->tor,1,0x94,9);
+ t1out(p->tor,2,0x94,8);
+ t1out(p->tor,3,0x94,8);
+ t1out(p->tor,4,0x94,8);
/* Full-on Sync required (RCR1) */
t1out(p->tor,tspan, 0x2b, 8);
/* RSYNC is an input (RCR2) */
@@ -915,7 +934,7 @@ static int tor2_startup(struct zt_span *span)
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);
@@ -1010,7 +1029,7 @@ static int tor2_maint(struct zt_span *span, int cmd)
static inline void tor2_run(struct tor2 *tor)
{
int x,y;
- for (x=0;x<4;x++) {
+ for (x = 0; x < SPANS_PER_CARD; x++) {
if (tor->spans[x].flags & ZT_FLAG_RUNNING) {
/* since the Tormenta 2 PCI is double-buffered, you
need to delay the transmit data 2 entire chunks so
@@ -1028,7 +1047,7 @@ static inline void tor2_run(struct tor2 *tor)
zt_receive(&tor->spans[x]);
}
}
- for (x=0;x<4;x++) {
+ for (x = 0; x < SPANS_PER_CARD; x++) {
if (tor->spans[x].flags & ZT_FLAG_RUNNING)
zt_transmit(&tor->spans[x]);
}
@@ -1068,10 +1087,10 @@ static int tor2_findsync(struct tor2 *tor)
/* If we're the first card, go through all the motions, up to 8 levels
of sync source */
p = 1;
- while(p < 8) {
+ while (p < 8) {
nonzero = 0;
for (x=0;cards[x];x++) {
- for (i=0;i<4;i++) {
+ for (i = 0; i < SPANS_PER_CARD; i++) {
if (cards[x]->syncpos[i]) {
nonzero = 1;
if ((cards[x]->syncpos[i] == p) &&
@@ -1105,7 +1124,7 @@ found:
if (tor->syncsrc != syncsrc) {
tor->syncsrc = syncsrc;
/* Update sync sources */
- for(i = 0; i < 4; i++) {
+ for (i = 0; i < SPANS_PER_CARD; i++) {
tor->spans[i].syncsrc = tor->syncsrc;
}
if (syncnum == tor->num) {
@@ -1156,8 +1175,8 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
#endif
/* do the transmit output */
- for(n = 0; n < tor->spans[0].channels; n++) {
- for(i = 0; i < ZT_CHUNKSIZE; i++) {
+ 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;
/* span 2 */
@@ -1172,8 +1191,8 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
/* Do the receive input */
- for(n = 0; n < tor->spans[0].channels; n++) {
- for(i = 0; i < ZT_CHUNKSIZE; i++) {
+ for (n = 0; n < tor->spans[0].channels; n++) {
+ for (i = 0; i < ZT_CHUNKSIZE; i++) {
/* read from */
rxword = le32_to_cpu(tor->mem32[tor->datxlt[n] + (32 * i)]);
/* span 1 */
@@ -1190,9 +1209,8 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
i = tor->passno & 15;
/* if an E1 card, do rx signalling for it */
if ((i < 3) && (tor->cardtype == TYPE_E1)) { /* if an E1 card */
- for(j = (i * 5); j < (i * 5) + 5; j++)
- {
- for(k = 1; k <= 4; k++) {
+ for (j = (i * 5); j < (i * 5) + 5; j++) {
+ for (k = 1; k <= SPANS_PER_CARD; k++) {
c = t1in(tor,k,0x31 + j);
rxc = c & 15;
if (rxc != tor->spans[k - 1].chans[j + 16].rxsig) {
@@ -1231,7 +1249,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
}
- for(i = 0; i < 4; i++) { /* Go thru all 4 spans */
+ for (i = 0; i < SPANS_PER_CARD; i++) { /* Go thru all the spans */
/* if alarm timer, and it's timed out */
if (tor->alarmtimer[i]) {
if (!--tor->alarmtimer[i]) {
@@ -1308,7 +1326,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 < tor->spans[i].channels; 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++;
@@ -1347,14 +1365,24 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
if (!(tor->passno % 1000)) /* even second boundary */
{
/* do all spans */
- for(i = 1; i <= 4; i++)
+ for (i = 1; i <= SPANS_PER_CARD; i++)
{
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);
+ if (tor->spans[i - 1].lineconfig & ZT_CONFIG_CRC4)
+ {
+ tor->spans[i - 1].crc4count += t1in(tor,i,3) + ((t1in(tor,i,2) & 3) << 8);
+ tor->spans[i - 1].ebitcount += t1in(tor,i,5) + ((t1in(tor,i,4) & 3) << 8);
+ }
+ tor->spans[i - 1].fascount += (t1in(tor,i,4) >> 2) + ((t1in(tor,i,2) & 0x3F) << 6);
+ }
else
+ {
/* add this second's BPV count to total one */
tor->spans[i - 1].bpvcount += t1in(tor,i,0x24) + (t1in(tor,i,0x23) << 8);
+ }
}
}
if (!timingcable) {
@@ -1372,7 +1400,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
}
/* if any others specified, see if we can use them */
- for(i = 1; i < 4; i++) {
+ for (i = 1; i < SPANS_PER_CARD; i++) {
/* if we dont have one yet, and there is one specified at this level, see if we can use it */
if ((!tor->syncsrc) && (tor->psyncs[i])) {
/* if no alarms, use it */
@@ -1384,7 +1412,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
}
/* update sync src info */
- for(i = 0; i < 4; i++) tor->spans[i].syncsrc = syncsrc;
+ for (i = 0; i < SPANS_PER_CARD; i++) tor->spans[i].syncsrc = syncsrc;
/* actually set the sync register */
tor->mem8[SYNCREG] = tor->syncsrc;
@@ -1424,7 +1452,7 @@ static int tor2_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data
}
MODULE_AUTHOR("Mark Spencer");
-MODULE_DESCRIPTION("Tormenta 2 PCI Driver");
+MODULE_DESCRIPTION("Tormenta 2 PCI Quad T1 or E1 Zaptel Driver");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif