summaryrefslogtreecommitdiff
path: root/tor2.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-12-16 19:15:20 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-12-16 19:15:20 +0000
commit1ab5fa38aab79228f241525048c48425274d1287 (patch)
treedbed804fb667043a8caa29502197ec84b484b530 /tor2.c
parent145d11e3a9c8ed59c566c2ad7a4858bbc3bc7121 (diff)
Version 0.4.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@138 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'tor2.c')
-rwxr-xr-xtor2.c165
1 files changed, 131 insertions, 34 deletions
diff --git a/tor2.c b/tor2.c
index 4eb0847..8b3e64e 100755
--- a/tor2.c
+++ b/tor2.c
@@ -85,6 +85,8 @@ struct tor2 {
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 */
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 */
@@ -142,6 +144,8 @@ static void tor2_tasklet(unsigned long data);
#define E1DIV 0x10
#define INTACK (0x80 + ((loopback & 3) << 5))
#define INTACTIVE 2
+#define MASTER (1 << 3)
+
/* un-define this if you dont want NON-REV A hardware support */
/* #define NONREVA 1 */
@@ -150,6 +154,7 @@ static void tor2_tasklet(unsigned long data);
#define SYNC2 2
#define SYNC3 3
#define SYNC4 4
+#define SYNCEXTERN 5
#define LEDRED 2
#define LEDGREEN 1
@@ -165,6 +170,7 @@ struct tor2 *cards[MAX_TOR_CARDS];
static int debug;
static int loopback;
static int highestorder;
+static int timingcable;
static void set_clear(struct tor2 *tor);
static int tor2_startup(struct zt_span *span);
@@ -204,6 +210,7 @@ static int tor2_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
p->tor->psyncs[i] = 0;
}
}
+ p->tor->syncpos[p->span] = lc->sync;
/* if a sync src, put it in proper place */
if (lc->sync) {
p->tor->syncs[lc->sync - 1] = span->spanno;
@@ -770,12 +777,17 @@ static int tor2_startup(struct zt_span *span)
memset(p->tor->ec_chunk2[p->span][i],
ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE);
}
+ /* Force re-evaluation fo timing source */
+ if (timingcable)
+ p->tor->syncsrc = -1;
+
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;
+ /* Force re-evaluation of sync src */
/* Zero out all registers */
for (i = 0; i < 192; i++)
t1out(p->tor,tspan, i, 0);
@@ -1030,6 +1042,87 @@ static void tor2_tasklet(unsigned long data)
}
#endif
+static int syncsrc = 0;
+static int syncnum = 0 /* -1 */;
+static int syncspan = 0;
+static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
+
+static int tor2_findsync(struct tor2 *tor)
+{
+ int i;
+ int x;
+ long flags;
+ int p;
+ int nonzero;
+ int newsyncsrc = 0; /* Zaptel span number */
+ int newsyncnum = 0; /* tor2 card number */
+ int newsyncspan = 0; /* span on given tor2 card */
+ spin_lock_irqsave(&synclock, flags);
+#if 1
+ if (!tor->num) {
+ /* If we're the first card, go through all the motions, up to 8 levels
+ of sync source */
+ p = 1;
+ while(p < 8) {
+ nonzero = 0;
+ for (x=0;cards[x];x++) {
+ for (i=0;i<4;i++) {
+ if (cards[x]->syncpos[i]) {
+ nonzero = 1;
+ if ((cards[x]->syncpos[i] == p) &&
+ !(cards[x]->spans[i].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_LOOPBACK)) &&
+ (cards[x]->spans[i].flags & ZT_FLAG_RUNNING)) {
+ /* This makes a good sync source */
+ newsyncsrc = cards[x]->spans[i].spanno;
+ newsyncnum = x;
+ newsyncspan = i + 1;
+ /* Jump out */
+ goto found;
+ }
+ }
+ }
+ }
+ if (nonzero)
+ p++;
+ else
+ break;
+ }
+found:
+ if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) {
+ syncnum = newsyncnum;
+ syncsrc = newsyncsrc;
+ syncspan = newsyncspan;
+ if (debug) printk("New syncnum: %d, syncsrc: %d, syncspan: %d\n", syncnum, syncsrc, syncspan);
+ }
+ }
+#endif
+ /* update sync src info */
+ if (tor->syncsrc != syncsrc) {
+ tor->syncsrc = syncsrc;
+ /* Update sync sources */
+ for(i = 0; i < 4; i++) {
+ tor->spans[i].syncsrc = tor->syncsrc;
+ }
+ if (syncnum == tor->num) {
+#if 1
+ /* actually set the sync register */
+ tor->mem8[SYNCREG] = syncspan;
+#endif
+ if (debug) printk("Card %d, using sync span %d, master\n", tor->num, syncspan);
+ tor->master = MASTER;
+ } else {
+#if 1
+ /* time from the timing cable */
+ tor->mem8[SYNCREG] = SYNCEXTERN;
+#endif
+ tor->master = 0;
+ if (debug) printk("Card %d, using Timing Bus, NOT master\n", tor->num);
+ }
+ }
+ spin_unlock_irqrestore(&synclock, flags);
+ return 0;
+}
+
static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
{
int n, i, j, k, syncsrc;
@@ -1047,10 +1140,10 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
if (tor->cardtype == TYPE_E1)
/* set outbit, interrupt enable, and ack interrupt */
- tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | E1DIV;
+ tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | E1DIV | tor->master;
else
/* set outbit, interrupt enable, and ack interrupt */
- tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK;
+ tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | tor->master;
#if 0
if (!tor->passno)
@@ -1089,7 +1182,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
}
- i = tor->passno & 63;
+ 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++)
@@ -1148,11 +1241,11 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
}
}
- i = tor->passno & 63;
- if ((i >= 50) && (i <= 53))
+ i = tor->passno & 15;
+ if ((i >= 10) && (i <= 13))
{
j = 0; /* clear this alarm status */
- i -= 50;
+ i -= 10;
if (tor->cardtype == TYPE_T1) {
c = t1in(tor,i + 1,0x31); /* get RIR2 */
tor->spans[i].rxlevel = c >> 6; /* get rx level */
@@ -1259,36 +1352,39 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
tor->spans[i - 1].bpvcount += t1in(tor,i,0x24) + (t1in(tor,i,0x23) << 8);
}
}
- /* re-evaluate active sync src */
- tor->syncsrc = 0;
- syncsrc = 0;
- /* if primary sync specified, see if we can use it */
- if (tor->psyncs[0])
- {
- /* if no alarms, use it */
- if (!(tor->spans[tor->psyncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE |
- ZT_ALARM_LOOPBACK))) {
- tor->syncsrc = tor->psyncs[0];
- syncsrc = tor->syncs[0];
- }
- }
- /* if any others specified, see if we can use them */
- for(i = 1; i < 4; 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 (!timingcable) {
+ /* re-evaluate active sync src (no cable version) */
+ tor->syncsrc = 0;
+ syncsrc = 0;
+ /* if primary sync specified, see if we can use it */
+ if (tor->psyncs[0])
+ {
/* if no alarms, use it */
- if (!(tor->spans[tor->psyncs[i] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE |
+ if (!(tor->spans[tor->psyncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE |
ZT_ALARM_LOOPBACK))) {
- tor->syncsrc = tor->psyncs[i];
- syncsrc = tor->syncs[i];
+ tor->syncsrc = tor->psyncs[0];
+ syncsrc = tor->syncs[0];
}
+ }
+ /* if any others specified, see if we can use them */
+ for(i = 1; i < 4; 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 */
+ if (!(tor->spans[tor->psyncs[i] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE |
+ ZT_ALARM_LOOPBACK))) {
+ tor->syncsrc = tor->psyncs[i];
+ syncsrc = tor->syncs[i];
+ }
+ }
}
- }
- /* update sync src info */
- for(i = 0; i < 4; i++) tor->spans[i].syncsrc = syncsrc;
+ /* update sync src info */
+ for(i = 0; i < 4; i++) tor->spans[i].syncsrc = syncsrc;
- /* actually set the sync register */
- tor->mem8[SYNCREG] = tor->syncsrc;
+ /* actually set the sync register */
+ tor->mem8[SYNCREG] = tor->syncsrc;
+ } else /* Timing cable version */
+ tor2_findsync(tor);
tor->passno++;
@@ -1303,13 +1399,13 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)
#else
tor2_run(tor);
#endif
-
+ /* We are not the timing bus master */
if (tor->cardtype == TYPE_E1)
/* clear OUTBIT and enable interrupts */
- tor->mem8[CTLREG] = INTENA | E1DIV;
+ tor->mem8[CTLREG] = INTENA | E1DIV | tor->master;
else
/* clear OUTBIT and enable interrupts */
- tor->mem8[CTLREG] = INTENA;
+ tor->mem8[CTLREG] = INTENA | tor->master;
}
@@ -1329,6 +1425,7 @@ MODULE_LICENSE("GPL");
#endif
MODULE_PARM(debug, "i");
MODULE_PARM(loopback, "i");
+MODULE_PARM(timingcable, "i");
MODULE_DEVICE_TABLE(pci, tor2_pci_ids);