summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Meyerriecks <rmeyerreicks@digium.com>2010-02-22 16:18:45 +0000
committerRuss Meyerriecks <rmeyerreicks@digium.com>2010-02-22 16:18:45 +0000
commita0e532fc44b63d9996b16ca7329d9a98e04e3362 (patch)
treea1bab9d8538cf26f8661e4a2602cc5f2102ce82e
parentc6190b93918fa1bc174d7fdfb87cc6e9425eddb5 (diff)
Branch merge from the maintenance modes project
* Added logic for both the single and dual/quad span cards for supporting local loopback (virtual loopback plug), network loopback, network payload loopback, loopup, and loopback transmitting. * Added logic for the dual/quad span driver to support exporting the performance and error counters including : - errored seconds - framing errors - coding violations - bipolar violations - crc4 errors - ebit errors - fas errors * Moved the error and performance counters into a substructure for all drivers taking advantage of dahdi_span bpvcount. * Modified the DAHDI_SPANSTAT ioctl interface, so I moved the old interface to DAHDI_SPANSTAT_V1. The new interface comes with a nice, new shiny packed struct dahdi_spaninfo. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8061 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/dahdi-base.c115
-rw-r--r--drivers/dahdi/tor2.c20
-rw-r--r--drivers/dahdi/wct4xxp/base.c211
-rw-r--r--drivers/dahdi/wcte12xp/base.c29
-rw-r--r--drivers/dahdi/wcte12xp/wcte12xp.h7
-rw-r--r--include/dahdi/kernel.h5
-rw-r--r--include/dahdi/user.h53
7 files changed, 379 insertions, 61 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 0fe4130..30668e6 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -670,21 +670,21 @@ static int dahdi_proc_read(char *page, char **start, off_t off, int count, int *
(spans[span]->syncsrc == spans[span]->spanno))
len += snprintf(page + len, count - len, "ClockSource ");
len += snprintf(page + len, count - len, "\n");
- if (spans[span]->bpvcount)
+ if (spans[span]->count.bpv)
len += snprintf(page + len, count - len, "\tBPV count: %d\n",
- spans[span]->bpvcount);
- if (spans[span]->crc4count)
+ spans[span]->count.bpv);
+ if (spans[span]->count.crc4)
len += snprintf(page + len, count - len,
"\tCRC4 error count: %d\n",
- spans[span]->crc4count);
- if (spans[span]->ebitcount)
+ spans[span]->count.crc4);
+ if (spans[span]->count.ebit)
len += snprintf(page + len, count - len,
"\tE-bit error count: %d\n",
- spans[span]->ebitcount);
- if (spans[span]->fascount)
+ spans[span]->count.ebit);
+ if (spans[span]->count.fas)
len += snprintf(page + len, count - len,
"\tFAS error count: %d\n",
- spans[span]->fascount);
+ spans[span]->count.fas);
if (spans[span]->irqmisses)
len += snprintf(page + len, count - len,
"\tIRQ misses: %d\n",
@@ -3679,9 +3679,11 @@ cleanup:
static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long data, int unit)
{
union {
+ struct dahdi_spaninfo_v1 spaninfo_v1;
struct dahdi_spaninfo spaninfo;
struct dahdi_params param;
} stack;
+
struct dahdi_chan *chan;
unsigned long flags;
int i,j;
@@ -3834,12 +3836,9 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long
dahdi_copy_string(stack.spaninfo.desc, spans[i]->desc, sizeof(stack.spaninfo.desc));
dahdi_copy_string(stack.spaninfo.name, spans[i]->name, sizeof(stack.spaninfo.name));
stack.spaninfo.alarms = spans[i]->alarms; /* get alarm status */
- stack.spaninfo.bpvcount = spans[i]->bpvcount; /* get BPV count */
stack.spaninfo.rxlevel = spans[i]->rxlevel; /* get rx level */
stack.spaninfo.txlevel = spans[i]->txlevel; /* get tx level */
- stack.spaninfo.crc4count = spans[i]->crc4count; /* get CRC4 error count */
- stack.spaninfo.ebitcount = spans[i]->ebitcount; /* get E-bit error count */
- stack.spaninfo.fascount = spans[i]->fascount; /* get FAS error count */
+ stack.spaninfo.count = spans[i]->count; /* get counters */
stack.spaninfo.irqmisses = spans[i]->irqmisses; /* get IRQ miss count */
stack.spaninfo.syncsrc = spans[i]->syncsrc; /* get active sync source */
stack.spaninfo.totalchans = spans[i]->channels;
@@ -3865,6 +3864,75 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long
if (copy_to_user(user_data, &stack.spaninfo, size_to_copy))
return -EFAULT;
break;
+ case DAHDI_SPANSTAT_V1:
+ size_to_copy = sizeof(struct dahdi_spaninfo_v1);
+ if (copy_from_user(&stack.spaninfo_v1,
+ (struct dahdi_spaninfo_v1 *) data,
+ size_to_copy))
+ return -EFAULT;
+ i = stack.spaninfo_v1.spanno; /* get specified span number */
+ if ((i < 0) || (i >= maxspans))
+ return -EINVAL; /* if bad span no */
+ if (i == 0) {
+ /* if to figure it out for this chan */
+ if (!chans[unit])
+ return -EINVAL;
+ i = chans[unit]->span->spanno;
+ }
+ if (!spans[i])
+ return -EINVAL;
+ stack.spaninfo_v1.spanno = i; /* put the span # in here */
+ stack.spaninfo_v1.totalspans = 0;
+ if (maxspans) /* put total number of spans here */
+ stack.spaninfo_v1.totalspans = maxspans - 1;
+ dahdi_copy_string(stack.spaninfo_v1.desc,
+ spans[i]->desc,
+ sizeof(stack.spaninfo_v1.desc));
+ dahdi_copy_string(stack.spaninfo_v1.name,
+ spans[i]->name,
+ sizeof(stack.spaninfo_v1.name));
+ stack.spaninfo_v1.alarms = spans[i]->alarms;
+ stack.spaninfo_v1.bpvcount = spans[i]->count.bpv;
+ stack.spaninfo_v1.rxlevel = spans[i]->rxlevel;
+ stack.spaninfo_v1.txlevel = spans[i]->txlevel;
+ stack.spaninfo_v1.crc4count = spans[i]->count.crc4;
+ stack.spaninfo_v1.ebitcount = spans[i]->count.ebit;
+ stack.spaninfo_v1.fascount = spans[i]->count.fas;
+ stack.spaninfo_v1.irqmisses = spans[i]->irqmisses;
+ stack.spaninfo_v1.syncsrc = spans[i]->syncsrc;
+ stack.spaninfo_v1.totalchans = spans[i]->channels;
+ stack.spaninfo_v1.numchans = 0;
+ for (j = 0; j < spans[i]->channels; j++) {
+ if (spans[i]->chans[j]->sig)
+ stack.spaninfo_v1.numchans++;
+ }
+ stack.spaninfo_v1.lbo = spans[i]->lbo;
+ stack.spaninfo_v1.lineconfig = spans[i]->lineconfig;
+ stack.spaninfo_v1.irq = spans[i]->irq;
+ stack.spaninfo_v1.linecompat = spans[i]->linecompat;
+ dahdi_copy_string(stack.spaninfo_v1.lboname,
+ dahdi_lboname(spans[i]->lbo),
+ sizeof(stack.spaninfo_v1.lboname));
+ if (spans[i]->manufacturer)
+ dahdi_copy_string(stack.spaninfo_v1.manufacturer,
+ spans[i]->manufacturer,
+ sizeof(stack.spaninfo_v1.manufacturer));
+ if (spans[i]->devicetype)
+ dahdi_copy_string(stack.spaninfo_v1.devicetype,
+ spans[i]->devicetype,
+ sizeof(stack.spaninfo_v1.devicetype));
+ dahdi_copy_string(stack.spaninfo_v1.location,
+ spans[i]->location,
+ sizeof(stack.spaninfo_v1.location));
+ if (spans[i]->spantype)
+ dahdi_copy_string(stack.spaninfo_v1.spantype,
+ spans[i]->spantype,
+ sizeof(stack.spaninfo_v1.spantype));
+
+ if (copy_to_user((struct dahdi_spaninfo_v1 *) data,
+ &stack.spaninfo_v1, size_to_copy))
+ return -EFAULT;
+ break;
case DAHDI_CHANDIAG_V1: /* Intentional drop through. */
case DAHDI_CHANDIAG:
{
@@ -4423,7 +4491,8 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
switch(maint.command) {
case DAHDI_MAINT_NONE:
case DAHDI_MAINT_LOCALLOOP:
- case DAHDI_MAINT_REMOTELOOP:
+ case DAHDI_MAINT_NETWORKLINELOOP:
+ case DAHDI_MAINT_NETWORKPAYLOADLOOP:
/* if same, ignore it */
if (i == maint.command)
break;
@@ -4445,8 +4514,26 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
return rv;
spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
break;
+ case DAHDI_MAINT_FAS_DEFECT:
+ case DAHDI_MAINT_MULTI_DEFECT:
+ case DAHDI_MAINT_CRC_DEFECT:
+ case DAHDI_MAINT_CAS_DEFECT:
+ case DAHDI_MAINT_PRBS_DEFECT:
+ case DAHDI_MAINT_BIPOLAR_DEFECT:
+ case DAHDI_MAINT_PRBS:
+ case DAHDI_RESET_COUNTERS:
+ rv = spans[maint.spanno]->maint(spans[maint.spanno],
+ maint.command);
+ spin_unlock_irqrestore(&spans[maint.spanno]->lock,
+ flags);
+ if (rv)
+ return rv;
+ spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
+ break;
default:
- module_printk(KERN_NOTICE, "Unknown maintenance event: %d\n", maint.command);
+ module_printk(KERN_NOTICE,
+ "Unknown maintenance event: %d\n",
+ maint.command);
}
dahdi_alarm_notify(spans[maint.spanno]); /* process alarm-related events */
spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
diff --git a/drivers/dahdi/tor2.c b/drivers/dahdi/tor2.c
index 3cde7ec..cfafa11 100644
--- a/drivers/dahdi/tor2.c
+++ b/drivers/dahdi/tor2.c
@@ -1426,18 +1426,28 @@ DAHDI_IRQ_HANDLER(tor2_intr)
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);
+ tor->spans[i - 1].count.bpv +=
+ t1in(tor, i, 1) + (t1in(tor, i, 0)<<8);
+
if (tor->spans[i - 1].lineconfig & DAHDI_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].count.crc4 +=
+ t1in(tor, i, 3) +
+ ((t1in(tor, i, 2) & 3) << 8);
+ tor->spans[i - 1].count.ebit +=
+ 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);
+ tor->spans[i - 1].count.fas +=
+ (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);
+ tor->spans[i - 1].count.bpv +=
+ t1in(tor, i, 0x24) +
+ (t1in(tor, i, 0x23) << 8);
}
}
}
diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c
index c05fc4b..36300d2 100644
--- a/drivers/dahdi/wct4xxp/base.c
+++ b/drivers/dahdi/wct4xxp/base.c
@@ -2,6 +2,7 @@
* TE410P Quad-T1/E1 PCI Driver version 0.1, 12/16/02
*
* Written by Mark Spencer <markster@digium.com>
+ case DAHDI_MAINT_LOOPDOWN:
* Based on previous works, designs, and archetectures conceived and
* written by Jim Dixon <jim@lambdatel.com>.
* Further modified, optimized, and maintained by
@@ -412,6 +413,7 @@ static int t4_startup(struct dahdi_span *span);
static int t4_shutdown(struct dahdi_span *span);
static int t4_rbsbits(struct dahdi_chan *chan, int bits);
static int t4_maint(struct dahdi_span *span, int cmd);
+static int t4_reset_counters(struct dahdi_span *span);
#ifdef SUPPORT_GEN1
static int t4_reset_dma(struct t4 *wc);
#endif
@@ -452,6 +454,49 @@ static void t4_check_sigbits(struct t4 *wc, int span);
#define WC_RECOVER 0
#define WC_SELF 1
+#define LIM0_T 0x36 /* Line interface mode 0 register */
+#define LIM0_LL (1 << 1) /* Local Loop */
+#define LIM1_T 0x37 /* Line interface mode 1 register */
+#define LIM1_RL (1 << 1) /* Remote Loop */
+
+#define FMR1_T 0x1D /* Framer Mode Register 1 */
+#define FMR1_ECM (1 << 2) /* Error Counter 1sec Interrupt Enable */
+#define DEC_T 0x60 /* Diable Error Counter */
+#define IERR_T 0x1B /* Single Bit Defect Insertion Register */
+enum{IBV, IPE, ICASE, ICRCE, IMFE, IFASE};
+#define ISR3_SEC (1 << 6) /* Internal one-second interrupt bit mask */
+#define ISR3_ES (1 << 7) /* Errored Second interrupt bit mask */
+#define ESM 0x47 /* Errored Second mask register */
+
+#define FMR2_T 0x1E /* Framer Mode Register 2 */
+#define FMR2_PLB (1 << 2) /* Framer Mode Register 2 */
+
+#define FECL_T 0x50 /* Framing Error Counter Lower Byte */
+#define FECH_T 0x51 /* Framing Error Counter Higher Byte */
+#define CVCL_T 0x52 /* Code Violation Counter Lower Byte */
+#define CVCH_T 0x53 /* Code Violation Counter Higher Byte */
+#define CEC1L_T 0x54 /* CRC Error Counter 1 Lower Byte */
+#define CEC1H_T 0x55 /* CRC Error Counter 1 Higher Byte */
+#define EBCL_T 0x56 /* E-Bit Error Counter Lower Byte */
+#define EBCH_T 0x57 /* E-Bit Error Counter Higher Byte */
+#define BECL_T 0x58 /* Bit Error Counter Lower Byte */
+#define BECH_T 0x59 /* Bit Error Counter Higher Byte */
+#define COEC_T 0x5A /* COFA Event Counter */
+#define PRBSSTA_T 0xDA /* PRBS Status Register */
+
+#define LCR1_T 0x3B /* Loop Code Register 1 */
+#define EPRM (1 << 7) /* Enable PRBS rx */
+#define XPRBS (1 << 6) /* Enable PRBS tx */
+#define FLLB (1 << 1) /* Framed line loop/Invert */
+#define LLBP (1 << 0) /* Line Loopback Pattern */
+#define TPC0_T 0xA8 /* Test Pattern Control Register */
+#define FRA (1 << 6) /* Framed/Unframed Selection */
+#define PRBS23 (3 << 4) /* Pattern selection (23 poly) */
+#define PRM (1 << 2) /* Non framed mode */
+#define FRS1_T 0x4D /* Framer Receive Status Reg 1 */
+#define LLBDD (1 << 4)
+#define LLBAD (1 << 3)
+
#define MAX_T4_CARDS 64
static void t4_isr_bh(unsigned long data);
@@ -1386,6 +1431,7 @@ static int t4_maint(struct dahdi_span *span, int cmd)
{
struct t4_span *ts = span->pvt;
struct t4 *wc = ts->owner;
+ unsigned int reg;
if (ts->spantype == TYPE_E1) {
switch(cmd) {
@@ -1413,32 +1459,109 @@ static int t4_maint(struct dahdi_span *span, int cmd)
}
} else {
switch(cmd) {
- case DAHDI_MAINT_NONE:
- printk(KERN_NOTICE "XXX Turn off local and remote loops T1 XXX\n");
+ case DAHDI_MAINT_NONE:
+ dev_info(&wc->dev->dev, "Turning off all looping\n");
+
+ reg = t4_framer_in(wc, span->offset, LIM0_T);
+ t4_framer_out(wc, span->offset,
+ LIM0_T, (reg & ~LIM0_LL));
+
+ reg = t4_framer_in(wc, span->offset, LIM1_T);
+ t4_framer_out(wc, span->offset, LIM1_T,
+ (reg & ~LIM1_RL));
+
+ reg = t4_framer_in(wc, span->offset, LCR1_T);
+ t4_framer_out(wc, span->offset, LCR1_T,
+ (reg & ~(XPRBS | EPRM)));
+
+ span->mainttimer = 0;
+ break;
+ case DAHDI_MAINT_LOCALLOOP:
+ dev_info(&wc->dev->dev,
+ "Turning on local loopback\n");
+ reg = t4_framer_in(wc, span->offset, LIM0_T);
+ t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
+ break;
+ case DAHDI_MAINT_NETWORKLINELOOP:
+ dev_info(&wc->dev->dev,
+ "Turning on network line loopback\n");
+ reg = t4_framer_in(wc, span->offset, LIM1_T);
+ t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
+ break;
+ case DAHDI_MAINT_NETWORKPAYLOADLOOP:
+ dev_info(&wc->dev->dev,
+ "Turning on network payload loopback\n");
+ reg = t4_framer_in(wc, span->offset, FMR2_T);
+ t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
+ break;
+ case DAHDI_MAINT_LOOPUP:
+ dev_info(&wc->dev->dev, "Transmitting loopup code\n");
+ t4_framer_out(wc, span->offset, 0x21, 0x50);
+ break;
+ case DAHDI_MAINT_LOOPDOWN:
+ dev_info(&wc->dev->dev, "Transmitting loopdown code\n");
+ t4_framer_out(wc, span->offset, 0x21, 0x60);
+ break;
+ case DAHDI_MAINT_LOOPSTOP:
+ dev_info(&wc->dev->dev, "Transmitting loopstop code\n");
+ t4_framer_out(wc, span->offset, 0x21, 0x40);
+ break;
+ case DAHDI_MAINT_FAS_DEFECT:
+ t4_framer_out(wc, span->offset, IERR_T, IFASE);
+ break;
+ case DAHDI_MAINT_MULTI_DEFECT:
+ t4_framer_out(wc, span->offset, IERR_T, IMFE);
break;
- case DAHDI_MAINT_LOCALLOOP:
- printk(KERN_NOTICE "XXX Turn on local loop and no remote loop XXX\n");
+ case DAHDI_MAINT_CRC_DEFECT:
+ t4_framer_out(wc, span->offset, IERR_T, ICRCE);
break;
- case DAHDI_MAINT_REMOTELOOP:
- printk(KERN_NOTICE "XXX Turn on remote loopup XXX\n");
+ case DAHDI_MAINT_CAS_DEFECT:
+ t4_framer_out(wc, span->offset, IERR_T, ICASE);
break;
- case DAHDI_MAINT_LOOPUP:
- t4_framer_out(wc, span->offset, 0x21, 0x50); /* FMR5: Nothing but RBS mode */
+ case DAHDI_MAINT_PRBS_DEFECT:
+ t4_framer_out(wc, span->offset, IERR_T, IPE);
break;
- case DAHDI_MAINT_LOOPDOWN:
- t4_framer_out(wc, span->offset, 0x21, 0x60); /* FMR5: Nothing but RBS mode */
+ case DAHDI_MAINT_BIPOLAR_DEFECT:
+ t4_framer_out(wc, span->offset, IERR_T, IBV);
break;
- case DAHDI_MAINT_LOOPSTOP:
- t4_framer_out(wc, span->offset, 0x21, 0x40); /* FMR5: Nothing but RBS mode */
+ case DAHDI_MAINT_PRBS:
+ dev_info(&wc->dev->dev, "PRBS not supported\n");
+#if 0
+ printk(KERN_NOTICE "Enabling PRBS!\n");
+ span->mainttimer = 1;
+ /* Enable PRBS monitor */
+ reg = t4_framer_in(wc, span->offset, LCR1_T);
+ reg |= EPRM;
+
+ /* Setup PRBS xmit */
+ t4_framer_out(wc, span->offset, TPC0_T, 0);
+
+ /* Enable PRBS transmit */
+ reg |= XPRBS;
+ reg &= ~LLBP;
+ reg &= ~FLLB;
+ t4_framer_out(wc, span->offset, LCR1_T, reg);
+#endif
break;
- default:
- printk(KERN_NOTICE "TE%dXXP: Unknown T1 maint command: %d\n", wc->numspans, cmd);
+ case DAHDI_RESET_COUNTERS:
+ t4_reset_counters(span);
+ break;
+ default:
+ dev_info(&wc->dev->dev, "Unknown T1 maint command:%d\n",
+ cmd);
break;
}
}
return 0;
}
+static int t4_reset_counters(struct dahdi_span *span)
+{
+ struct t4_span *ts = span->pvt;
+ memset(&ts->span.count, 0, sizeof(ts->span.count));
+ return 0;
+}
+
static int t4_rbsbits(struct dahdi_chan *chan, int bits)
{
u_char m,c;
@@ -1702,6 +1825,7 @@ static void init_spans(struct t4 *wc)
int x,y;
int gen2;
struct t4_span *ts;
+ unsigned int reg;
gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
for (x = 0; x < wc->numspans; x++) {
@@ -1775,6 +1899,19 @@ static void init_spans(struct t4 *wc)
mychans->pvt = wc;
mychans->chanpos = y + 1;
}
+
+ /* Enable 1sec timer interrupt */
+ reg = t4_framer_in(wc, x, FMR1_T);
+ t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
+ dev_info(&wc->dev->dev, "Enabled 1sec error counter "\
+ "interrupt\n");
+
+ /* Enable Errored Second interrupt */
+ t4_framer_out(wc, x, ESM, 0);
+ dev_info(&wc->dev->dev, "Enabled errored second interrupt\n");
+
+ t4_reset_counters(&ts->span);
+
}
set_span_devicetype(wc);
@@ -2109,9 +2246,9 @@ static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlev
/* Don't mask framer interrupts if hardware HDLC is in use */
__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CAS changes, etc */
__t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about nothing */
- __t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */
- __t4_framer_out(wc, unit, 0x17, 0xf4); /* IMR3: We care about AIS and friends */
- __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */
+ __t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: All the alarm stuff! */
+ __t4_framer_out(wc, unit, 0x17, 0x34); /* IMR3: AIS and friends */
+ __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: Slips on transmit */
printk(KERN_INFO "TE%dXXP: Span %d configured for %s/%s\n", wc->numspans, unit + 1, framing, line);
}
@@ -2195,7 +2332,7 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
__t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CRC errors, CAS changes, etc */
__t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about loopup / loopdown */
__t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */
- __t4_framer_out(wc, unit, 0x17, 0xc4 | imr3extra); /* IMR3: We care about AIS and friends */
+ __t4_framer_out(wc, unit, 0x17, 0x44 | imr3extra); /* IMR3: AIS */
__t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */
printk(KERN_INFO "TE%dXXP: Span %d configured for %s/%s%s\n", wc->numspans, unit + 1, framing, line, crc4);
@@ -2903,14 +3040,12 @@ static inline void __handle_leds(struct t4 *wc)
static inline void t4_framer_interrupt(struct t4 *wc, int span)
{
/* Check interrupts for a given span */
- unsigned char gis, isr0, isr1, isr2, isr3, isr4;
+ unsigned char gis, isr0, isr1, isr2, isr3, isr4, reg;
int readsize = -1;
struct t4_span *ts = wc->tspans[span];
struct dahdi_chan *sigchan;
unsigned long flags;
- if (debug & DEBUG_FRAMER)
- printk(KERN_DEBUG "framer interrupt span %d:%d!\n", wc->num, span + 1);
/* 1st gen cards isn't used interrupts */
gis = t4_framer_in(wc, span, FRMR_GIS);
@@ -2920,10 +3055,35 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
isr3 = (gis & FRMR_GIS_ISR3) ? t4_framer_in(wc, span, FRMR_ISR3) : 0;
isr4 = (gis & FRMR_GIS_ISR4) ? t4_framer_in(wc, span, FRMR_ISR4) : 0;
- if (debug & DEBUG_FRAMER)
- printk(KERN_DEBUG "gis: %02x, isr0: %02x, isr1: %02x, isr2: "\
- "%02x, isr3: %02x, isr4: %02x, intcount= %u\n",
- gis, isr0, isr1, isr2, isr3, isr4, wc->intcount);
+ if ((debug & DEBUG_FRAMER) && !(isr3 & ISR3_SEC)) {
+ dev_info(&wc->dev->dev, "gis: %02x, isr0: %02x, isr1: %02x, "\
+ "isr2: %02x, isr3: %08x, isr4: %02x, intcount=%u\n",
+ gis, isr0, isr1, isr2, isr3, isr4, wc->intcount);
+ }
+
+ if (isr3 & ISR3_SEC) {
+ ts->span.count.fe += t4_framer_in(wc, span, FECL_T);
+ ts->span.count.crc4 += t4_framer_in(wc, span, CEC1L_T);
+ ts->span.count.cv += t4_framer_in(wc, span, CVCL_T);
+ ts->span.count.ebit += t4_framer_in(wc, span, EBCL_T);
+ ts->span.count.be += t4_framer_in(wc, span, BECL_T);
+ ts->span.count.prbs = t4_framer_in(wc, span, FRS1_T);
+ }
+
+ if (isr3 & ISR3_ES) {
+ ts->span.count.errsec += 1;
+ dev_info(&wc->dev->dev, "Errored second: span %d\n", span+1);
+ }
+
+ if (isr3 & 0x08) {
+ reg = t4_framer_in(wc, span, FRS1_T);
+ printk(KERN_INFO "FRS1: %d\n", reg);
+ if (reg & LLBDD) {
+ dev_info(&wc->dev->dev, "Line loop-back activation "\
+ "signal detected with status: %01d "\
+ "for span %d\n", reg & LLBAD, span+1);
+ }
+ }
if (isr0)
t4_check_sigbits(wc, span);
@@ -3050,7 +3210,6 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
if (isr1 & FRMR_ISR1_ALLS) {
if (debug & DEBUG_FRAMER) printk(KERN_DEBUG "ALLS received\n");
}
-
}
#ifdef SUPPORT_GEN1
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 79ded20..dfba2dd 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -1099,6 +1099,7 @@ static inline void t1_check_sigbits(struct t1 *wc)
static int t1xxp_maint(struct dahdi_span *span, int cmd)
{
struct t1 *wc = span->pvt;
+ int reg = 0;
if (wc->spantype == TYPE_E1) {
switch (cmd) {
@@ -1128,24 +1129,34 @@ static int t1xxp_maint(struct dahdi_span *span, int cmd)
} else {
switch (cmd) {
case DAHDI_MAINT_NONE:
- t1_info(wc, "XXX Turn off local and remote "
- "loops T1 XXX\n");
+ /* Turn off local loop */
+ reg = t1_getreg(wc, LIM0);
+ t1_setreg(wc, LIM0, reg & ~LIM0_LL);
+
+ /* Turn off remote loop & jitter attenuator */
+ reg = t1_getreg(wc, LIM1);
+ t1_setreg(wc, LIM1, reg & ~(LIM1_RL | LIM1_JATT));
break;
case DAHDI_MAINT_LOCALLOOP:
- t1_info(wc, "XXX Turn on local loop and no remote "
- "loop XXX\n");
+ reg = t1_getreg(wc, LIM0);
+ t1_setreg(wc, LIM0, reg | LIM0_LL);
break;
- case DAHDI_MAINT_REMOTELOOP:
- t1_info(wc, "XXX Turn on remote loopup XXX\n");
+ case DAHDI_MAINT_NETWORKLINELOOP:
+ reg = t1_getreg(wc, LIM1);
+ t1_setreg(wc, LIM1, reg | LIM1_RL);
+ break;
+ case DAHDI_MAINT_NETWORKPAYLOADLOOP:
+ reg = t1_getreg(wc, LIM1);
+ t1_setreg(wc, LIM1, reg | (LIM1_RL | LIM1_JATT));
break;
case DAHDI_MAINT_LOOPUP:
- t1_setreg(wc, 0x21, 0x50); /* FMR5: Nothing but RBS mode */
+ t1_setreg(wc, 0x21, 0x50);
break;
case DAHDI_MAINT_LOOPDOWN:
- t1_setreg(wc, 0x21, 0x60); /* FMR5: Nothing but RBS mode */
+ t1_setreg(wc, 0x21, 0x60);
break;
case DAHDI_MAINT_LOOPSTOP:
- t1_setreg(wc, 0x21, 0x40); /* FMR5: Nothing but RBS mode */
+ t1_setreg(wc, 0x21, 0x40);
break;
default:
t1_info(wc, "Unknown T1 maint command: %d\n", cmd);
diff --git a/drivers/dahdi/wcte12xp/wcte12xp.h b/drivers/dahdi/wcte12xp/wcte12xp.h
index 1729ec5..0ec3c3a 100644
--- a/drivers/dahdi/wcte12xp/wcte12xp.h
+++ b/drivers/dahdi/wcte12xp/wcte12xp.h
@@ -140,4 +140,11 @@ struct t1 {
#define t1_info(t1, format, arg...) \
dev_info(&t1->vb.pdev->dev , format , ## arg)
+/* Maintenance Mode Registers */
+#define LIM0 0x36
+#define LIM0_LL (1<<1)
+#define LIM1 0x37
+#define LIM1_RL (1<<1)
+#define LIM1_JATT (1<<2)
+
#endif
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index 1d75245..c905234 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -759,10 +759,7 @@ struct dahdi_span {
int txlevel; /*!< Tx level */
int rxlevel; /*!< Rx level */
int syncsrc; /*!< current sync src (gets copied here) */
- unsigned int bpvcount; /*!< BPV counter */
- unsigned int crc4count; /*!< CRC4 error counter */
- unsigned int ebitcount; /*!< current E-bit error count */
- unsigned int fascount; /*!< current FAS error count */
+ struct dahdi_count count; /*!< Performance and Error counters */
int maintstat; /*!< Maintenance state */
wait_queue_head_t maintq; /*!< Maintenance queue */
diff --git a/include/dahdi/user.h b/include/dahdi/user.h
index 1d0570a..a5d6ed2 100644
--- a/include/dahdi/user.h
+++ b/include/dahdi/user.h
@@ -323,9 +323,19 @@ enum {
#define DAHDI_MAINT_NONE 0 /* Normal Mode */
#define DAHDI_MAINT_LOCALLOOP 1 /* Local Loopback */
#define DAHDI_MAINT_REMOTELOOP 2 /* Remote Loopback */
+#define DAHDI_MAINT_NETWORKLINELOOP 2 /* Remote Loopback */
#define DAHDI_MAINT_LOOPUP 3 /* send loopup code */
#define DAHDI_MAINT_LOOPDOWN 4 /* send loopdown code */
#define DAHDI_MAINT_LOOPSTOP 5 /* stop sending loop codes */
+#define DAHDI_MAINT_FAS_DEFECT 6 /* insert a FAS defect */
+#define DAHDI_MAINT_MULTI_DEFECT 7 /* insert a Multiframe defect */
+#define DAHDI_MAINT_CRC_DEFECT 8 /* insert a FAS defect */
+#define DAHDI_MAINT_CAS_DEFECT 9 /* insert a FAS defect */
+#define DAHDI_MAINT_PRBS_DEFECT 10 /* insert a FAS defect */
+#define DAHDI_MAINT_BIPOLAR_DEFECT 11 /* insert a FAS defect */
+#define DAHDI_MAINT_PRBS 12 /* enable the PRBS gen/mon */
+#define DAHDI_MAINT_NETWORKPAYLOADLOOP 13 /* Remote Loopback */
+#define DAHDI_RESET_COUNTERS 14 /* clear the error counters */
/* Flag Value for IOMUX, read avail */
#define DAHDI_IOMUX_READ 1
@@ -519,6 +529,18 @@ struct dahdi_params {
*/
#define DAHDI_IOMUX _IOWR(DAHDI_CODE, 9, int)
+struct dahdi_count {
+ __u32 fe; /*!< Framing error counter */
+ __u32 cv; /*!< Coding violations counter */
+ __u32 bpv; /*!< Bipolar Violation counter */
+ __u32 crc4; /*!< CRC4 error counter */
+ __u32 ebit; /*!< current E-bit error count */
+ __u32 fas; /*!< current FAS error count */
+ __u32 be; /*!< current bit error count */
+ __u32 prbs; /*!< current PRBS detected pattern */
+ __u32 errsec; /*!< errored seconds */
+};
+
/*
* Get Span Status
*/
@@ -529,6 +551,31 @@ struct dahdi_spaninfo {
int alarms; /* alarms status */
int txlevel; /* what TX level is set to */
int rxlevel; /* current RX level */
+ struct dahdi_count count;/* Performance and Error counters */
+ int irqmisses; /* current IRQ misses */
+ int syncsrc; /* span # of current sync source,
+ or 0 for free run */
+ int numchans; /* number of configured channels on this span */
+ int totalchans; /* total number of channels on the span */
+ int totalspans; /* total number of spans in entire system */
+ int lbo; /* line build out */
+ int lineconfig; /* framing/coding */
+ char lboname[40]; /* line build out in text form */
+ char location[40]; /* span's device location in system */
+ char manufacturer[40]; /* manufacturer of span's device */
+ char devicetype[40]; /* span's device type */
+ int irq; /* span's device IRQ */
+ int linecompat; /* signaling modes possible on this span */
+ char spantype[6]; /* type of span in text form */
+} __attribute__((packed));
+
+struct dahdi_spaninfo_v1 {
+ int spanno; /* span number */
+ char name[20]; /* Name */
+ char desc[40]; /* Description */
+ int alarms; /* alarms status */
+ int txlevel; /* what TX level is set to */
+ int rxlevel; /* current RX level */
int bpvcount; /* current BPV count */
int crc4count; /* current CRC4 error count */
int ebitcount; /* current E-bit error count */
@@ -548,14 +595,14 @@ struct dahdi_spaninfo {
int linecompat; /* signaling modes possible on this span */
char spantype[6]; /* type of span in text form */
};
-
-#define DAHDI_SPANSTAT _IOWR(DAHDI_CODE, 10, struct dahdi_spaninfo)
+#define DAHDI_SPANSTAT _IOWR(DAHDI_CODE, 10, struct dahdi_spaninfo)
+#define DAHDI_SPANSTAT_V1 _IOWR(DAHDI_CODE, 10, struct dahdi_spaninfo_v1)
/*
* Set Maintenance Mode
*/
struct dahdi_maintinfo {
- int spanno; /* span number 1-2 */
+ int spanno; /* span number */
int command; /* command */
};