Commit bc586acd authored by Sven Meier's avatar Sven Meier

bmc & wr locking: added leap second propagation and added reset of locking

Leap seconds are now also fetched from the system in case we are a grandmaster
A reset of the locking procedure was added so a locked switch can get master again
parent 8633ced3
......@@ -32,6 +32,7 @@ static struct wr_operations wrpc_wr_operations = {
.locking_enable = wrpc_spll_locking_enable,
.locking_poll = wrpc_spll_locking_poll,
.locking_disable = wrpc_spll_locking_disable,
.locking_reset = wrpc_spll_locking_reset,
.enable_ptracker = wrpc_spll_enable_ptracker,
.adjust_in_progress = wrpc_adjust_in_progress,
......
......@@ -47,6 +47,13 @@ int wrpc_spll_locking_poll(struct pp_instance *ppi, int grandmaster)
return locked ? WR_SPLL_READY : WR_SPLL_ERROR;
}
int wrpc_spll_locking_reset(struct pp_instance *ppi)
{
//TODO?
return WR_SPLL_OK;
}
int wrpc_spll_locking_disable(struct pp_instance *ppi)
{
/* softpll_disable(); */
......
......@@ -46,6 +46,7 @@ struct wrpc_ethhdr {
int wrpc_spll_locking_enable(struct pp_instance *ppi);
int wrpc_spll_locking_poll(struct pp_instance *ppi, int grandmaster);
int wrpc_spll_locking_disable(struct pp_instance *ppi);
int wrpc_spll_locking_reset(struct pp_instance *ppi);
int wrpc_spll_enable_ptracker(struct pp_instance *ppi);
int wrpc_adjust_in_progress(void);
int wrpc_adjust_counters(int64_t adjust_sec, int32_t adjust_nsec);
......
......@@ -26,6 +26,7 @@
#define HEXP_LOCK_CMD_START 1
#define HEXP_LOCK_CMD_CHECK 2
#define HEXP_LOCK_CMD_ENABLE_TRACKING 3
#define HEXP_LOCK_CMD_RESET 4
#define HEXP_LOCK_STATUS_LOCKED 0
#define HEXP_LOCK_STATUS_BUSY 1
......
......@@ -76,6 +76,7 @@ int wrs_calibration_pattern_disable(struct pp_instance *ppi);
int wrs_locking_enable(struct pp_instance *ppi);
int wrs_locking_poll(struct pp_instance *ppi, int grandmaster);
int wrs_locking_disable(struct pp_instance *ppi);
int wrs_locking_reset(struct pp_instance *ppi);
int wrs_enable_ptracker(struct pp_instance *ppi);
int wrs_adjust_in_progress(void);
int wrs_adjust_counters(int64_t adjust_sec, int32_t adjust_nsec);
......
......@@ -36,6 +36,7 @@ static struct wr_operations wrs_wr_operations = {
.locking_enable = wrs_locking_enable,
.locking_poll = wrs_locking_poll,
.locking_disable = wrs_locking_disable,
.locking_reset = wrs_locking_reset,
.enable_ptracker = wrs_enable_ptracker,
.adjust_in_progress = wrs_adjust_in_progress,
......
......@@ -87,6 +87,10 @@ get_current_state_table_item(struct pp_instance *ppi)
*/
static int leave_current_state(struct pp_instance *ppi)
{
/* If something has to be done in an extension */
if (pp_hooks.state_change)
pp_hooks.state_change(ppi);
/* if the next or old state is non standard PTP reset all timeouts */
if ((ppi->state > PPS_SLAVE) || (ppi->next_state > PPS_SLAVE))
pp_timeout_setall(ppi);
......
......@@ -165,6 +165,7 @@ struct pp_ext_hooks {
int (*pack_announce)(struct pp_instance *ppi);
void (*unpack_announce)(void *buf, MsgAnnounce *ann);
int (*state_decision)(struct pp_instance *ppi, int next_state);
void (*state_change)(struct pp_instance *ppi);
};
extern struct pp_ext_hooks pp_hooks; /* The one for the extension we build */
......@@ -197,7 +198,7 @@ extern struct pp_network_operations unix_net_ops;
* If "set" receives a NULL time value, it should update the TAI offset.
*/
struct pp_time_operations {
int (*get_utc_offset)(struct pp_instance *ppi, int *offset);
int (*get_utc_offset)(struct pp_instance *ppi, int *offset, int *leap59, int *leap61);
int (*get)(struct pp_instance *ppi, struct pp_time *t);
int (*set)(struct pp_instance *ppi, const struct pp_time *t);
/* freq_ppb is parts per billion */
......
......@@ -277,10 +277,6 @@ static void wr_unpack_announce(void *buf, MsgAnnounce *ann)
/* State decision algorithm 9.3.3 Fig 26 with extension for wr */
static int wr_state_decision(struct pp_instance *ppi, int next_state)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct pp_globals *ppg = GLBS(ppi);
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
/*
......@@ -297,25 +293,42 @@ static int wr_state_decision(struct pp_instance *ppi, int next_state)
(ppi->state == WRS_WR_LINK_ON))
return ppi->state;
/* else do the normal statemachine */
return next_state;
}
static void wr_state_change(struct pp_instance *ppi)
{
struct pp_globals *ppg = GLBS(ppi);
struct wr_dsport *wrp = WR_DSPOR(ppi);
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
if ((ppi->next_state == WRS_PRESENT) ||
(ppi->next_state == WRS_M_LOCK) ||
(ppi->next_state == WRS_S_LOCK) ||
(ppi->next_state == WRS_LOCKED) ||
(ppi->next_state == WRS_CALIBRATION) ||
(ppi->next_state == WRS_CALIBRATED) ||
(ppi->next_state == WRS_RESP_CALIB_REQ) ||
(ppi->next_state == WRS_WR_LINK_ON))
return;
/* if we are leaving the WR locked states reset the WR process */
if ((next_state != ppi->state) &&
(WR_DSPOR(ppi)->wrModeOn == TRUE) &&
if ((ppi->next_state != ppi->state) &&
(wrp->wrModeOn == TRUE) &&
((ppi->state == PPS_SLAVE) ||
(ppi->state == PPS_MASTER))) {
wrp->wrStateTimeout = WR_DEFAULT_STATE_TIMEOUT_MS;
wrp->calPeriod = WR_DEFAULT_CAL_PERIOD;
wrp->wrModeOn = FALSE;
wrp->parentWrConfig = NON_WR;
wrp->parentWrModeOn = FALSE;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
/* if we are leaving the slave state reset the servo */
if ((ppi->state == PPS_SLAVE) &&
(ppg->ebest_idx == ppi->port_idx)) {
wr_servo_reset(ppi);
}
wrp->ops->locking_reset(ppi);
}
/* else do the normal statemachine */
return next_state;
}
struct pp_ext_hooks pp_hooks = {
......@@ -335,4 +348,5 @@ struct pp_ext_hooks pp_hooks = {
.pack_announce = wr_pack_announce,
.unpack_announce = wr_unpack_announce,
.state_decision = wr_state_decision,
.state_change = wr_state_change,
};
......@@ -11,7 +11,7 @@
/* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data
* structure */
#define WRS_PPSI_SHMEM_VERSION 25 /* linkUp added to pp_instance */
#define WRS_PPSI_SHMEM_VERSION 27 /* added locking_reset to wr_operations */
/* Don't include the Following when this file is included in assembler. */
#ifndef __ASSEMBLY__
......@@ -106,6 +106,7 @@ struct wr_operations {
int (*locking_enable)(struct pp_instance *ppi);
int (*locking_poll)(struct pp_instance *ppi, int grandmaster);
int (*locking_disable)(struct pp_instance *ppi);
int (*locking_reset)(struct pp_instance *ppi);
int (*enable_ptracker)(struct pp_instance *ppi);
int (*adjust_in_progress)(void);
......
......@@ -23,7 +23,7 @@ void bmc_m1(struct pp_instance *ppi)
struct DSDefault *defds = DSDEF(ppi);
struct DSTimeProperties *prop = DSPRO(ppi);
int ret = 0;
int offset;
int offset, leap59, leap61;
/* Current data set update */
DSCUR(ppi)->stepsRemoved = 0;
......@@ -41,9 +41,13 @@ void bmc_m1(struct pp_instance *ppi)
parent->grandmasterPriority1 = defds->priority1;
parent->grandmasterPriority2 = defds->priority2;
ret = ppi->t_ops->get_utc_offset(ppi, &offset);
if (ret)
ret = ppi->t_ops->get_utc_offset(ppi, &offset, &leap59, &leap61);
if (ret) {
offset = PP_DEFAULT_UTC_OFFSET;
pp_diag(ppi, bmc, 1,
"Could not get UTC offset from system, taking default: %i\n",
offset);
}
/* Time Properties data set */
if (prop->currentUtcOffset != offset) {
pp_diag(ppi, bmc, 1, "New UTC offset: %i\n",
......@@ -55,16 +59,18 @@ void bmc_m1(struct pp_instance *ppi)
{
prop->timeTraceable = FALSE;
prop->currentUtcOffsetValid = FALSE;
prop->leap59 = FALSE;
prop->leap61 = FALSE;
}
else
{
prop->timeTraceable = TRUE;
prop->currentUtcOffsetValid = TRUE;
prop->leap59 = (leap59 != 0);
prop->leap61 = (leap61 != 0);
}
/* these are the default according to 9.4 */
prop->leap59 = FALSE;
prop->leap61 = FALSE;
prop->frequencyTraceable = FALSE;
prop->ptpTimescale = TRUE;
prop->timeSource = INTERNAL_OSCILLATOR;
......@@ -77,7 +83,7 @@ void bmc_m2(struct pp_instance *ppi)
struct DSDefault *defds = DSDEF(ppi);
struct DSTimeProperties *prop = DSPRO(ppi);
int ret = 0;
int offset;
int offset, leap59, leap61;
/* Current data set update */
DSCUR(ppi)->stepsRemoved = 0;
......@@ -95,9 +101,13 @@ void bmc_m2(struct pp_instance *ppi)
parent->grandmasterPriority1 = defds->priority1;
parent->grandmasterPriority2 = defds->priority2;
ret = ppi->t_ops->get_utc_offset(ppi, &offset);
if (ret)
ret = ppi->t_ops->get_utc_offset(ppi, &offset, &leap59, &leap61);
if (ret) {
offset = PP_DEFAULT_UTC_OFFSET;
pp_diag(ppi, bmc, 1,
"Could not get UTC offset from system, taking default: %i\n",
offset);
}
/* Time Properties data set */
if (prop->currentUtcOffset != offset) {
pp_diag(ppi, bmc, 1, "New UTC offset: %i\n",
......@@ -109,16 +119,18 @@ void bmc_m2(struct pp_instance *ppi)
{
prop->timeTraceable = FALSE;
prop->currentUtcOffsetValid = FALSE;
prop->leap59 = FALSE;
prop->leap61 = FALSE;
}
else
{
prop->timeTraceable = TRUE;
prop->currentUtcOffsetValid = TRUE;
prop->leap59 = (leap59 != 0);
prop->leap61 = (leap61 != 0);
}
/* these are the default according to 9.4 */
prop->leap59 = FALSE;
prop->leap61 = FALSE;
prop->frequencyTraceable = FALSE;
prop->ptpTimescale = TRUE;
prop->timeSource = INTERNAL_OSCILLATOR;
......@@ -951,7 +963,7 @@ static void bmc_update_erbest(struct pp_globals *ppg)
frgn_master = ppi->frgn_master;
/* if link is down clear foreign master table */
if (!ppi->linkUP)
if ((!ppi->linkUP) && (ppi->frgn_rec_num > 0))
bmc_flush_frgn_master(ppi);
if (ppi->frgn_rec_num > 0) {
......
......@@ -8,14 +8,26 @@
#include <ppsi/ppsi.h>
#include "bare-linux.h"
static int bare_time_get_utc_offset(struct pp_instance *ppi, int *offset)
static int bare_time_get_utc_offset(struct pp_instance *ppi, int *offset, int *leap59, int *leap61)
{
int ret;
struct bare_timex t;
/*
* Get the UTC/TAI difference
*/
memset(&t, 0, sizeof(t));
if (adjtimex(&t) >= 0) {
ret = adjtimex(&t);
if (ret >= 0) {
if (ret == TIME_INS) {
*leap59 = 0;
*leap61 = 1;
} else if (ret == TIME_DEL) {
*leap59 = 1;
*leap61 = 0;
} else {
*leap59 = 0;
*leap61 = 0;
}
*offset = (int)t.tai;
return 0;
} else {
......
......@@ -46,9 +46,11 @@ int sim_fast_forward_ns(struct pp_globals *ppg, int64_t ff_ns)
return 0;
}
static int sim_time_get_utc_offset(struct pp_instance *ppi, int *offset)
static int sim_time_get_utc_offset(struct pp_instance *ppi, int *offset, int *leap59, int *leap61)
{
/* no UTC offset */
*leap59 = 0;
*leap61 = 0;
*offset = 0;
return -1;
}
......
......@@ -23,14 +23,26 @@ static void clock_fatal_error(char *context)
exit(1);
}
static int unix_time_get_utc_offset(struct pp_instance *ppi, int *offset)
static int unix_time_get_utc_offset(struct pp_instance *ppi, int *offset, int *leap59, int *leap61)
{
int ret;
struct timex t;
/*
* Get the UTC/TAI difference
*/
memset(&t, 0, sizeof(t));
if (adjtimex(&t) >= 0) {
ret = adjtimex(&t);
if (ret >= 0) {
if (ret == TIME_INS) {
*leap59 = 0;
*leap61 = 1;
} else if (ret == TIME_DEL) {
*leap59 = 1;
*leap61 = 0;
} else {
*leap59 = 0;
*leap61 = 0;
}
/*
* Our WRS kernel has tai support, but our compiler does not.
* We are 32-bit only, and we know for sure that tai is
......
......@@ -9,9 +9,11 @@
#include "pps_gen.h" /* in wrpc-sw */
#include "syscon.h" /* in wrpc-sw */
static int wrpc_time_get_utc_offset(struct pp_instance *ppi, int *offset)
static int wrpc_time_get_utc_offset(struct pp_instance *ppi, int *offset, int *leap59, int *leap61)
{
/* no UTC offset */
*leap59 = 0;
*leap61 = 0;
*offset = 0;
return -1;
}
......
......@@ -136,6 +136,21 @@ int wrs_locking_enable(struct pp_instance *ppi)
return WR_SPLL_OK;
}
int wrs_locking_reset(struct pp_instance *ppi)
{
int ret, rval;
pp_diag(ppi, time, 1, "Reset locking\n");
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_lock_cmd,
&rval, ppi->iface_name, HEXP_LOCK_CMD_RESET, 0);
if ((ret < 0) || (rval < 0))
return WR_SPLL_ERROR;
return WR_SPLL_OK;
}
int wrs_locking_poll(struct pp_instance *ppi, int grandmaster)
{
int ret, rval;
......@@ -187,14 +202,26 @@ static int wrdate_get(struct pp_time *t)
return 0;
}
static int wrs_time_get_utc_offset(struct pp_instance *ppi, int *offset)
static int wrs_time_get_utc_offset(struct pp_instance *ppi, int *offset, int *leap59, int *leap61)
{
int ret;
struct timex t;
/*
* Get the UTC/TAI difference
*/
memset(&t, 0, sizeof(t));
if (adjtimex(&t) >= 0) {
ret = adjtimex(&t);
if (ret >= 0) {
if (ret == TIME_INS) {
*leap59 = 0;
*leap61 = 1;
} else if (ret == TIME_DEL) {
*leap59 = 1;
*leap61 = 0;
} else {
*leap59 = 0;
*leap61 = 0;
}
/*
* Our WRS kernel has tai support, but our compiler does not.
* We are 32-bit only, and we know for sure that tai is
......
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