From a0e532fc44b63d9996b16ca7329d9a98e04e3362 Mon Sep 17 00:00:00 2001 From: Russ Meyerriecks Date: Mon, 22 Feb 2010 16:18:45 +0000 Subject: 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 --- drivers/dahdi/dahdi-base.c | 115 ++++++++++++++++++--- drivers/dahdi/tor2.c | 20 +++- drivers/dahdi/wct4xxp/base.c | 211 +++++++++++++++++++++++++++++++++----- drivers/dahdi/wcte12xp/base.c | 29 ++++-- drivers/dahdi/wcte12xp/wcte12xp.h | 7 ++ include/dahdi/kernel.h | 5 +- include/dahdi/user.h | 53 +++++++++- 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 + case DAHDI_MAINT_LOOPDOWN: * Based on previous works, designs, and archetectures conceived and * written by Jim Dixon . * 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,10 +529,47 @@ 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 */ struct dahdi_spaninfo { + 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 */ + 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 */ @@ -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 */ }; -- cgit v1.2.3