Commit 8633ced3 authored by Sven Meier's avatar Sven Meier

bmc & cleanup: fixes after the audit portings

The audit portings changed the timely behaviour of the ppsi which cause wrong behaviours,
the timeout scheme was changed to only reset timeouts where needed and in all non PTP
states. UTC offset is now fetched from the system where supported, link up/down is now
considered in the BMC, also some state changes where cleaned up to be out of the BMC, e.g.
state changes based on timeouts between PreMaster and Master or between Uncalibrated and Slave.
parent 6295769e
...@@ -51,6 +51,8 @@ void sim_main_loop(struct pp_globals *ppg) ...@@ -51,6 +51,8 @@ void sim_main_loop(struct pp_globals *ppg)
for (j = 0; j < ppg->nlinks; j++) { for (j = 0; j < ppg->nlinks; j++) {
ppi = INST(ppg, j); ppi = INST(ppg, j);
ppi->is_new_state = 1; ppi->is_new_state = 1;
/* just tell that the links are up */
ppi->linkUp = TRUE;
} }
delay_ns = run_all_state_machines(ppg) * 1000LL * 1000LL; delay_ns = run_all_state_machines(ppg) * 1000LL * 1000LL;
......
...@@ -48,6 +48,8 @@ void unix_main_loop(struct pp_globals *ppg) ...@@ -48,6 +48,8 @@ void unix_main_loop(struct pp_globals *ppg)
for (j = 0; j < ppg->nlinks; j++) { for (j = 0; j < ppg->nlinks; j++) {
ppi = INST(ppg, j); ppi = INST(ppg, j);
/* just tell that the links are up */
ppi->linkUp = TRUE;
/* /*
* The main loop here is based on select. While we are not * The main loop here is based on select. While we are not
......
...@@ -225,7 +225,8 @@ int wrc_ptp_start() ...@@ -225,7 +225,8 @@ int wrc_ptp_start()
delay_ms = pp_state_machine(ppi, NULL, 0); delay_ms = pp_state_machine(ppi, NULL, 0);
start_tics = timer_get_tics(); start_tics = timer_get_tics();
WR_DSPOR(ppi)->linkUP = FALSE; /* just tell that the link is up, if not it will anyhow not receive anything */
ppi->linkUP = TRUE;
wr_servo_reset(ppi); wr_servo_reset(ppi);
ptp_enabled = 1; ptp_enabled = 1;
...@@ -244,6 +245,8 @@ int wrc_ptp_stop() ...@@ -244,6 +245,8 @@ int wrc_ptp_stop()
memset(ppi->frgn_master, 0, sizeof(ppi->frgn_master)); memset(ppi->frgn_master, 0, sizeof(ppi->frgn_master));
ppi->frgn_rec_num = 0; /* no known master */ ppi->frgn_rec_num = 0; /* no known master */
/* just tell that the link is down now */
ppi->linkUP = FALSE;
ptp_enabled = 0; ptp_enabled = 0;
wr_servo_reset(ppi); wr_servo_reset(ppi);
pp_close_globals(&ppg_static); pp_close_globals(&ppg_static);
......
...@@ -29,7 +29,7 @@ static int run_all_state_machines(struct pp_globals *ppg) ...@@ -29,7 +29,7 @@ static int run_all_state_machines(struct pp_globals *ppg)
for (j = 0; j < ppg->nlinks; j++) { for (j = 0; j < ppg->nlinks; j++) {
struct pp_instance *ppi = INST(ppg, j); struct pp_instance *ppi = INST(ppg, j);
int old_lu = WR_DSPOR(ppi)->linkUP; int old_lu = ppi->linkUP;
struct hal_port_state *p; struct hal_port_state *p;
/* FIXME: we should save this pointer in the ppi itself */ /* FIXME: we should save this pointer in the ppi itself */
...@@ -40,16 +40,16 @@ static int run_all_state_machines(struct pp_globals *ppg) ...@@ -40,16 +40,16 @@ static int run_all_state_machines(struct pp_globals *ppg)
continue; continue;
} }
WR_DSPOR(ppi)->linkUP = ppi->linkUP =
(p->state != HAL_PORT_STATE_LINK_DOWN && (p->state != HAL_PORT_STATE_LINK_DOWN &&
p->state != HAL_PORT_STATE_DISABLED); p->state != HAL_PORT_STATE_DISABLED);
if (old_lu != WR_DSPOR(ppi)->linkUP) { if (old_lu != ppi->linkUP) {
pp_diag(ppi, fsm, 1, "iface %s went %s\n", pp_diag(ppi, fsm, 1, "iface %s went %s\n",
ppi->iface_name, WR_DSPOR(ppi)->linkUP ? "up":"down"); ppi->iface_name, ppi->linkUP ? "up":"down");
if (WR_DSPOR(ppi)->linkUP) { if (ppi->linkUP) {
ppi->state = PPS_INITIALIZING; ppi->state = PPS_INITIALIZING;
} }
else { else {
...@@ -62,7 +62,7 @@ static int run_all_state_machines(struct pp_globals *ppg) ...@@ -62,7 +62,7 @@ static int run_all_state_machines(struct pp_globals *ppg)
} }
/* Do not call state machine if link is down */ /* Do not call state machine if link is down */
if (WR_DSPOR(ppi)->linkUP) if (ppi->linkUP)
delay_ms_j = pp_state_machine(ppi, NULL, 0); delay_ms_j = pp_state_machine(ppi, NULL, 0);
else else
delay_ms_j = PP_DEFAULT_NEXT_DELAY_MS; delay_ms_j = PP_DEFAULT_NEXT_DELAY_MS;
......
...@@ -87,8 +87,11 @@ get_current_state_table_item(struct pp_instance *ppi) ...@@ -87,8 +87,11 @@ get_current_state_table_item(struct pp_instance *ppi)
*/ */
static int leave_current_state(struct pp_instance *ppi) static int leave_current_state(struct pp_instance *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);
ppi->state = ppi->next_state; ppi->state = ppi->next_state;
pp_timeout_setall(ppi);
ppi->flags &= ~PPI_FLAGS_WAITING; ppi->flags &= ~PPI_FLAGS_WAITING;
pp_diag_fsm(ppi, ppi->current_state_item->name, STATE_LEAVE, 0); pp_diag_fsm(ppi, ppi->current_state_item->name, STATE_LEAVE, 0);
/* next_delay unused: go to new state now */ /* next_delay unused: go to new state now */
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define PP_DEFAULT_SYNC_INTERVAL 0 /* -7 in 802.1AS */ #define PP_DEFAULT_SYNC_INTERVAL 0 /* -7 in 802.1AS */
#define PP_DEFAULT_SYNC_RECEIPT_TIMEOUT 3 #define PP_DEFAULT_SYNC_RECEIPT_TIMEOUT 3
#define PP_DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT 3 /* 3 by default */ #define PP_DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT 3 /* 3 by default */
#define PP_DEFAULT_UTC_OFFSET 37
/* Clock classes (pag 55, PTP-2008). See ppsi-manual for an explanation */ /* Clock classes (pag 55, PTP-2008). See ppsi-manual for an explanation */
#define PP_CLASS_SLAVE_ONLY 255 #define PP_CLASS_SLAVE_ONLY 255
......
...@@ -180,6 +180,7 @@ struct pp_instance { ...@@ -180,6 +180,7 @@ struct pp_instance {
UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]; /* last sent this type */ UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]; /* last sent this type */
MsgHeader received_ptp_header; MsgHeader received_ptp_header;
Boolean linkUP;
char *iface_name; /* for direct actions on hardware */ char *iface_name; /* for direct actions on hardware */
char *port_name; /* for diagnostics, mainly */ char *port_name; /* for diagnostics, mainly */
int port_idx; int port_idx;
......
...@@ -197,6 +197,7 @@ extern struct pp_network_operations unix_net_ops; ...@@ -197,6 +197,7 @@ extern struct pp_network_operations unix_net_ops;
* If "set" receives a NULL time value, it should update the TAI offset. * If "set" receives a NULL time value, it should update the TAI offset.
*/ */
struct pp_time_operations { struct pp_time_operations {
int (*get_utc_offset)(struct pp_instance *ppi, int *offset);
int (*get)(struct pp_instance *ppi, struct pp_time *t); int (*get)(struct pp_instance *ppi, struct pp_time *t);
int (*set)(struct pp_instance *ppi, const struct pp_time *t); int (*set)(struct pp_instance *ppi, const struct pp_time *t);
/* freq_ppb is parts per billion */ /* freq_ppb is parts per billion */
......
...@@ -24,6 +24,8 @@ void bare_main_loop(struct pp_instance *ppi) ...@@ -24,6 +24,8 @@ void bare_main_loop(struct pp_instance *ppi)
{ {
int delay_ms; int delay_ms;
/* just tell that the links are up */
ppi->linkUp = TRUE;
/* /*
* The main loop here is based on select. While we are not * The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff * doing anything else but the protocol, this allows extra stuff
......
...@@ -307,9 +307,11 @@ static int wr_state_decision(struct pp_instance *ppi, int next_state) ...@@ -307,9 +307,11 @@ static int wr_state_decision(struct pp_instance *ppi, int next_state)
wrp->parentWrModeOn = FALSE; wrp->parentWrModeOn = FALSE;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED; wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
/* if we are leaving the slave state reset the servo */
if ((ppi->state == PPS_SLAVE) && if ((ppi->state == PPS_SLAVE) &&
(ppg->ebest_idx == ppi->port_idx)) (ppg->ebest_idx == ppi->port_idx)) {
wr_servo_reset(ppi); wr_servo_reset(ppi);
}
} }
/* else do the normal statemachine */ /* else do the normal statemachine */
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
/* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data /* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data
* structure */ * structure */
#define WRS_PPSI_SHMEM_VERSION 23 /* Changed struct pp_frgn_master */ #define WRS_PPSI_SHMEM_VERSION 25 /* linkUp added to pp_instance */
/* Don't include the Following when this file is included in assembler. */ /* Don't include the Following when this file is included in assembler. */
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -51,7 +51,6 @@ struct wr_dsport { ...@@ -51,7 +51,6 @@ struct wr_dsport {
FixedDelta otherNodeDeltaTx; FixedDelta otherNodeDeltaTx;
FixedDelta otherNodeDeltaRx; FixedDelta otherNodeDeltaRx;
Boolean doRestart; Boolean doRestart;
Boolean linkUP;
}; };
/* This uppercase name matches "DSPOR(ppi)" used by standard protocol */ /* This uppercase name matches "DSPOR(ppi)" used by standard protocol */
......
...@@ -22,6 +22,8 @@ void bmc_m1(struct pp_instance *ppi) ...@@ -22,6 +22,8 @@ void bmc_m1(struct pp_instance *ppi)
struct DSParent *parent = DSPAR(ppi); struct DSParent *parent = DSPAR(ppi);
struct DSDefault *defds = DSDEF(ppi); struct DSDefault *defds = DSDEF(ppi);
struct DSTimeProperties *prop = DSPRO(ppi); struct DSTimeProperties *prop = DSPRO(ppi);
int ret = 0;
int offset;
/* Current data set update */ /* Current data set update */
DSCUR(ppi)->stepsRemoved = 0; DSCUR(ppi)->stepsRemoved = 0;
...@@ -38,16 +40,31 @@ void bmc_m1(struct pp_instance *ppi) ...@@ -38,16 +40,31 @@ void bmc_m1(struct pp_instance *ppi)
parent->grandmasterClockQuality = defds->clockQuality; parent->grandmasterClockQuality = defds->clockQuality;
parent->grandmasterPriority1 = defds->priority1; parent->grandmasterPriority1 = defds->priority1;
parent->grandmasterPriority2 = defds->priority2; parent->grandmasterPriority2 = defds->priority2;
ret = ppi->t_ops->get_utc_offset(ppi, &offset);
if (ret)
offset = PP_DEFAULT_UTC_OFFSET;
/* Time Properties data set */ /* Time Properties data set */
/* TODO get the time properties from somewhere, if (prop->currentUtcOffset != offset) {
* these are the default according to 9.4 pp_diag(ppi, bmc, 1, "New UTC offset: %i\n",
*/ offset);
prop->currentUtcOffset = 37; prop->currentUtcOffset = offset;
prop->currentUtcOffsetValid = FALSE; ppi->t_ops->set(ppi, NULL);
}
if (ret)
{
prop->timeTraceable = FALSE;
prop->currentUtcOffsetValid = FALSE;
}
else
{
prop->timeTraceable = TRUE;
prop->currentUtcOffsetValid = TRUE;
}
/* these are the default according to 9.4 */
prop->leap59 = FALSE; prop->leap59 = FALSE;
prop->leap61 = FALSE; prop->leap61 = FALSE;
prop->timeTraceable = FALSE;
prop->frequencyTraceable = FALSE; prop->frequencyTraceable = FALSE;
prop->ptpTimescale = TRUE; prop->ptpTimescale = TRUE;
prop->timeSource = INTERNAL_OSCILLATOR; prop->timeSource = INTERNAL_OSCILLATOR;
...@@ -59,6 +76,8 @@ void bmc_m2(struct pp_instance *ppi) ...@@ -59,6 +76,8 @@ void bmc_m2(struct pp_instance *ppi)
struct DSParent *parent = DSPAR(ppi); struct DSParent *parent = DSPAR(ppi);
struct DSDefault *defds = DSDEF(ppi); struct DSDefault *defds = DSDEF(ppi);
struct DSTimeProperties *prop = DSPRO(ppi); struct DSTimeProperties *prop = DSPRO(ppi);
int ret = 0;
int offset;
/* Current data set update */ /* Current data set update */
DSCUR(ppi)->stepsRemoved = 0; DSCUR(ppi)->stepsRemoved = 0;
...@@ -75,16 +94,31 @@ void bmc_m2(struct pp_instance *ppi) ...@@ -75,16 +94,31 @@ void bmc_m2(struct pp_instance *ppi)
parent->grandmasterClockQuality = defds->clockQuality; parent->grandmasterClockQuality = defds->clockQuality;
parent->grandmasterPriority1 = defds->priority1; parent->grandmasterPriority1 = defds->priority1;
parent->grandmasterPriority2 = defds->priority2; parent->grandmasterPriority2 = defds->priority2;
ret = ppi->t_ops->get_utc_offset(ppi, &offset);
if (ret)
offset = PP_DEFAULT_UTC_OFFSET;
/* Time Properties data set */ /* Time Properties data set */
/* TODO get the time properties from somewhere, if (prop->currentUtcOffset != offset) {
* these are the default according to 9.4 pp_diag(ppi, bmc, 1, "New UTC offset: %i\n",
*/ offset);
prop->currentUtcOffset = 37; prop->currentUtcOffset = offset;
prop->currentUtcOffsetValid = FALSE; ppi->t_ops->set(ppi, NULL);
}
if (ret)
{
prop->timeTraceable = FALSE;
prop->currentUtcOffsetValid = FALSE;
}
else
{
prop->timeTraceable = TRUE;
prop->currentUtcOffsetValid = TRUE;
}
/* these are the default according to 9.4 */
prop->leap59 = FALSE; prop->leap59 = FALSE;
prop->leap61 = FALSE; prop->leap61 = FALSE;
prop->timeTraceable = FALSE;
prop->frequencyTraceable = FALSE; prop->frequencyTraceable = FALSE;
prop->ptpTimescale = TRUE; prop->ptpTimescale = TRUE;
prop->timeSource = INTERNAL_OSCILLATOR; prop->timeSource = INTERNAL_OSCILLATOR;
...@@ -559,15 +593,16 @@ master_m1: ...@@ -559,15 +593,16 @@ master_m1:
return PPS_LISTENING; return PPS_LISTENING;
} }
bmc_m1(ppi); bmc_m1(ppi);
if (ppi->state != PPS_MASTER) { if ((ppi->state != PPS_MASTER) &&
/* if not already in pre master state start qualification */ (ppi->state != PPS_PRE_MASTER)) {
if (ppi->state != PPS_PRE_MASTER) { /* 9.2.6.10 a) timeout 0 */
/* 9.2.6.10 a) timeout 0 */ pp_timeout_clear(ppi, PP_TO_QUALIFICATION);
pp_timeout_clear(ppi, PP_TO_QUALIFICATION);
}
return PPS_PRE_MASTER; return PPS_PRE_MASTER;
} else } else {
return PPS_MASTER; /* the decision to go from PPS_PRE_MASTER to PPS_MASTER is
* done outside the BMC, so just return the current state */
return ppi->state;
}
master_m2: master_m2:
pp_diag(ppi, bmc, 1, "%s: master m2\n", __func__); pp_diag(ppi, bmc, 1, "%s: master m2\n", __func__);
...@@ -578,15 +613,16 @@ master_m2: ...@@ -578,15 +613,16 @@ master_m2:
return PPS_LISTENING; return PPS_LISTENING;
} }
bmc_m2(ppi); bmc_m2(ppi);
if (ppi->state != PPS_MASTER) { if ((ppi->state != PPS_MASTER) &&
/* if not already in pre master state start qualification */ (ppi->state != PPS_PRE_MASTER)) {
if (ppi->state != PPS_PRE_MASTER) { /* 9.2.6.10 a) timeout 0 */
/* 9.2.6.10 a) timeout 0 */ pp_timeout_clear(ppi, PP_TO_QUALIFICATION);
pp_timeout_clear(ppi, PP_TO_QUALIFICATION);
}
return PPS_PRE_MASTER; return PPS_PRE_MASTER;
} else } else {
return PPS_MASTER; /* the decision to go from PPS_PRE_MASTER to PPS_MASTER is
* done outside the BMC, so just return the current state */
return ppi->state;
}
master_m3: master_m3:
pp_diag(ppi, bmc, 1, "%s: master m3\n", __func__); pp_diag(ppi, bmc, 1, "%s: master m3\n", __func__);
...@@ -597,17 +633,18 @@ master_m3: ...@@ -597,17 +633,18 @@ master_m3:
return PPS_LISTENING; return PPS_LISTENING;
} }
bmc_m3(ppi); bmc_m3(ppi);
if (ppi->state != PPS_MASTER) { if ((ppi->state != PPS_MASTER) &&
/* if not already in pre master state start qualification */ (ppi->state != PPS_PRE_MASTER)) {
if (ppi->state != PPS_PRE_MASTER) { /* timeout reinit */
/* timeout reinit */ pp_timeout_init(ppi);
pp_timeout_init(ppi); /* 9.2.6.11 b) timeout steps removed+1*/
/* 9.2.6.11 b) timeout steps removed+1*/ pp_timeout_set(ppi, PP_TO_QUALIFICATION);
pp_timeout_set(ppi, PP_TO_QUALIFICATION);
}
return PPS_PRE_MASTER; return PPS_PRE_MASTER;
} else } else {
return PPS_MASTER; /* the decision to go from PPS_PRE_MASTER to PPS_MASTER is
* done outside the BMC, so just return the current state */
return ppi->state;
}
slave_s1: slave_s1:
pp_diag(ppi, bmc, 1, "%s: slave s1\n", __func__); pp_diag(ppi, bmc, 1, "%s: slave s1\n", __func__);
...@@ -642,7 +679,9 @@ slave_s1: ...@@ -642,7 +679,9 @@ slave_s1:
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/ /* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_SLAVE) if (ppi->state != PPS_SLAVE)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT); pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_SLAVE; /* the decision to go from UNCALIBRATED to SLAVEW is
* done outside the BMC, so just return the current state */
return ppi->state;
} }
} }
} }
...@@ -811,6 +850,14 @@ void bmc_add_frgn_master(struct pp_instance *ppi, void *buf, ...@@ -811,6 +850,14 @@ void bmc_add_frgn_master(struct pp_instance *ppi, void *buf,
pp_diag(ppi, bmc, 1, "New foreign Master %i added\n", sel); pp_diag(ppi, bmc, 1, "New foreign Master %i added\n", sel);
} }
static void bmc_flush_frgn_master(struct pp_instance *ppi)
{
pp_diag(ppi, bmc, 2, "%s\n", __func__);
memset(ppi->frgn_master, 0, sizeof(ppi->frgn_master));
ppi->frgn_rec_num = 0;
}
static void bmc_age_frgn_master(struct pp_instance *ppi) static void bmc_age_frgn_master(struct pp_instance *ppi)
{ {
int i, j; int i, j;
...@@ -877,8 +924,7 @@ static int bmc_any_port_initializing(struct pp_globals *ppg) ...@@ -877,8 +924,7 @@ static int bmc_any_port_initializing(struct pp_globals *ppg)
ppi = INST(ppg, i); ppi = INST(ppg, i);
if ((WR_DSPOR(ppi)->linkUP) if (ppi->linkUP && (ppi->state == PPS_INITIALIZING)) {
&& (ppi->state == PPS_INITIALIZING)) {
pp_diag(ppi, bmc, 2, "The first port in INITIALIZING " pp_diag(ppi, bmc, 2, "The first port in INITIALIZING "
"state is %i\n", i); "state is %i\n", i);
return 1; return 1;
...@@ -904,6 +950,10 @@ static void bmc_update_erbest(struct pp_globals *ppg) ...@@ -904,6 +950,10 @@ static void bmc_update_erbest(struct pp_globals *ppg)
ppi = INST(ppg, i); ppi = INST(ppg, i);
frgn_master = ppi->frgn_master; frgn_master = ppi->frgn_master;
/* if link is down clear foreign master table */
if (!ppi->linkUP)
bmc_flush_frgn_master(ppi);
if (ppi->frgn_rec_num > 0) { if (ppi->frgn_rec_num > 0) {
/* Only if port is not in the FAULTY or DISABLED /* Only if port is not in the FAULTY or DISABLED
* state 9.2.6.8 */ * state 9.2.6.8 */
...@@ -1020,8 +1070,13 @@ int bmc(struct pp_instance *ppi) ...@@ -1020,8 +1070,13 @@ int bmc(struct pp_instance *ppi)
/* Calulate Ebest Figure 25 */ /* Calulate Ebest Figure 25 */
bmc_update_ebest(ppg); bmc_update_ebest(ppg);
/* Make state decision */ if (ppi->linkUP) {
next_state = bmc_state_decision(ppi); /* Make state decision */
next_state = bmc_state_decision(ppi);
} else {
/* Set it back to initializing */
next_state = PPS_INITIALIZING;
}
/* Extra states handled here */ /* Extra states handled here */
if (pp_hooks.state_decision) if (pp_hooks.state_decision)
......
...@@ -91,6 +91,7 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len) ...@@ -91,6 +91,7 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
port->logSyncInterval = opt->sync_intvl; port->logSyncInterval = opt->sync_intvl;
port->versionNumber = PP_VERSION_PTP; port->versionNumber = PP_VERSION_PTP;
pp_timeout_init(ppi); pp_timeout_init(ppi);
pp_timeout_setall(ppi);
if (pp_hooks.init) if (pp_hooks.init)
ret = pp_hooks.init(ppi, buf, len); ret = pp_hooks.init(ppi, buf, len);
...@@ -105,7 +106,7 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len) ...@@ -105,7 +106,7 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
DSDEF(ppi)->clockQuality.clockAccuracy); DSDEF(ppi)->clockQuality.clockAccuracy);
msg_init_header(ppi, ppi->tx_ptp); /* This is used for all tx */ msg_init_header(ppi, ppi->tx_ptp); /* This is used for all tx */
if (ppi->role != PPSI_ROLE_MASTER) if (ppi->role != PPSI_ROLE_MASTER)
ppi->next_state = PPS_LISTENING; ppi->next_state = PPS_LISTENING;
else else
......
...@@ -8,6 +8,22 @@ ...@@ -8,6 +8,22 @@
#include <ppsi/ppsi.h> #include <ppsi/ppsi.h>
#include "bare-linux.h" #include "bare-linux.h"
static int bare_time_get_utc_offset(struct pp_instance *ppi, int *offset)
{
struct bare_timex t;
/*
* Get the UTC/TAI difference
*/
memset(&t, 0, sizeof(t));
if (adjtimex(&t) >= 0) {
*offset = (int)t.tai;
return 0;
} else {
*offset = 0;
return -1;
}
}
static int bare_time_get(struct pp_instance *ppi, struct pp_time *t) static int bare_time_get(struct pp_instance *ppi, struct pp_time *t)
{ {
struct bare_timeval tv; struct bare_timeval tv;
...@@ -100,6 +116,7 @@ static unsigned long bare_calc_timeout(struct pp_instance *ppi, int millisec) ...@@ -100,6 +116,7 @@ static unsigned long bare_calc_timeout(struct pp_instance *ppi, int millisec)
} }
struct pp_time_operations bare_time_ops = { struct pp_time_operations bare_time_ops = {
.get_utc_offset = bare_time_get_utc_offset,
.get = bare_time_get, .get = bare_time_get,
.set = bare_time_set, .set = bare_time_set,
.adjust = bare_time_adjust, .adjust = bare_time_adjust,
......
...@@ -46,6 +46,13 @@ int sim_fast_forward_ns(struct pp_globals *ppg, int64_t ff_ns) ...@@ -46,6 +46,13 @@ int sim_fast_forward_ns(struct pp_globals *ppg, int64_t ff_ns)
return 0; return 0;
} }
static int sim_time_get_utc_offset(struct pp_instance *ppi, int *offset)
{
/* no UTC offset */
*offset = 0;
return -1;
}
static int sim_time_get(struct pp_instance *ppi, struct pp_time *t) static int sim_time_get(struct pp_instance *ppi, struct pp_time *t)
{ {
t->scaled_nsecs = (SIM_PPI_ARCH(ppi)->time.current_ns % t->scaled_nsecs = (SIM_PPI_ARCH(ppi)->time.current_ns %
...@@ -113,6 +120,7 @@ static unsigned long sim_calc_timeout(struct pp_instance *ppi, int millisec) ...@@ -113,6 +120,7 @@ static unsigned long sim_calc_timeout(struct pp_instance *ppi, int millisec)
} }
struct pp_time_operations sim_time_ops = { struct pp_time_operations sim_time_ops = {
.get_utc_offset = sim_time_get_utc_offset,
.get = sim_time_get, .get = sim_time_get,
.set = sim_time_set, .set = sim_time_set,
.adjust = sim_time_adjust, .adjust = sim_time_adjust,
......
...@@ -23,6 +23,27 @@ static void clock_fatal_error(char *context) ...@@ -23,6 +23,27 @@ static void clock_fatal_error(char *context)
exit(1); exit(1);
} }
static int unix_time_get_utc_offset(struct pp_instance *ppi, int *offset)
{
struct timex t;
/*
* Get the UTC/TAI difference
*/
memset(&t, 0, sizeof(t));
if (adjtimex(&t) >= 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
* exactly after stbcnt. It's a bad hack, but it works
*/
*offset = *((int *)(&t.stbcnt) + 1);
return 0;
} else {
*offset = 0;
return -1;
}
}
static int unix_time_get(struct pp_instance *ppi, struct pp_time *t) static int unix_time_get(struct pp_instance *ppi, struct pp_time *t)
{ {
struct timespec tp; struct timespec tp;
...@@ -124,6 +145,7 @@ static unsigned long unix_calc_timeout(struct pp_instance *ppi, int millisec) ...@@ -124,6 +145,7 @@ static unsigned long unix_calc_timeout(struct pp_instance *ppi, int millisec)
} }
struct pp_time_operations unix_time_ops = { struct pp_time_operations unix_time_ops = {
.get_utc_offset = unix_time_get_utc_offset,
.get = unix_time_get, .get = unix_time_get,
.set = unix_time_set, .set = unix_time_set,
.adjust = unix_time_adjust, .adjust = unix_time_adjust,
......
...@@ -9,6 +9,13 @@ ...@@ -9,6 +9,13 @@
#include "pps_gen.h" /* in wrpc-sw */ #include "pps_gen.h" /* in wrpc-sw */
#include "syscon.h" /* in wrpc-sw */ #include "syscon.h" /* in wrpc-sw */
static int wrpc_time_get_utc_offset(struct pp_instance *ppi, int *offset)
{
/* no UTC offset */
*offset = 0;
return -1;
}
static int wrpc_time_get(struct pp_instance *ppi, struct pp_time *t) static int wrpc_time_get(struct pp_instance *ppi, struct pp_time *t)
{ {
uint64_t sec; uint64_t sec;
...@@ -65,6 +72,7 @@ static unsigned long wrpc_calc_timeout(struct pp_instance *ppi, int millisec) ...@@ -65,6 +72,7 @@ static unsigned long wrpc_calc_timeout(struct pp_instance *ppi, int millisec)
} }
struct pp_time_operations wrpc_time_ops = { struct pp_time_operations wrpc_time_ops = {
.get_utc_offset = wrpc_time_get_utc_offset,
.get = wrpc_time_get, .get = wrpc_time_get,
.set = wrpc_time_set, .set = wrpc_time_set,
.adjust = wrpc_time_adjust, .adjust = wrpc_time_adjust,
......
...@@ -187,6 +187,27 @@ static int wrdate_get(struct pp_time *t) ...@@ -187,6 +187,27 @@ static int wrdate_get(struct pp_time *t)
return 0; return 0;
} }
static int wrs_time_get_utc_offset(struct pp_instance *ppi, int *offset)
{
struct timex t;
/*
* Get the UTC/TAI difference
*/
memset(&t, 0, sizeof(t));
if (adjtimex(&t) >= 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
* exactly after stbcnt. It's a bad hack, but it works
*/
*offset = *((int *)(&t.stbcnt) + 1);
return 0;
} else {
*offset = 0;
return -1;
}
}
/* This is only used when the wrs is slave to a non-WR master */ /* This is only used when the wrs is slave to a non-WR master */
static int wrs_time_get(struct pp_instance *ppi, struct pp_time *t) static int wrs_time_get(struct pp_instance *ppi, struct pp_time *t)
{ {
...@@ -371,6 +392,7 @@ static unsigned long wrs_calc_timeout(struct pp_instance *ppi, ...@@ -371,6 +392,7 @@ static unsigned long wrs_calc_timeout(struct pp_instance *ppi,
} }
struct pp_time_operations wrs_time_ops = { struct pp_time_operations wrs_time_ops = {
.get_utc_offset = wrs_time_get_utc_offset,
.get = wrs_time_get, .get = wrs_time_get,
.set = wrs_time_set, .set = wrs_time_set,
.adjust = wrs_time_adjust, .adjust = wrs_time_adjust,
......
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