From b04ba7d0159f807f3b8a4dc88123e1163506729d Mon Sep 17 00:00:00 2001 From: tzafrir Date: Fri, 21 Mar 2008 00:36:13 +0000 Subject: * Earleier initialization of PRI module's register. * Fix zaptel-perl reporting of battery after procfs changes. * Documentation updates. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@4036 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/card_pri.c | 98 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 34 deletions(-) (limited to 'xpp/card_pri.c') diff --git a/xpp/card_pri.c b/xpp/card_pri.c index eeabb25..08ac650 100644 --- a/xpp/card_pri.c +++ b/xpp/card_pri.c @@ -175,6 +175,8 @@ struct pri_leds { }; #define REG_FRS0 0x4C /* Framer Receive Status Register 0 */ +#define REG_FRS0_LMFA BIT(1) /* Loss of Multiframe Alignment */ +#define REG_FRS0_NMF BIT(2) /* No Multiframe Alignment Found */ #define REG_FRS0_RRA BIT(4) /* Receive Remote Alarm: T1-YELLOW-Alarm */ #define REG_FRS0_LFA BIT(5) /* Loss of Frame Alignment */ #define REG_FRS0_AIS BIT(6) /* Alarm Indication Signal: T1-BLUE-Alarm */ @@ -654,13 +656,8 @@ static const struct { VALID_CONFIG(10, ZT_CONFIG_CRC4, "CRC4"), }; -/* - * Called only for 'span' keyword in /etc/zaptel.conf - */ - -static int pri_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) +static int pri_lineconfig(xpd_t *xpd, int lineconfig) { - xpd_t *xpd = span->pvt; struct PRI_priv_data *priv; const char *framingstr = ""; const char *codingstr = ""; @@ -676,8 +673,8 @@ static int pri_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) /* * validate */ - bad_bits = lc->lineconfig & pri_linecompat(priv->pri_protocol); - bad_bits = bad_bits ^ lc->lineconfig; + bad_bits = lineconfig & pri_linecompat(priv->pri_protocol); + bad_bits = bad_bits ^ lineconfig; for(i = 0; i < ARRAY_SIZE(valid_spanconfigs); i++) { unsigned int flags = valid_spanconfigs[i].flags; @@ -703,15 +700,6 @@ static int pri_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) } if(bad_bits) goto bad_lineconfig; - if(lc->span != xpd->span.spanno) { - XPD_ERR(xpd, "I am span %d but got spanconfig for span %d\n", - xpd->span.spanno, lc->span); - return -EINVAL; - } - /* - * FIXME: lc->name is unused by ztcfg and zaptel... - * We currently ignore it also. - */ if(priv->pri_protocol == PRI_PROTO_E1) fmr2 = REG_FMR2_E_AXRA | REG_FMR2_E_ALMF; /* 0x03 */ else if(priv->pri_protocol == PRI_PROTO_T1) @@ -723,41 +711,37 @@ static int pri_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) if(priv->local_loopback) fmr2 |= REG_FMR2_E_PLB; /* framing first */ - if (lc->lineconfig & ZT_CONFIG_B8ZS) { + if (lineconfig & ZT_CONFIG_B8ZS) { framingstr = "B8ZS"; fmr0 = REG_FMR0_E_XC1 | REG_FMR0_E_XC0 | REG_FMR0_E_RC1 | REG_FMR0_E_RC0; - } else if (lc->lineconfig & ZT_CONFIG_AMI) { + } else if (lineconfig & ZT_CONFIG_AMI) { framingstr = "AMI"; fmr0 = REG_FMR0_E_XC1 | REG_FMR0_E_RC1; - } else if (lc->lineconfig & ZT_CONFIG_HDB3) { + } else if (lineconfig & ZT_CONFIG_HDB3) { framingstr = "HDB3"; fmr0 = REG_FMR0_E_XC1 | REG_FMR0_E_XC0 | REG_FMR0_E_RC1 | REG_FMR0_E_RC0; } /* then coding */ - if (lc->lineconfig & ZT_CONFIG_ESF) { + if (lineconfig & ZT_CONFIG_ESF) { codingstr = "ESF"; fmr4 |= REG_FMR4_FM1; fmr2 |= REG_FMR2_T_AXRA | REG_FMR2_T_MCSP | REG_FMR2_T_SSP; - } else if (lc->lineconfig & ZT_CONFIG_D4) { + } else if (lineconfig & ZT_CONFIG_D4) { codingstr = "D4"; - } else if (lc->lineconfig & ZT_CONFIG_CCS) { + } else if (lineconfig & ZT_CONFIG_CCS) { codingstr = "CCS"; /* do nothing */ } /* E1's can enable CRC checking */ - if (lc->lineconfig & ZT_CONFIG_CRC4) { + if (lineconfig & ZT_CONFIG_CRC4) { crcstr = "CRC4"; fmr2 |= REG_FMR2_E_RFS1; } - XPD_DBG(GENERAL, xpd, "[%s] lbo=%d lineconfig=%s/%s/%s %s (0x%X) sync=%d\n", + XPD_DBG(GENERAL, xpd, "[%s] lineconfig=%s/%s/%s %s (0x%X)\n", (priv->is_nt)?"NT":"TE", - lc->lbo, framingstr, codingstr, crcstr, - (lc->lineconfig & ZT_CONFIG_NOTOPEN)?"YELLOW":"", - lc->lineconfig, - lc->sync); - span->lineconfig = lc->lineconfig; - xpd->timing_priority = lc->sync; + (lineconfig & ZT_CONFIG_NOTOPEN)?"YELLOW":"", + lineconfig); if(fmr0 != 0) { XPD_DBG(GENERAL, xpd, "%s: fmr0(0x%02X) = 0x%02X\n", __FUNCTION__, REG_FMR0, fmr0); write_subunit(xpd, REG_FMR0, fmr0); @@ -766,14 +750,45 @@ static int pri_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) write_subunit(xpd, REG_FMR4, fmr4); XPD_DBG(GENERAL, xpd, "%s: fmr2(0x%02X) = 0x%02X\n", __FUNCTION__, REG_FMR2, fmr2); write_subunit(xpd, REG_FMR2, fmr2); - set_master_mode("spanconfig", xpd); - elect_syncer("PRI-master_mode"); return 0; bad_lineconfig: - XPD_ERR(xpd, "Bad span configuration. Abort\n"); + XPD_ERR(xpd, "Bad lineconfig. Abort\n"); return -EINVAL; } +/* + * Called only for 'span' keyword in /etc/zaptel.conf + */ + +static int pri_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) +{ + xpd_t *xpd = span->pvt; + struct PRI_priv_data *priv; + int ret; + + BUG_ON(!xpd); + priv = xpd->priv; + if(lc->span != xpd->span.spanno) { + XPD_ERR(xpd, "I am span %d but got spanconfig for span %d\n", + xpd->span.spanno, lc->span); + return -EINVAL; + } + /* + * FIXME: lc->name is unused by ztcfg and zaptel... + * We currently ignore it also. + */ + XPD_DBG(GENERAL, xpd, "[%s] lbo=%d lineconfig=0x%X sync=%d\n", + (priv->is_nt)?"NT":"TE", lc->lbo, lc->lineconfig, lc->sync); + ret = pri_lineconfig(xpd, lc->lineconfig); + if(!ret) { + span->lineconfig = lc->lineconfig; + xpd->timing_priority = lc->sync; + set_master_mode("spanconfig", xpd); + elect_syncer("PRI-master_mode"); + } + return ret; +} + /* * Set signalling type (if appropriate) * Called from zaptel with spinlock held on chan. Must not call back @@ -839,6 +854,15 @@ static int PRI_card_init(xbus_t *xbus, xpd_t *xpd) XPD_NOTICE(xpd, "PRI protocol not set\n"); goto err; } + /* + * Must set default now, so layer1 polling (Register REG_FRS0) would + * give reliable results. + */ + ret = pri_lineconfig(xpd, ZT_CONFIG_CCS | ZT_CONFIG_CRC4 | ZT_CONFIG_HDB3); + if(ret) { + XPD_NOTICE(xpd, "Failed setting PRI default line config\n"); + goto err; + } XPD_DBG(GENERAL, xpd, "done\n"); for(ret = 0; ret < NUM_LEDS; ret++) { DO_LED(xpd, ret, PRI_LED_ON); @@ -1332,6 +1356,12 @@ static void layer1_state(xpd_t *xpd, byte subunit, byte data_low) if(data_low & REG_FRS0_RRA) alarms |= ZT_ALARM_YELLOW; priv->layer1_up = alarms == 0; + /* + * Some bad bits (e.g: LMFA and NMF have no alarm "colors" + * associated. However, layer1 is still not working if they are set. + */ + if(data_low & (REG_FRS0_LMFA | REG_FRS0_NMF)) + priv->layer1_up = 0; priv->alarms = alarms; if(!priv->layer1_up) dchan_state(xpd, 0); -- cgit v1.2.3