summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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