summaryrefslogtreecommitdiff
path: root/wct4xxp.c
diff options
context:
space:
mode:
authorjim <jim@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-04-23 02:10:18 +0000
committerjim <jim@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-04-23 02:10:18 +0000
commit709e2be4a4ed3ea6ef77ec79f9e8101ba56426fa (patch)
tree110e5800c9527a863e47f90d1cae3a3a13d81cfb /wct4xxp.c
parentef96b440e1e3ab30938d2e04ff6dbcacaf72ec29 (diff)
Fixed problems in wct4xxp driver, and added error/alarm processing to patgen and pattest (Jim D)
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@370 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct4xxp.c')
-rwxr-xr-xwct4xxp.c219
1 files changed, 40 insertions, 179 deletions
diff --git a/wct4xxp.c b/wct4xxp.c
index 64b654a..9785c53 100755
--- a/wct4xxp.c
+++ b/wct4xxp.c
@@ -72,6 +72,7 @@ static int altab[] = {
#define FLAG_NMF (1 << 1)
#define FLAG_SENDINGYELLOW (1 << 2)
+
#define TYPE_T1 1 /* is a T1 card */
#define TYPE_E1 2 /* is an E1 card */
@@ -138,6 +139,7 @@ struct t4 {
int checktiming; /* Set >0 to cause the timing source to be checked */
};
+
static void __set_clear(struct t4 *wc, int span);
static int t4_startup(struct zt_span *span);
static int t4_shutdown(struct zt_span *span);
@@ -145,7 +147,7 @@ static int t4_rbsbits(struct zt_chan *chan, int bits);
static int t4_maint(struct zt_span *span, int cmd);
static int t4_reset_dma(struct t4 *wc);
static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data);
-static void __t4_set_timing_source_auto(struct t4 *wc);
+static void __t4_set_timing_source(struct t4 *wc, int unit);
#define WC_RDADDR 0
#define WC_WRADDR 1
@@ -376,7 +378,7 @@ static int t4_maint(struct zt_span *span, int cmd)
t4_framer_out(wc, span->offset, 0x21, 0x40); /* FMR5: Nothing but RBS mode */
break;
default:
- printk("TE410P: Unknown T1 maint command: %d\n", cmd);
+ printk("TE410P: Unknown E1 maint command: %d\n", cmd);
break;
}
}
@@ -390,8 +392,8 @@ static int t4_rbsbits(struct zt_chan *chan, int bits)
struct t4 *wc = chan->pvt;
unsigned long flags;
- if(debug) printk("Setting bits to %d on channel %s\n", bits, chan->name);
spin_lock_irqsave(&wc->reglock, flags);
+ if(debug) printk("Setting bits to %d on channel %s\n", bits, chan->name);
k = chan->span->offset;
if (wc->spantype[k] == TYPE_E1) { /* do it E1 way */
if (chan->chanpos == 16) {
@@ -430,9 +432,9 @@ static int t4_rbsbits(struct zt_chan *chan, int bits)
/* output them to the chip */
__t4_framer_out(wc,k,0x70 + b,c);
}
- spin_unlock_irqrestore(&wc->reglock, flags);
if (debug)
printk("Finished setting RBS bits\n");
+ spin_unlock_irqrestore(&wc->reglock, flags);
return 0;
}
@@ -466,9 +468,8 @@ static int t4_shutdown(struct zt_span *span)
__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
/* Acknowledge any pending interrupts */
__t4_pci_out(wc, WC_INTR, 0x00000000);
- __t4_set_timing_source_auto(wc);
- } else
- wc->checktiming = 1;
+ __t4_set_timing_source(wc,4);
+ } else wc->checktiming = 1;
spin_unlock_irqrestore(&wc->reglock, flags);
if (debug)
printk("Span %d (%s) shutdown\n", span->spanno, span->name);
@@ -487,13 +488,9 @@ static int t4_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
span->txlevel = lc->lbo;
span->rxlevel = 0;
span->syncsrc = wc->syncsrc;
- if (lc->sync < 0)
- lc->sync = 0;
- if (lc->sync > 4)
- lc->sync = 0;
/* remove this span number from the current sync sources, if there */
- for(i = 0; i < 4; i++) {
+ for(i = 0; i < 3; i++) {
if (wc->syncs[i] == span->spanno) {
wc->syncs[i] = 0;
wc->psyncs[i] = 0;
@@ -508,7 +505,6 @@ static int t4_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
/* If we're already running, then go ahead and apply the changes */
if (span->flags & ZT_FLAG_RUNNING)
return t4_startup(span);
- wc->checktiming = 1;
return 0;
}
@@ -583,7 +579,7 @@ static void init_spans(struct t4 *wc)
struct zt_chan *mychans = wc->chans[x] + y;
sprintf(mychans->name, "TE4/%d/%d/%d", wc->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 | ZT_SIG_CAS | ZT_SIG_EM_E1;
+ ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS;
c = (x * wc->spans[x].channels) + y;
mychans->pvt = wc;
mychans->chanpos = y + 1;
@@ -637,47 +633,30 @@ static void __t4_set_timing_source(struct t4 *wc, int unit)
{
unsigned int timing;
int x;
- int updated = 0;
- wc->checktiming = 0;
timing = 0x34; /* CMR1: RCLK unit, 8.192 Mhz TCLK, RCLK is 8.192 Mhz */
- if (unit != wc->syncsrc) {
- if ((unit > -1) && (unit < 4)) {
- timing |= (unit << 6);
- } else {
- timing |= 0x1; /* Use TCLK timing */
- }
- for (x=0;x<4;x++)
- __t4_framer_out(wc, x, 0x44, timing);
- if ((unit > -1) && (unit < 4)) {
- __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl | (1 << 29));
- /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from proper channel, */
- __t4_framer_out(wc, 0, 0x85, 0xe0 | (unit << 2) | (unit));
- } else
- __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
- updated = 1;
- }
- wc->syncsrc = unit;
- if ((unit < 0) || (unit > 3))
- unit = 0;
- else
- unit++;
- for (x=0;x<4;x++)
- wc->spans[x].syncsrc = unit;
- if (updated) {
- if (unit)
- printk("TE410P: Timing from span %d\n", unit);
- else
- printk("TE410P: Timing from internal timer\n");
+ if ((unit > -1) && (unit < 4)) {
+ timing |= (unit << 6);
+ for (x=0;x<4;x++) /* set all 4 receive reference clocks to unit */
+ t4_framer_out(wc, x, 0x44, timing);
+ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl | (1 << 29));
+ } else {
+ for (x=0;x<4;x++) /* set each receive reference clock to itself */
+ t4_framer_out(wc, x, 0x44, timing | (x << 6));
+ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
}
+#if 0
+ printk("wct4xxp: Timing source set to %d\n",unit);
+#endif
}
static void __t4_set_timing_source_auto(struct t4 *wc)
{
int x;
+ wc->checktiming = 0;
for (x=0;x<4;x++) {
if (wc->syncs[x]) {
if ((wc->spans[wc->syncs[x] - 1].flags & ZT_FLAG_RUNNING) &&
- !(wc->spans[wc->syncs[x] - 1].alarms & ~(ZT_ALARM_YELLOW))) {
+ !(wc->spans[wc->syncs[x] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_NOTOPEN) )) {
/* Valid timing sourc e*/
__t4_set_timing_source(wc, wc->syncs[x] - 1);
return;
@@ -687,14 +666,6 @@ static void __t4_set_timing_source_auto(struct t4 *wc)
__t4_set_timing_source(wc, 4);
}
-static void t4_set_timing_source_auto(struct t4 *wc)
-{
- unsigned long flags;
- spin_lock_irqsave(&wc->reglock, flags);
- __t4_set_timing_source_auto(wc);
- spin_unlock_irqrestore(&wc->reglock, flags);
-}
-
static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel)
{
unsigned int fmr4, fmr2, fmr1, fmr0, lim2;
@@ -877,10 +848,7 @@ static int t4_startup(struct zt_span *span)
}
if (!alreadyrunning) {
- /* Never trust timing from something we're just starting. Let it settle first. */
- span->alarms |= ZT_ALARM_RECOVER;
span->flags |= ZT_FLAG_RUNNING;
- wc->alarmtimer[span->offset] = ZT_ALARMSETTLE_TIME;
wc->spansstarted++;
/* enable interrupts */
/* Start DMA, enabling DMA interrupts on read only */
@@ -893,87 +861,9 @@ static int t4_startup(struct zt_span *span)
if (wc->syncs[1] == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
if (wc->syncs[2] == span->spanno) printk("SPAN %d: Tertiary Sync Source\n",span->spanno);
if (wc->syncs[3] == span->spanno) printk("SPAN %d: Quaternary Sync Source\n",span->spanno);
- wc->checktiming = 1;
return 0;
}
-#if 0
-static int syncsrc = 0;
-static int syncnum = 0 /* -1 */;
-static int syncspan = 0;
-static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
-
-static int t4_findsync(struct t4 *wc)
-{
- int i;
- int x;
- unsigned long flags;
- int p;
- int nonzero;
- int newsyncsrc = 0; /* Zaptel span number */
- int newsyncnum = 0; /* t4xxp card number */
- int newsyncspan = 0; /* span on given t4xxp card */
- spin_lock_irqsave(&synclock, flags);
-#if 1
- if (!wc->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 (wc->syncsrc != syncsrc) {
- wc->syncsrc = syncsrc;
- /* Update sync sources */
- for(i = 0; i < 4; i++) {
- wc->spans[i].syncsrc = wc->syncsrc;
- }
- if (syncnum == wc->num) {
- printk("XXX Set sync span to %d XXX\n", syncspan);
- if (debug) printk("Card %d, using sync span %d, master\n", wc->num, syncspan);
- wc->master = 1;
- } else {
- printk("XXX Set timing from external cable XXX\n");
- wc->master = 0;
- if (debug) printk("Card %d, using Timing Bus, NOT master\n", wc->num);
- }
- }
- spin_unlock_irqrestore(&synclock, flags);
- return 0;
-}
-#endif
-
static inline void e1_check(struct t4 *wc, int span, int val)
{
if ((wc->spans[span].channels > 24) &&
@@ -1187,7 +1077,6 @@ static void __t4_do_counters(struct t4 *wc)
if (wc->alarmtimer[span]) {
if (!--wc->alarmtimer[span]) {
wc->spans[span].alarms &= ~(ZT_ALARM_RECOVER);
- wc->checktiming = 1;
zt_alarm_notify(&wc->spans[span]);
}
}
@@ -1197,7 +1086,7 @@ static void __t4_do_counters(struct t4 *wc)
static void __t4_check_alarms(struct t4 *wc, int span)
{
unsigned char c,d;
- int alarms, oldalarms;
+ int alarms;
int x,j;
if (!(wc->spans[span].flags & ZT_FLAG_RUNNING))
@@ -1208,8 +1097,6 @@ static void __t4_check_alarms(struct t4 *wc, int span)
/* Assume no alarms */
alarms = 0;
-
- oldalarms = wc->spans[span].alarms;
/* And consider only carrier alarms */
wc->spans[span].alarms &= (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_NOTOPEN);
@@ -1266,15 +1153,15 @@ static void __t4_check_alarms(struct t4 *wc, int span)
alarms |= ZT_ALARM_NOTOPEN;
}
- if (c & 0xa0) {
- if (wc->redalarms[span] > 10)
- alarms |= ZT_ALARM_RED;
- else
- wc->redalarms[span]++;
- } else
- wc->redalarms[span] = 0;
+ if (c & 0xa0)
+ alarms |= ZT_ALARM_RED;
if (c & 0x4)
alarms |= ZT_ALARM_BLUE;
+
+ if (((!wc->spans[span].alarms) && alarms) ||
+ (wc->spans[span].alarms && (!alarms)))
+ wc->checktiming = 1;
+
/* Keep track of recovering */
if ((!alarms) && wc->spans[span].alarms)
wc->alarmtimer[span] = ZT_ALARMSETTLE_TIME;
@@ -1291,7 +1178,7 @@ static void __t4_check_alarms(struct t4 *wc, int span)
fmr4 = __t4_framer_in(wc, span, 0x20);
__t4_framer_out(wc, span, 0x20, fmr4 | 0x20);
wc->spanflags[span] |= FLAG_SENDINGYELLOW;
- } else if (!alarms && wc->spanflags[span] & FLAG_SENDINGYELLOW) {
+ } else if ((!alarms) && (wc->spanflags[span] & FLAG_SENDINGYELLOW)) {
unsigned char fmr4;
#if 1
printk("wct4xxp: Clearing yellow alarm on span %d\n", span + 1);
@@ -1302,37 +1189,13 @@ static void __t4_check_alarms(struct t4 *wc, int span)
wc->spanflags[span] &= ~FLAG_SENDINGYELLOW;
}
-#if 0
- if (wc->spans[span].alarms != alarms) {
- d = __control_get_reg(wc, WC_CLOCK);
- start_alarm(wc);
- if (!(alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_LOOPBACK)) &&
- wc->sync) {
- /* Use the recieve signalling */
- wc->spans[span].syncsrc = wc->spans[span].spanno;
- d |= 1;
- } else {
- wc->spans[span].syncsrc = 0;
- d &= ~1;
- }
- __control_set_reg(wc, WC_CLOCK, d);
- }
-#endif
-
+ /* Re-check the timing source when we enter/leave alarm, not withstanding
+ yellow alarm */
if (c & 0x10)
alarms |= ZT_ALARM_YELLOW;
-
if (wc->spans[span].mainttimer || wc->spans[span].maintstat)
alarms |= ZT_ALARM_LOOPBACK;
-
wc->spans[span].alarms = alarms;
- /* Re-check the timing source when we enter/leave alarm, not withstanding
- yellow alarm */
- oldalarms &= ~ZT_ALARM_YELLOW;
- alarms &= ~ZT_ALARM_YELLOW;
- if ((!oldalarms && alarms) || (oldalarms && !alarms))
- wc->checktiming = 1;
-
zt_alarm_notify(&wc->spans[span]);
}
@@ -1482,12 +1345,6 @@ static void t4_interrupt(int irq, void *dev_id, struct pt_regs *regs)
break;
}
-#if 0
- /* periodically check timing */
- if (!(wc->intcount % (8000/ZT_CHUNKSIZE)))
- wc->checktiming = 1;
-#endif
-
if (wc->checktiming > 0)
__t4_set_timing_source_auto(wc);
spin_unlock_irqrestore(&wc->reglock, flags);
@@ -1593,7 +1450,12 @@ static int __devinit t4_launch(struct t4 *wc)
zt_unregister(&wc->spans[2]);
return -1;
}
+ if (debug)
+ printk("Setting timing source\n");
+ if (debug)
+ printk("Timing source selected\n");
wc->checktiming = 1;
+ __t4_set_timing_source(wc,4);
#ifdef ENABLE_TASKLETS
tasklet_init(&wc->t4_tlet, t4_tasklet, (unsigned long)wc);
#endif
@@ -1623,7 +1485,6 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
wc->memaddr = pci_resource_start(pdev, 0);
wc->memlen = pci_resource_len(pdev, 0);
wc->membase = ioremap(wc->memaddr, wc->memlen);
- wc->checktiming = 0;
/* This rids of the Double missed interrupt message after loading */
wc->last0 = 1;
#if 0