📄 wct4xxp.c
字号:
if (debug) printk("Finished setting RBS bits\n"); return 0;}static int t4_shutdown(struct zt_span *span){ int tspan; int wasrunning; unsigned long flags; struct t4 *wc = span->pvt; tspan = span->offset + 1; if (tspan < 0) { printk("T4XXP: Span '%d' isn't us?\n", span->spanno); return -1; } spin_lock_irqsave(&wc->reglock, flags); wasrunning = span->flags & ZT_FLAG_RUNNING; span->flags &= ~ZT_FLAG_RUNNING; if (wasrunning) wc->spansstarted--; __t4_set_led(wc, span->offset, WC_OFF); if ((!(wc->spans[0].flags & ZT_FLAG_RUNNING)) && (!(wc->spans[1].flags & ZT_FLAG_RUNNING)) && (!(wc->spans[2].flags & ZT_FLAG_RUNNING)) && (!(wc->spans[3].flags & ZT_FLAG_RUNNING))) { /* No longer in use, disable interrupts */ printk("TE410P: Disabling interrupts since there are no active spans\n"); wc->dmactrl = 0x0; __t4_pci_out(wc, WC_DMACTRL, 0x00000000); /* Acknowledge any pending interrupts */ __t4_pci_out(wc, WC_INTR, 0x00000000); __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); return 0;}static int t4_spanconfig(struct zt_span *span, struct zt_lineconfig *lc){ int i; struct t4 *wc = span->pvt; if (debug) printk("TE410P: Configuring span %d\n", span->spanno); /* XXX We assume lineconfig is okay and shouldn't XXX */ span->lineconfig = lc->lineconfig; span->txlevel = lc->lbo; span->rxlevel = 0; 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++) { if (wc->syncs[i] == span->spanno) { wc->syncs[i] = 0; wc->psyncs[i] = 0; } } wc->syncpos[span->offset] = lc->sync; /* if a sync src, put it in proper place */ if (lc->sync) { wc->syncs[lc->sync - 1] = span->spanno; wc->psyncs[lc->sync - 1] = span->offset + 1; } wc->checktiming = 1; /* If we're already running, then go ahead and apply the changes */ if (span->flags & ZT_FLAG_RUNNING) return t4_startup(span); return 0;}static int t4_chanconfig(struct zt_chan *chan, int sigtype){ int alreadyrunning; unsigned long flags; struct t4 *wc = chan->pvt; alreadyrunning = wc->spans[chan->span->offset].flags & ZT_FLAG_RUNNING; if (debug) { if (alreadyrunning) printk("TE410P: Reconfigured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype); else printk("TE410P: Configured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype); } /* nothing more to do if an E1 */ if (wc->spantype[chan->span->offset] == TYPE_E1) return 0; spin_lock_irqsave(&wc->reglock, flags); if (alreadyrunning) __set_clear(wc, chan->span->offset); spin_unlock_irqrestore(&wc->reglock, flags); return 0;}static int t4_open(struct zt_chan *chan){#ifndef LINUX26 MOD_INC_USE_COUNT;#endif return 0;}static int t4_close(struct zt_chan *chan){#ifndef LINUX26 MOD_DEC_USE_COUNT;#endif return 0;}static void init_spans(struct t4 *wc){ int x,y,c; for (x=0;x<4;x++) { sprintf(wc->spans[x].name, "TE4/%d/%d", wc->num, x + 1); sprintf(wc->spans[x].desc, "TE410P (PCI) Card %d Span %d", wc->num, x+1); wc->spans[x].spanconfig = t4_spanconfig; wc->spans[x].chanconfig = t4_chanconfig; wc->spans[x].startup = t4_startup; wc->spans[x].shutdown = t4_shutdown; wc->spans[x].rbsbits = t4_rbsbits; wc->spans[x].maint = t4_maint; wc->spans[x].open = t4_open; wc->spans[x].close = t4_close; if (wc->spantype[x] == TYPE_T1) { wc->spans[x].channels = 24; wc->spans[x].deflaw = ZT_LAW_MULAW; } else { wc->spans[x].channels = 31; wc->spans[x].deflaw = ZT_LAW_ALAW; } wc->spans[x].chans = wc->chans[x]; wc->spans[x].flags = ZT_FLAG_RBS; wc->spans[x].linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF; wc->spans[x].ioctl = t4_ioctl; wc->spans[x].pvt = wc; wc->spans[x].offset = x; init_waitqueue_head(&wc->spans[x].maintq); for (y=0;y<wc->spans[x].channels;y++) { 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_DACS_RBS; c = (x * wc->spans[x].channels) + y; mychans->pvt = wc; mychans->chanpos = y + 1; } }}static void t4_serial_setup(struct t4 *wc, int unit){ if (!wc->globalconfig) { wc->globalconfig = 1; printk("TE410P: Setting up global serial parameters\n"); t4_framer_out(wc, 0, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */ t4_framer_out(wc, 0, 0x08, 0x01); /* IPC: Interrupt push/pull active low */ /* Global clocks (8.192 Mhz CLK) */ t4_framer_out(wc, 0, 0x92, 0x00); t4_framer_out(wc, 0, 0x93, 0x18); t4_framer_out(wc, 0, 0x94, 0xfb); t4_framer_out(wc, 0, 0x95, 0x0b); t4_framer_out(wc, 0, 0x96, 0x00); t4_framer_out(wc, 0, 0x97, 0x0b); t4_framer_out(wc, 0, 0x98, 0xdb); t4_framer_out(wc, 0, 0x99, 0xdf); } /* Configure interrupts */ t4_framer_out(wc, unit, 0x46, 0x40); /* GCR: Interrupt on Activation/Deactivation of AIX, LOS */ /* Configure system interface */ t4_framer_out(wc, unit, 0x3e, 0xc2); /* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */ t4_framer_out(wc, unit, 0x3f, unit << 1); /* SIC2: No FFS, no center receive eliastic buffer, phase */ t4_framer_out(wc, unit, 0x40, 0x04); /* SIC3: Edges for capture */ t4_framer_out(wc, unit, 0x45, 0x00); /* CMR2: We provide sync and clock for tx and rx. */ if (!wc->t1e1) { t4_framer_out(wc, unit, 0x22, 0x03); /* XC0: Normal operation of Sa-bits */ t4_framer_out(wc, unit, 0x23, 0x84); /* XC1: 0 offset */ t4_framer_out(wc, unit, 0x24, 0x03); /* RC0: Just shy of 1023 */ t4_framer_out(wc, unit, 0x25, 0x84); /* RC1: The rest of RC0 */ } else { t4_framer_out(wc, unit, 0x22, 0x00); /* XC0: Normal operation of Sa-bits */ t4_framer_out(wc, unit, 0x23, 0x04); /* XC1: 0 offset */ t4_framer_out(wc, unit, 0x24, 0x04); /* RC0: Just shy of 1023 */ t4_framer_out(wc, unit, 0x25, 0x04); /* RC1: The rest of RC0 */ } /* Configure ports */ t4_framer_out(wc, unit, 0x80, 0x00); /* PC1: SPYR/SPYX input on RPA/XPA */ t4_framer_out(wc, unit, 0x81, 0x22); /* PC2: RMFB/XSIG output/input on RPB/XPB */ t4_framer_out(wc, unit, 0x82, 0x65); /* PC3: Some unused stuff */ t4_framer_out(wc, unit, 0x83, 0x35); /* PC4: Some more unused stuff */ t4_framer_out(wc, unit, 0x84, 0x01); /* PC5: XMFS active low, SCLKR is input, RCLK is output */ if (debug) printk("Successfully initialized serial bus for unit %d\n", unit);}static void __t4_set_timing_source(struct t4 *wc, int unit){ unsigned int timing; int x; if (unit != wc->syncsrc) { timing = 0x34; /* CMR1: RCLK unit, 8.192 Mhz TCLK, RCLK is 8.192 Mhz */ 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); } wc->syncsrc = unit; if ((unit < 0) || (unit > 3)) unit = 0; else unit++; for (x=0;x<4;x++) wc->spans[x].syncsrc = unit; } else { if (debug) printk("TE410P: Timing source already set to %d\n", unit); }#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_RED | ZT_ALARM_BLUE) )) { /* Valid timing sourc e*/ __t4_set_timing_source(wc, wc->syncs[x] - 1); return; } } } __t4_set_timing_source(wc, 4);}static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel){ unsigned int fmr4, fmr2, fmr1, fmr0, lim2; char *framing, *line; int mytxlevel; if ((txlevel > 7) || (txlevel < 4)) mytxlevel = 0; else mytxlevel = txlevel - 4; fmr1 = 0x9c; /* FMR1: Mode 1, T1 mode, CRC on for ESF, 8.192 Mhz system data rate, no XAIS */ fmr2 = 0x22; /* FMR2: no payload loopback, auto send yellow alarm */ if (loopback) fmr2 |= 0x4; fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */ lim2 = 0x21; /* LIM2: 50% peak is a "1", Advanced Loss recovery */ lim2 |= (mytxlevel << 6); /* LIM2: Add line buildout */ __t4_framer_out(wc, unit, 0x1d, fmr1); __t4_framer_out(wc, unit, 0x1e, fmr2); /* Configure line interface */ if (lineconfig & ZT_CONFIG_AMI) { line = "AMI"; fmr0 = 0xa0; } else { line = "B8ZS"; fmr0 = 0xf0; } if (lineconfig & ZT_CONFIG_D4) { framing = "D4"; } else { framing = "ESF"; fmr4 |= 0x2; fmr2 |= 0xc0; } __t4_framer_out(wc, unit, 0x1c, fmr0); __t4_framer_out(wc, unit, 0x20, fmr4); __t4_framer_out(wc, unit, 0x21, 0x40); /* FMR5: Enable RBS mode */ __t4_framer_out(wc, unit, 0x37, 0xf0 ); /* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */ __t4_framer_out(wc, unit, 0x36, 0x08); /* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */ __t4_framer_out(wc, unit, 0x02, 0x50); /* CMDR: Reset the receiver and transmitter line interface */ __t4_framer_out(wc, unit, 0x02, 0x00); /* CMDR: Reset the receiver and transmitter line interface */ __t4_framer_out(wc, unit, 0x3a, lim2); /* LIM2: 50% peak amplitude is a "1" */ __t4_framer_out(wc, unit, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */ __t4_framer_out(wc, unit, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */ /* Generate pulse mask for T1 */ switch(mytxlevel) { case 3: __t4_framer_out(wc, unit, 0x26, 0x07); /* XPM0 */ __t4_framer_out(wc, unit, 0x27, 0x01); /* XPM1 */ __t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */ break; case 2: __t4_framer_out(wc, unit, 0x26, 0x8c); /* XPM0 */ __t4_framer_out(wc, unit, 0x27, 0x11); /* XPM1 */ __t4_framer_out(wc, unit, 0x28, 0x01); /* XPM2 */ break; case 1: __t4_framer_out(wc, unit, 0x26, 0x8c); /* XPM0 */ __t4_framer_out(wc, unit, 0x27, 0x01); /* XPM1 */ __t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */ break; case 0: default: __t4_framer_out(wc, unit, 0x26, 0xd7); /* XPM0 */ __t4_framer_out(wc, unit, 0x27, 0x22); /* XPM1 */ __t4_framer_out(wc, unit, 0x28, 0x01); /* XPM2 */ break; } printk("TE410P: Span %d configured for %s/%s\n", unit + 1, framing, line);}static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig){ unsigned int fmr2, fmr1, fmr0; unsigned int cas = 0; char *crc4 = ""; char *framing, *line; fmr1 = 0x44; /* FMR1: E1 mode, Automatic force resync, PCM30 mode, 8.192 Mhz backplane, no XAIS */ fmr2 = 0x03; /* FMR2: Auto transmit remote alarm, auto loss of multiframe recovery, no payload loopback */ if (loopback) fmr2 |= 0x4; if (lineconfig & ZT_CONFIG_CRC4) { fmr1 |= 0x08; /* CRC4 transmit */ fmr2 |= 0xc0; /* CRC4 receive */ crc4 = "/CRC4"; } __t4_framer_out(wc, unit, 0x1d, fmr1); __t4_framer_out(wc, unit, 0x1e, fmr2); /* Configure line interface */ if (lineconfig & ZT_CONFIG_AMI) { line = "AMI"; fmr0 = 0xa0; } else { line = "HDB3"; fmr0 = 0xf0; } if (lineconfig & ZT_CONFIG_CCS) { framing = "CCS"; } else { framing = "CAS"; cas = 0x40; } __t4_framer_out(wc, unit, 0x1c, fmr0); __t4_framer_out(wc, unit, 0x37, 0xf0 /*| 0x6 */ ); /* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */ __t4_framer_out(wc, unit, 0x36, 0x08); /* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */ __t4_framer_out(wc, unit, 0x02, 0x50); /* CMDR: Reset the receiver and transmitter line interface */ __t4_framer_out(wc, unit, 0x02, 0x00); /* CMDR: Reset the receiver and transmitter line interface */ /* Condition receive line interface for E1 after reset */ __t4_framer_out(wc, unit, 0xbb, 0x17); __t4_framer_out(wc, unit, 0xbc, 0x55); __t4_framer_out(wc, unit, 0xbb, 0x97); __t4_framer_out(wc, unit, 0xbb, 0x11); __t4_framer_out(wc, unit, 0xbc, 0xaa); __t4_framer_out(wc, unit, 0xbb, 0x91); __t4_framer_out(wc, unit, 0xbb, 0x12); __t4_framer_out(wc, unit, 0xbc, 0x55); __t4_framer_out(wc, unit, 0xbb, 0x92); __t4_framer_out(wc, unit, 0xbb, 0x0c); __t4_framer_out(wc, unit, 0xbb, 0x00); __t4_framer_out(wc, unit, 0xbb, 0x8c); __t4_framer_out(wc, unit, 0x3a, 0x20); /* LIM2: 50% peak amplitude is a "1" */ __t4_framer_out(wc, unit, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */ __t4_framer_out(wc, unit, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */ __t4_framer_out(wc, unit, 0x20, 0x9f); /* XSW: Spare bits all to 1 */ __t4_framer_out(wc, unit, 0x21, 0x1c|cas); /* XSP: E-bit set when async. AXS auto, XSIF to 1 */ /* Generate pulse mask for E1 */ __t4_framer_out(wc, unit, 0x26, 0x54); /* XPM0 */ __t4_framer_out(wc, unit, 0x27, 0x02); /* XPM1 */ __t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */ printk("TE410P: Span %d configured for %s/%s%s\n", unit + 1, framing, line, crc4);}static int t4_startup(struct zt_span *span){ int i; int tspan; unsigned long flags; int alreadyrunning; struct t4 *wc = span->pvt; tspan = span->offset + 1; if (tspan < 0) { printk("TE410P: Span '%d' isn't us?\n", span->spanno); return -1; } spin_lock_irqsave(&wc->reglock, flags); 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++) { memset(wc->ec_chunk1[span->offset][i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); memset(wc->ec_chunk2[span->offset][i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); } /* Force re-evaluation fo timing source */ if (timingcable) wc->syncsrc = -1; if (wc->spantype[span->offset] == TYPE_E1) { /* if this is an E1 card */ __t4_configure_e1(wc, span->offset, span->lineconfig); } else { /* is a T1 card */ __t4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel); __set_clear(wc, span->offset); } if (!alreadyrunning) { span->flags |= ZT_FLAG_RUNNING; wc->spansstarted++; /* enable interrupts */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -