summaryrefslogtreecommitdiff
path: root/xpp/card_bri.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/card_bri.c')
-rw-r--r--xpp/card_bri.c359
1 files changed, 257 insertions, 102 deletions
diff --git a/xpp/card_bri.c b/xpp/card_bri.c
index ad10aed..9919036 100644
--- a/xpp/card_bri.c
+++ b/xpp/card_bri.c
@@ -105,7 +105,7 @@ static const char *xhfc_state_name(xpd_type_t xpd_type, enum xhfc_states state)
#define HFC_L1_ACTIVATING 1
#define HFC_L1_ACTIVATED 2
-#define NT_T1_COUNT 25 /* number of 4ms interrupts for G2 timeout */
+#define TIMER_T1_MAX 2500
#define HFC_TIMER_T3 8000 /* 8s activation timer T3 */
#define HFC_TIMER_T4 500 /* 500ms deactivation timer T4 */
#define HFC_TIMER_OFF -1 /* timer disabled */
@@ -130,6 +130,7 @@ typedef union {
} su_rd_sta_t;
#define REG30_LOST 3 /* in polls */
+#define DCHAN_LOST 15000 /* in ticks */
#define BRI_DCHAN_SIGCAP ( \
ZT_SIG_EM | \
@@ -163,18 +164,13 @@ static int proc_xpd_register_write(struct file *file, const char __user *buffer,
enum led_state {
BRI_LED_OFF = 0x0,
BRI_LED_ON = 0x1,
- BRI_LED_BLINK_SLOW = 0x2, /* 1/2 a second blink cycle */
- BRI_LED_BLINK_FAST = 0x3 /* 1/4 a second blink cycle */
-};
-
-#define LED_STATE_NAME(x) [ BRI_ ## x ] = #x
-static const char *led_state_names[] = {
- LED_STATE_NAME(LED_OFF),
- LED_STATE_NAME(LED_ON),
- LED_STATE_NAME(LED_BLINK_SLOW),
- LED_STATE_NAME(LED_BLINK_FAST),
+ /*
+ * We blink by software from driver, so that
+ * if the driver malfunction that blink would stop.
+ */
+ // BRI_LED_BLINK_SLOW = 0x2, /* 1/2 a second blink cycle */
+ // BRI_LED_BLINK_FAST = 0x3 /* 1/4 a second blink cycle */
};
-#undef LED_STATE_NAME
enum bri_led_names {
GREEN_LED = 0,
@@ -184,6 +180,7 @@ enum bri_led_names {
#define NUM_LEDS 2
#define LED_TICKS 100
+
struct bri_leds {
byte state:2;
byte led_sel:1; /* 0 - GREEN, 1 - RED */
@@ -201,11 +198,13 @@ struct BRI_priv_data {
struct proc_dir_entry *bri_info;
su_rd_sta_t state_register;
bool initialized;
+ int t1; /* timer 1 for NT deactivation */
int t3; /* timer 3 for activation */
int t4; /* timer 4 for deactivation */
ulong l1_flags;
bool reg30_good;
uint reg30_ticks;
+ bool layer1_up;
/*
* D-Chan: buffers + extra state info.
@@ -219,9 +218,14 @@ struct BRI_priv_data {
reg_cmd_t last_reply;
uint tick_counter;
uint poll_counter;
- uint drop_counter;
+ uint dchan_tx_counter;
+ uint dchan_rx_counter;
+ uint dchan_rx_drops;
+ bool dchan_alive;
+ uint dchan_alive_ticks;
+ uint dchan_notx_ticks;
+ uint dchan_norx_ticks;
enum led_state ledstate[NUM_LEDS];
- enum led_state ledcontrol[NUM_LEDS];
};
xproto_table_t PROTO_TABLE(BRI_NT);
@@ -240,19 +244,14 @@ static void dump_hex_buf(xpd_t *xpd, char *msg, byte *buf, size_t len)
{
char debug_buf[DEBUG_BUF_SIZE + 1];
int i;
- char *p;
+ int n = 0;
xbus_t *xbus = xpd->xbus;
- if (len >= DEBUG_BUF_SIZE) {
- ERR("%s: dumped buffer too long. Length: %d, Maximum allowed: %d.\n",
- __FUNCTION__, len, DEBUG_BUF_SIZE);
- return;
- }
- p = debug_buf;
- *p = '\0';
- for(i=0; i<len; i++)
- p += snprintf(p, DEBUG_BUF_SIZE - (p - debug_buf), "%02X ", buf[i]);
- printk(KERN_DEBUG "%s/%s: %s[0..%d]: %s\n", xbus->busname, xpd->xpdname, msg, len-1, debug_buf);
+ debug_buf[0] = '\0';
+ for(i = 0; i < len && n < DEBUG_BUF_SIZE; i++)
+ n += snprintf(&debug_buf[n], DEBUG_BUF_SIZE - n, "%02X ", buf[i]);
+ DBG("%s/%s: %s[0..%d]: %s%s\n", xbus->busname, xpd->xpdname, msg,
+ len-1, debug_buf, (n >= DEBUG_BUF_SIZE)?"...":"");
}
static void dump_dchan_packet(xpd_t *xpd, bool transmit, byte *buf, int len)
@@ -289,6 +288,83 @@ static void dump_dchan_packet(xpd_t *xpd, bool transmit, byte *buf, int len)
dump_hex_buf(xpd, msgbuf, buf, len);
}
+static void layer1_state(xpd_t *xpd, bool up)
+{
+ struct BRI_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ if(priv->layer1_up == up)
+ return;
+ priv->layer1_up = up;
+ DBG("%s/%s: STATE CHANGE: Layer1 %s\n", xpd->xbus->busname, xpd->xpdname,
+ (up)?"UP":"DOWN");
+}
+
+static void dchan_state(xpd_t *xpd, bool up)
+{
+ struct BRI_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ if(priv->dchan_alive == up)
+ return;
+ if(up) {
+ DBG("%s/%s: STATE CHANGE: D-Channel RUNNING\n",
+ xpd->xbus->busname, xpd->xpdname);
+ priv->dchan_alive = 1;
+ } else {
+ DBG("%s/%s: STATE CHANGE: D-Channel STOPPED\n",
+ xpd->xbus->busname, xpd->xpdname);
+ priv->dchan_rx_counter = priv->dchan_tx_counter = priv->dchan_rx_drops = 0;
+ priv->dchan_alive = 0;
+ priv->dchan_alive_ticks = 0;
+ }
+}
+
+static void xpd_activation(xpd_t *xpd, bool on)
+{
+ struct BRI_priv_data *priv;
+ xbus_t *xbus;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ xbus = xpd->xbus;
+ DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"ON":"OFF");
+ switch(xpd->type) {
+ case XPD_TYPE_BRI_TE:
+ if(on) {
+ DBG("%s/%s: HFC_L1_ACTIVATE_TE\n", xbus->busname, xpd->xpdname);
+ set_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+ write_state_register(xpd, STA_ACTIVATE);
+ priv->t3 = HFC_TIMER_T3;
+ } else {
+ DBG("%s/%s: HFC_L1_FORCE_DEACTIVATE_TE\n", xbus->busname, xpd->xpdname);
+ write_state_register(xpd, STA_DEACTIVATE);
+ }
+ break;
+ case XPD_TYPE_BRI_NT:
+ if(on) {
+ DBG("%s/%s: HFC_L1_ACTIVATE_NT\n", xbus->busname, xpd->xpdname);
+ priv->t1 = TIMER_T1_MAX;
+ set_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+ write_state_register(xpd, STA_ACTIVATE | V_SU_SET_G2_G3);
+ } else {
+ DBG("%s/%s: HFC_L1_DEACTIVATE_NT\n", xbus->busname, xpd->xpdname);
+ write_state_register(xpd, STA_DEACTIVATE);
+ }
+ break;
+ default:
+ ERR("%s: %s/%s: Bad xpd type %d\n", __FUNCTION__,
+ xbus->busname, xpd->xpdname, xpd->type);
+ BUG();
+ }
+}
+
+
/*
* D-Chan receive
*/
@@ -371,6 +447,8 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
*/
dchan->bytes2receive = idx - 1;
dchan->eofrx = 1;
+ priv->dchan_rx_counter++;
+ priv->dchan_norx_ticks = 0;
drop:
priv->dchan_r_idx = 0;
out:
@@ -441,7 +519,7 @@ static int tx_dchan(xpd_t *xpd)
DBG("%s/%s: T3 expired\n", xpd->xbus->busname, xpd->xpdname);
priv->t3 = HFC_TIMER_OFF;
clear_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
- CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0); /* Deactivate TE */
+ xpd_activation(xpd, 0); /* Deactivate TE */
}
}
if (priv->t4 > HFC_TIMER_OFF) {
@@ -470,7 +548,8 @@ static int tx_dchan(xpd_t *xpd)
return -EINVAL;
}
if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
- CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1); /* Kick transmitter */
+ DBG("%s/%s: Kick D-Channel transmiter\n", xpd->xbus->busname, xpd->xpdname);
+ xpd_activation(xpd, 1);
return 0;
}
if(print_dbg)
@@ -483,6 +562,8 @@ static int tx_dchan(xpd_t *xpd)
if(ret < 0)
NOTICE("%s/%s: %s: failed sending xframe\n",
__FUNCTION__, xpd->xbus->busname, xpd->xpdname);
+ priv->dchan_tx_counter++;
+ priv->dchan_notx_ticks = 0;
return ret;
}
@@ -552,6 +633,7 @@ static int BRI_card_init(xbus_t *xbus, xpd_t *xpd)
priv->regfile->read_proc = proc_xpd_register_read;
priv->regfile->data = xpd;
#endif
+ priv->t1 = HFC_TIMER_OFF;
ret = run_initialize_registers(xpd);
if(ret < 0)
goto err;
@@ -562,9 +644,6 @@ static int BRI_card_init(xbus_t *xbus, xpd_t *xpd)
CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_HOST, 0);
DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
priv->initialized = 1;
- CALL_PROTO(BRI, SET_LED, xbus, xpd, GREEN_LED, BRI_LED_ON);
- CALL_PROTO(BRI, SET_LED, xbus, xpd, RED_LED, BRI_LED_ON);
- msleep(10);
return 0;
err:
clean_proc(xbus, xpd);
@@ -644,9 +723,6 @@ static int BRI_card_zaptel_postregistration(xpd_t *xpd, bool on)
priv = xpd->priv;
BUG_ON(!xbus);
DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"on":"off");
- msleep(10);
- CALL_PROTO(BRI, SET_LED, xbus, xpd, GREEN_LED, BRI_LED_OFF);
- CALL_PROTO(BRI, SET_LED, xbus, xpd, RED_LED, BRI_LED_OFF);
return(0);
}
@@ -656,6 +732,79 @@ int BRI_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
return 0;
}
+/*
+ * LED managment is done by the driver now:
+ * - Turn constant ON RED/GREEN led to indicate NT/TE port
+ * - Very fast "Double Blink" to indicate Layer1 alive (without D-Channel)
+ * - Constant blink (1/2 sec cycle) to indicate D-Channel alive.
+ */
+static void handle_leds(xbus_t *xbus, xpd_t *xpd)
+{
+ struct BRI_priv_data *priv;
+ unsigned int timer_count;
+ int which_led;
+ int other_led;
+ enum led_state ledstate;
+ int mod;
+
+ BUG_ON(!xpd);
+ if(xpd->type == XPD_TYPE_BRI_TE) {
+ which_led = GREEN_LED;
+ other_led = RED_LED;
+ } else {
+ which_led = RED_LED;
+ other_led = GREEN_LED;
+ }
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ ledstate = priv->ledstate[which_led];
+ timer_count = xpd->timer_count;
+ if((timer_count % DEFAULT_LED_PERIOD) == 0) {
+ if(xpd->blink_mode) {
+ // led state is toggled
+ if(ledstate == BRI_LED_OFF) {
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_ON);
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, other_led, BRI_LED_ON);
+ } else {
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_OFF);
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, other_led, BRI_LED_OFF);
+ }
+ return;
+ } else if(priv->ledstate[other_led] == BRI_LED_ON) /* cleanup after blink */
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, other_led, BRI_LED_OFF);
+ }
+ if(priv->dchan_alive) {
+ mod = timer_count % 1000;
+ switch(mod) {
+ case 0:
+ if(ledstate == BRI_LED_OFF)
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_ON);
+ break;
+ case 500:
+ if(ledstate == BRI_LED_ON)
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_OFF);
+ break;
+ }
+ } else if(priv->layer1_up) {
+ mod = timer_count % 1000;
+ switch(mod) {
+ case 0:
+ case 100:
+ if(ledstate == BRI_LED_OFF)
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_ON);
+ break;
+ case 50:
+ case 150:
+ if(ledstate == BRI_LED_ON)
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_OFF);
+ break;
+ }
+ } else {
+ if(priv->ledstate[which_led] != BRI_LED_ON)
+ CALL_PROTO(BRI, SET_LED, xbus, xpd, which_led, BRI_LED_ON);
+ }
+}
+
/* Poll the register ST/Up-State-machine Register, to see if the cable
* if a cable is connected to the port.
*/
@@ -673,29 +822,49 @@ static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd)
priv->poll_counter++;
CALL_PROTO(BRI, REGISTER_REQUEST, xbus, xpd, 0, 0, 0, A_SU_RD_STA, 0, 0, 0);
}
- if((priv->tick_counter % LED_TICKS) == 0) {
- int i;
-
- if(priv->reg30_good && priv->reg30_ticks > poll_interval * REG30_LOST) {
- /* No reply for 1/2 a second */
- ERR("%s/%s: Lost state tracking for %d ticks\n",
- xbus->busname, xpd->xpdname, priv->reg30_ticks);
- priv->reg30_good = 0;
- }
- if(!priv->reg30_good) {
- priv->ledcontrol[RED_LED] = BRI_LED_OFF;
- priv->ledcontrol[GREEN_LED] = BRI_LED_OFF;
- }
- for(i = 0; i < NUM_LEDS; i++) {
- if(xpd->blink_mode) {
- CALL_PROTO(BRI, SET_LED, xbus, xpd, i, BRI_LED_BLINK_FAST);
- } else if(priv->ledstate[i] != priv->ledcontrol[i]) {
- CALL_PROTO(BRI, SET_LED, xbus, xpd, i,
- priv->ledcontrol[i]);
+ /* Detect D-Channel disconnect heuristic */
+ priv->dchan_notx_ticks++;
+ priv->dchan_norx_ticks++;
+ priv->dchan_alive_ticks++;
+ if(priv->dchan_alive && (priv->dchan_notx_ticks > DCHAN_LOST || priv->dchan_norx_ticks > DCHAN_LOST)) {
+ /*
+ * No tx_dchan() or rx_dchan() for many ticks
+ * This D-Channel is probabelly dead.
+ */
+ dchan_state(xpd, 0);
+ } else if(priv->dchan_rx_counter > 1 && priv->dchan_tx_counter > 1) {
+ if(!priv->dchan_alive)
+ dchan_state(xpd, 1);
+ }
+ /* Detect Layer1 disconnect */
+ if(priv->reg30_good && priv->reg30_ticks > poll_interval * REG30_LOST) {
+ /* No reply for 1/2 a second */
+ ERR("%s/%s: Lost state tracking for %d ticks\n",
+ xbus->busname, xpd->xpdname, priv->reg30_ticks);
+ priv->reg30_good = 0;
+ layer1_state(xpd, 0);
+ dchan_state(xpd, 0);
+ }
+ handle_leds(xbus, xpd);
+ tx_dchan(xpd);
+#if 0
+ /*
+ Currently not used -- do we want to shut down NT if it wasn't
+ responding? For how long?
+ */
+
+ /* Detect T1 timer expiry on NT */
+ if(xpd->type == XPD_TYPE_BRI_NT) {
+ if (priv->t1 > HFC_TIMER_OFF) {
+ if (--priv->t1 == 0) {
+ DBG("%s/%s: T1 Expired. Kick NT\n", xbus->busname, xpd->xpdname);
+ priv->t1 = HFC_TIMER_OFF;
+ clear_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+ write_state_register(xpd, STA_DEACTIVATE);
}
}
}
- tx_dchan(xpd);
+#endif
priv->tick_counter++;
priv->reg30_ticks++;
return 0;
@@ -723,7 +892,7 @@ static int BRI_span_startup(xpd_t *xpd)
BUG_ON(!priv);
DBG("%s/%s: STARTUP\n", xpd->xbus->busname, xpd->xpdname);
write_state_register(xpd, 0); /* Enable L1 state machine */
- CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1);
+ xpd_activation(xpd, 1);
if(SPAN_REGISTERED(xpd)) {
dchan = &xpd->span.chans[2];
xpd->span.flags |= ZT_FLAG_RUNNING;
@@ -748,7 +917,7 @@ static int BRI_span_shutdown(xpd_t *xpd)
BUG_ON(!priv);
DBG("%s/%s: SHUTDOWN\n", xpd->xbus->busname, xpd->xpdname);
if(xpd->type == XPD_TYPE_BRI_NT)
- CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0);
+ xpd_activation(xpd, 0);
return 0;
}
@@ -788,39 +957,9 @@ static int BRI_span_shutdown(xpd_t *xpd)
/* 0x0F */ HOSTCMD(BRI, XPD_STATE, bool on)
{
- struct BRI_priv_data *priv;
-
BUG_ON(!xpd);
- priv = xpd->priv;
- BUG_ON(!priv);
DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"ON":"OFF");
- switch(xpd->type) {
- case XPD_TYPE_BRI_TE:
- if(on) {
- DBG("%s/%s: HFC_L1_ACTIVATE_TE\n", xbus->busname, xpd->xpdname);
- set_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
- write_state_register(xpd, STA_ACTIVATE);
- priv->t3 = HFC_TIMER_T3;
- } else {
- DBG("%s/%s: HFC_L1_FORCE_DEACTIVATE_TE\n", xbus->busname, xpd->xpdname);
- write_state_register(xpd, STA_DEACTIVATE);
- }
- break;
- case XPD_TYPE_BRI_NT:
- if(on) {
- DBG("%s/%s: HFC_L1_ACTIVATE_NT\n", xbus->busname, xpd->xpdname);
- set_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
- write_state_register(xpd, STA_ACTIVATE | V_SU_SET_G2_G3);
- } else {
- DBG("%s/%s: HFC_L1_DEACTIVATE_NT\n", xbus->busname, xpd->xpdname);
- write_state_register(xpd, STA_DEACTIVATE);
- }
- break;
- default:
- ERR("%s: %s/%s: Bad xpd type %d\n", __FUNCTION__,
- xbus->busname, xpd->xpdname, xpd->type);
- return -EINVAL;
- }
+ xpd_activation(xpd, on);
return 0;
}
@@ -849,11 +988,6 @@ static int BRI_span_shutdown(xpd_t *xpd)
priv = xpd->priv;
BUG_ON(!priv);
XFRAME_NEW(xframe, pack, xbus, BRI, SET_LED, xpd->id);
-#if 1
- DBG("%s/%s: %s %s (%d)\n", xbus->busname, xpd->xpdname,
- (red_led)?"RED":"GREEN",
- led_state_names[to_led_state], to_led_state);
-#endif
bri_leds = &RPACKET_FIELD(pack, BRI, SET_LED, bri_leds);
bri_leds->state = to_led_state;
bri_leds->led_sel = which_led;
@@ -880,28 +1014,39 @@ static int write_state_register(xpd_t *xpd, byte value)
return ret;
}
-
/*---------------- BRI: Astribank Reply Handlers --------------------------*/
static void su_new_state(xpd_t *xpd, byte reg_x30)
{
xbus_t *xbus;
struct BRI_priv_data *priv;
su_rd_sta_t new_state;
- int which_led = (xpd->type == XPD_TYPE_BRI_TE) ? GREEN_LED : RED_LED;
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
xbus = xpd->xbus;
+ if(!priv->initialized) {
+ ERR("%s/%s: %s called on uninitialized AB\n",
+ xbus->busname, xpd->xpdname, __FUNCTION__);
+ return;
+ }
new_state.reg = reg_x30;
priv->reg30_ticks = 0;
priv->reg30_good = 1;
if((xpd->type == XPD_TYPE_BRI_TE && new_state.bits.v_su_sta == ST_TE_ACTIVATED) ||
(xpd->type == XPD_TYPE_BRI_NT && new_state.bits.v_su_sta == ST_NT_ACTIVATED)) {
- priv->ledcontrol[which_led] = (new_state.bits.v_su_fr_sync) ? BRI_LED_BLINK_SLOW : BRI_LED_BLINK_FAST;
- update_xpd_status(xpd, ZT_ALARM_NONE);
+ if(!priv->layer1_up) {
+ layer1_state(xpd, 1);
+ update_xpd_status(xpd, ZT_ALARM_NONE);
+ }
} else {
- priv->ledcontrol[which_led] = BRI_LED_OFF;
+ /*
+ * Layer 1 disconnected
+ */
+ if(priv->layer1_up) {
+ layer1_state(xpd, 0);
+ dchan_state(xpd, 0);
+ }
/*
* Do NOT notify Zaptel about the disconnection.
* If we do, Asterisk stops transmitting on the D-channel and
@@ -917,7 +1062,7 @@ static void su_new_state(xpd_t *xpd, byte reg_x30)
if (priv->state_register.bits.v_su_sta == new_state.bits.v_su_sta)
return; /* same same */
DBG("%02X ---> %02X\n", priv->state_register.reg, reg_x30);
- DBG("%s/%s: %s%i\n", xpd->xbus->busname, xpd->xpdname,
+ DBG("%s/%s: %s%i\n", xbus->busname, xpd->xpdname,
(xpd->type == XPD_TYPE_BRI_NT)?"G":"F",
new_state.bits.v_su_sta);
@@ -965,18 +1110,21 @@ static void su_new_state(xpd_t *xpd, byte reg_x30)
case ST_NT_DEACTIVATED: /* G1 */
DBG("%s/%s: State ST_NT_DEACTIVATED (G1)\n", xbus->busname, xpd->xpdname);
clear_bit(HFC_L1_ACTIVATED, &priv->l1_flags);
+ priv->t1 = HFC_TIMER_OFF;
break;
case ST_NT_ACTIVATING: /* G2 */
DBG("%s/%s: State ST_NT_ACTIVATING (G2)\n", xbus->busname, xpd->xpdname);
- write_state_register(xpd, V_SU_SET_G2_G3); /* Enable transition to G3 */
+ xpd_activation(xpd, 1);
break;
case ST_NT_ACTIVATED: /* G3 */
DBG("%s/%s: State ST_NT_ACTIVATED (G3)\n", xbus->busname, xpd->xpdname);
clear_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
set_bit(HFC_L1_ACTIVATED, &priv->l1_flags);
+ priv->t1 = HFC_TIMER_OFF;
break;
case ST_NT_DEACTIVTING: /* G4 */
DBG("%s/%s: State ST_NT_DEACTIVTING (G4)\n", xbus->busname, xpd->xpdname);
+ priv->t1 = HFC_TIMER_OFF;
break;
default:
NOTICE("%s/%s: Bad NT state: %d\n", xbus->busname, xpd->xpdname, new_state.bits.v_su_sta);
@@ -1021,7 +1169,7 @@ HANDLER_DEF(BRI, REGISTER_REPLY)
#endif
ret = rx_dchan(xpd, info);
if (ret < 0) {
- priv->drop_counter++;
+ priv->dchan_rx_drops++;
if(atomic_read(&xpd->open_counter) > 0)
NOTICE("%s/%s: Multibyte Drop: errno=%d\n", xbus->busname, xpd->xpdname, ret);
}
@@ -1129,8 +1277,9 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
- len += sprintf(page + len, "%05d Layer 1 State: ", priv->poll_counter);
+ len += sprintf(page + len, "%05d Layer 1: ", priv->poll_counter);
if(priv->reg30_good) {
+ len += sprintf(page + len, "%-5s ", (priv->layer1_up) ? "UP" : "DOWN");
len += sprintf(page + len, "%c%d %-15s -- fr_sync=%d t2_exp=%d info0=%d g2_g3=%d\n",
(xpd->type == XPD_TYPE_BRI_NT)?'G':'F',
priv->state_register.bits.v_su_sta,
@@ -1141,14 +1290,20 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
priv->state_register.bits.v_g2_g3);
} else
len += sprintf(page + len, "Unkown\n");
+ if(xpd->type == XPD_TYPE_BRI_NT)
+ len += sprintf(page + len, "T1 Timer: %d\n", priv->t1);
len += sprintf(page + len, "Tick Counter: %d\n", priv->tick_counter);
len += sprintf(page + len, "Last Poll Reply: %d ticks ago\n", priv->reg30_ticks);
len += sprintf(page + len, "reg30_good=%d\n", priv->reg30_good);
- len += sprintf(page + len, "Drop Counter: %d\n", priv->drop_counter);
+ len += sprintf(page + len, "D-Channel: TX=[%5d] RX=[%5d] BAD=[%5d] (%s)\n\n",
+ priv->dchan_tx_counter, priv->dchan_rx_counter, priv->dchan_rx_drops,
+ (priv->dchan_alive) ? "alive" : "dead");
+ len += sprintf(page + len, "dchan_alive_ticks: %d\n", priv->dchan_alive_ticks);
+ len += sprintf(page + len, "dchan_notx_ticks: %d\n", priv->dchan_notx_ticks);
+ len += sprintf(page + len, "dchan_norx_ticks: %d\n", priv->dchan_norx_ticks);
for(led = 0; led < NUM_LEDS; led++) {
len += sprintf(page + len, "LED #%d\n", led);
len += sprintf(page + len, "\tledstate : %d\n", priv->ledstate[led]);
- len += sprintf(page + len, "\tledcontrol: %d\n", priv->ledcontrol[led]);
}
len += sprintf(page + len, "\nDCHAN:\n");
len += sprintf(page + len, "\n");