summaryrefslogtreecommitdiff
path: root/kernel/xpp/card_pri.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-03-21 01:51:39 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-03-21 01:51:39 +0000
commitd2bf4b90b68c4010d46398858cbfc589e1d9ff54 (patch)
tree87b3f40ee02b4ea949acd2c9bf2113417a38a6b2 /kernel/xpp/card_pri.c
parente0c4098698e7a7b4aa911c2bd292be398e78aa82 (diff)
* Earleier initialization of PRI module's register.
* Fix zaptel-perl reporting of battery after procfs changes. * Documentation updates. * Block hdlcstress/test fixes that followed: already merged. Merged revisions 4036 via svnmerge from http://svn.digium.com/svn/zaptel/branches/1.2 git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4039 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/xpp/card_pri.c')
-rw-r--r--kernel/xpp/card_pri.c98
1 files changed, 64 insertions, 34 deletions
diff --git a/kernel/xpp/card_pri.c b/kernel/xpp/card_pri.c
index eeabb25..08ac650 100644
--- a/kernel/xpp/card_pri.c
+++ b/kernel/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,15 +750,46 @@ 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
* zaptel functions.
@@ -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);