Commit 59851da4 authored by baujc's avatar baujc

In WR states with retry, improve precision of the time-out

Instead of restarting a timer on each retry, the timer is initialized
only once when we enter in the state. It helps to respect the time spent
in a given state before to skip it due to the time-out.
parent 70a3421a
......@@ -46,20 +46,6 @@ enum {
#define PROTO_EXT_HAS_FAULTS 0
#endif
/* Contains portDS common stuff which is manipulated outside of the protocol extension code */
/* Must be declared on top of the extension portDS structure */
typedef struct {
Boolean extModeOn;
Boolean ppsOutputOn;
} wrh_portds_head_t;
/* The head is expected at the beginning of the portDS structure */
static inline wrh_portds_head_t *WRH_DSPOR_HEAD(struct pp_instance *ppi)
{
return (wrh_portds_head_t *) ppi->portDS->ext_dsport;
}
/* White Rabbit hw-dependent functions (code in arch-wrpc and arch-wrs) */
struct wrh_operations {
int (*locking_enable)(struct pp_instance *ppi);
......
......@@ -10,9 +10,9 @@ static int wr_init(struct pp_instance *ppi, void *buf, int len)
wrp->wrStateTimeout = WR_DEFAULT_STATE_TIMEOUT_MS;
wrp->calPeriod = WR_DEFAULT_CAL_PERIOD;
wrp->head.extModeOn = 0;
wrp->wrModeOn =
wrp->parentWrModeOn = FALSE;
wrp->parentWrConfig = NON_WR;
wrp->parentExtModeOn = 0;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
#ifdef CONFIG_ABSCAL
......@@ -111,7 +111,7 @@ static int wr_handle_resp(struct pp_instance *ppi)
* After we adjusted the pps counter, stamps are invalid, so
* we'll have the Unix time instead, marked by "correct"
*/
if (!wrp->head.extModeOn) {
if (!wrp->wrModeOn) {
if ( is_timestamps_incorrect(ppi, NULL, 0x6 /* mask=t2&t3 */) ) {
pp_diag(ppi, servo, 1,
"T2 or T3 incorrect, discarding tuple\n");
......@@ -135,7 +135,7 @@ static void wr_s1(struct pp_instance *ppi, struct pp_frgn_master *frgn_master)
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
WR_DSPOR(ppi)->parentIsWRnode =
((frgn_master->ext_specific & WR_NODE_MODE) != NON_WR);
WR_DSPOR(ppi)->parentExtModeOn =
WR_DSPOR(ppi)->parentWrModeOn =
(frgn_master->ext_specific & WR_IS_WR_MODE) ? TRUE : FALSE;
WR_DSPOR(ppi)->parentCalibrated =
((frgn_master->ext_specific & WR_IS_CALIBRATED) ? 1 : 0);
......@@ -154,7 +154,7 @@ int wr_execute_slave(struct pp_instance *ppi)
if ((ppi->state == PPS_SLAVE) &&
(WR_DSPOR(ppi)->wrConfig & WR_S_ONLY) &&
(WR_DSPOR(ppi)->parentWrConfig & WR_M_ONLY) &&
(!WR_DSPOR(ppi)->head.extModeOn || !WR_DSPOR(ppi)->parentExtModeOn)) {
(!WR_DSPOR(ppi)->wrModeOn || !WR_DSPOR(ppi)->parentWrModeOn)) {
/* We must start the handshake as a WR slave */
wr_handshake_init(ppi, PPS_SLAVE);
}
......@@ -189,7 +189,7 @@ static int wr_handle_announce(struct pp_instance *ppi)
static int wr_sync_followup(struct pp_instance *ppi, struct pp_time *t1) {
if (!WR_DSPOR(ppi)->head.extModeOn)
if (!WR_DSPOR(ppi)->wrModeOn)
return 0;
wr_servo_got_sync(ppi, t1, &ppi->t2);
......@@ -225,7 +225,7 @@ static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi)
* we'll have the Unix time instead, marked by "correct"
*/
if (!wrp->head.extModeOn) {
if (!wrp->wrModeOn) {
if ( is_timestamps_incorrect(ppi, NULL, 0x24 /* mask=t3&t6 */) ) {
pp_diag(ppi, servo, 1,
"T3 or T6 incorrect, discarding tuple\n");
......@@ -312,15 +312,15 @@ static void wr_state_change(struct pp_instance *ppi)
/* if we are leaving the WR locked states reset the WR process */
if ((ppi->next_state != ppi->state) &&
(wrp->head.extModeOn == TRUE) &&
wrp->wrModeOn &&
((ppi->state == PPS_SLAVE) ||
(ppi->state == PPS_MASTER))) {
wrp->wrStateTimeout = WR_DEFAULT_STATE_TIMEOUT_MS;
wrp->calPeriod = WR_DEFAULT_CAL_PERIOD;
wrp->head.extModeOn = FALSE;
wrp->wrModeOn =
wrp->parentWrModeOn = FALSE;
wrp->parentWrConfig = NON_WR;
wrp->parentExtModeOn = FALSE;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
if (ppi->state == PPS_SLAVE)
......
......@@ -16,28 +16,30 @@ int wr_calibrated(struct pp_instance *ppi, void *buf, int len)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
MsgSignaling wrsig_msg;
int e = 0, enable = 0;
int enable = 0;
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_CALIBRATED_TIMEOUT_MS*(WR_STATE_RETRY+1));
enable = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*WR_CALIBRATED_TIMEOUT_MS)) {
/*
* FIXME: We should implement a retry by re-sending
* the "calibrated" message, moving it here from the
* previous state (sub-state 8 of "state-wr-calibration"
*/
if (wr_handshake_retry(ppi))
enable = 1;
else
return 0; /* non-wr already */
if (wr_handshake_retry(ppi))
enable = 1;
else
return 0; /* non-wr already */
}
}
if (enable)
{
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_CALIBRATED_TIMEOUT_MS);
e = msg_issue_wrsig(ppi, CALIBRATED);
}
if (enable){
msg_issue_wrsig(ppi, CALIBRATED);
}
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
......@@ -51,6 +53,6 @@ int wr_calibrated(struct pp_instance *ppi, void *buf, int len)
ppi->next_state = WRS_WR_LINK_ON;
}
ppi->next_delay = wrp->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*WR_CALIBRATED_TIMEOUT_MS;
return 0;
}
......@@ -20,16 +20,19 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0, wrp->calPeriod*(WR_STATE_RETRY+1));
sendmsg = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*wrp->calPeriod)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
}
}
if (sendmsg) {
__pp_timeout_set(ppi, PP_TO_EXT_0, wrp->calPeriod);
msg_issue_wrsig(ppi, CALIBRATE);
wrp->wrPortState = WR_PORT_CALIBRATION_0;
if (wrp->calibrated)
......@@ -134,7 +137,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
break;
}
ppi->next_delay = wrp->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*wrp->calPeriod;
return 0; /* ignore error */
}
......@@ -17,13 +17,13 @@ int wr_link_on(struct pp_instance *ppi, void *buf, int len)
struct wr_dsport *wrp = WR_DSPOR(ppi);
int e = 0;
wrp->head.extModeOn = TRUE;
wrp->wrModeOn = TRUE;
WRH_OPER()->enable_ptracker(ppi);
if (wrp->wrMode == WR_MASTER)
e = msg_issue_wrsig(ppi, WR_MODE_ON);
wrp->parentExtModeOn = TRUE;
wrp->parentWrModeOn = TRUE;
if (e != 0)
return -1;
......
......@@ -14,23 +14,26 @@
*/
int wr_locked(struct pp_instance *ppi, void *buf, int len)
{
int e = 0, sendmsg = 0;
int e=0, sendmsg = 0;
MsgSignaling wrsig_msg;
struct wr_dsport *wrp = WR_DSPOR(ppi);
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_LOCKED_TIMEOUT_MS*(WR_STATE_RETRY+1));
sendmsg = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*WR_LOCKED_TIMEOUT_MS)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
}
}
if (sendmsg) {
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_LOCKED_TIMEOUT_MS);
e = msg_issue_wrsig(ppi, LOCKED);
e=msg_issue_wrsig(ppi, LOCKED);
}
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
......@@ -42,7 +45,7 @@ int wr_locked(struct pp_instance *ppi, void *buf, int len)
ppi->next_state = WRS_RESP_CALIB_REQ;
}
ppi->next_delay = wrp->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*WR_LOCKED_TIMEOUT_MS;
return e;
}
......@@ -20,17 +20,20 @@ int wr_m_lock(struct pp_instance *ppi, void *buf, int len)
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_M_LOCK_TIMEOUT_MS*(WR_STATE_RETRY+1));
sendmsg = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*WR_M_LOCK_TIMEOUT_MS)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
}
}
if (sendmsg) {
e = msg_issue_wrsig(ppi, LOCK);
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_M_LOCK_TIMEOUT_MS);
}
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
......@@ -42,7 +45,7 @@ int wr_m_lock(struct pp_instance *ppi, void *buf, int len)
}
ppi->next_delay = wrp->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*WR_M_LOCK_TIMEOUT_MS;
return e;
}
......@@ -23,16 +23,19 @@ int wr_present(struct pp_instance *ppi, void *buf, int len)
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_PRESENT_TIMEOUT_MS*(WR_STATE_RETRY+1));
sendmsg = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*WR_PRESENT_TIMEOUT_MS)) {
if (wr_handshake_retry(ppi))
sendmsg = 1;
else
return 0; /* non-wr already */
}
}
if (sendmsg) {
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_PRESENT_TIMEOUT_MS);
e = msg_issue_wrsig(ppi, SLAVE_PRESENT);
}
......@@ -50,7 +53,7 @@ int wr_present(struct pp_instance *ppi, void *buf, int len)
/* nothing, just stay here again */
}
ppi->next_delay = WR_DSPOR(ppi)->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*WR_PRESENT_TIMEOUT_MS;
return e;
}
......@@ -17,21 +17,23 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len)
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0,WR_RESP_CALIB_REQ_TIMEOUT_MS*(WR_STATE_RETRY+1));
enable = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
if (send_pattern)
WRH_OPER()->calib_pattern_disable(ppi);
if (wr_handshake_retry(ppi))
enable = 1;
else
return 0; /* non-wr already */
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*WR_RESP_CALIB_REQ_TIMEOUT_MS)) {
if (send_pattern)
WRH_OPER()->calib_pattern_disable(ppi);
if (wr_handshake_retry(ppi))
enable = 1;
else
return 0; /* non-wr already */
}
}
if (enable) { /* first or retry */
if (send_pattern)
WRH_OPER()->calib_pattern_enable(ppi, 0, 0, 0);
__pp_timeout_set(ppi, PP_TO_EXT_0,
WR_RESP_CALIB_REQ_TIMEOUT_MS);
}
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
......@@ -49,6 +51,6 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len)
}
}
ppi->next_delay = wrp->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*WR_RESP_CALIB_REQ_TIMEOUT_MS;
return e;
}
......@@ -16,21 +16,24 @@ int wr_s_lock(struct pp_instance *ppi, void *buf, int len)
if (ppi->is_new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_S_LOCK_TIMEOUT_MS*(WR_STATE_RETRY+1));
enable = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
WRH_OPER()->locking_disable(ppi);
if (wr_handshake_retry(ppi))
enable = 1;
else
return 0; /* non-wr already */
} else {
int rms=pp_next_delay_1(ppi, PP_TO_EXT_0);
if ( rms==0 || rms<(wrp->wrStateRetry*WR_S_LOCK_TIMEOUT_MS)) {
WRH_OPER()->locking_disable(ppi);
if (wr_handshake_retry(ppi))
enable = 1;
else
return 0; /* non-wr already */
}
}
if (enable) {
WRH_OPER()->locking_enable(ppi);
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_S_LOCK_TIMEOUT_MS);
}
ppi->next_delay = wrp->wrStateTimeout;
ppi->next_delay = pp_next_delay_1(ppi,PP_TO_EXT_0)-wrp->wrStateRetry*WR_S_LOCK_TIMEOUT_MS;
poll_ret = WRH_OPER()->locking_poll(ppi, 0);
if (poll_ret == WRH_SPLL_READY) {
......
......@@ -29,9 +29,8 @@
* (see wrspec.v2-06-07-2011, page 17)
*/
struct wr_dsport {
wrh_portds_head_t head; /* Must on top of portDS */
Boolean parentExtModeOn;
Boolean wrModeOn; /* True when extension is running */
Boolean parentWrModeOn;
FixedDelta deltaTx;
FixedDelta deltaRx;
FixedDelta otherNodeDeltaTx;
......
......@@ -25,13 +25,14 @@
#define WR_DEFAULT_STATE_TIMEOUT_MS 300 /* [ms] ML: not really used*/
#define WR_PRESENT_TIMEOUT_MS 1000
#define WR_PRESENT_TIMEOUT_MS 1000
#define WR_M_LOCK_TIMEOUT_MS 15000
#define WR_S_LOCK_TIMEOUT_MS 15000
#define WR_LOCKED_TIMEOUT_MS 300
#define WR_CALIBRATION_TIMEOUT_MS 3000
#define WR_RESP_CALIB_REQ_TIMEOUT_MS 100 // 3
#define WR_CALIBRATED_TIMEOUT_MS 300
#define WR_LOCKED_TIMEOUT_MS 300
#define WR_CALIBRATION_TIMEOUT_MS 3000
#define WR_RESP_CALIB_REQ_TIMEOUT_MS 100 // 3
#define WR_CALIBRATED_TIMEOUT_MS 300
#define WR_DEFAULT_CAL_PERIOD WR_CALIBRATION_TIMEOUT_MS /* [us] */
......
......@@ -77,7 +77,7 @@ void msg_pack_announce_wr_tlv(struct pp_instance *ppi)
if (WR_DSPOR(ppi)->calibrated)
wr_flags = WR_IS_CALIBRATED | wr_flags;
if (WR_DSPOR(ppi)->head.extModeOn)
if (WR_DSPOR(ppi)->wrModeOn)
wr_flags = WR_IS_WR_MODE | wr_flags;
*(UInteger16 *)(buf + 76) = htons(wr_flags);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment