Commit f290c38b authored by Jean-Claude BAU's avatar Jean-Claude BAU Committed by Adam Wujek

Infrastructure changes: make wr_operations common for WRS and WRPC and

independant of a pp_instance. Also add wrh_servo_head for wr_mon.
parent be382fde
......@@ -26,7 +26,7 @@ extern int32_t cal_phase_transition;
int ptp_mode = WRC_MODE_UNKNOWN;
static int ptp_enabled = 0;
static struct wr_operations wrpc_wr_operations = {
struct wrh_operations wrh_oper = {
.locking_enable = wrpc_spll_locking_enable,
.locking_poll = wrpc_spll_locking_poll,
.locking_disable = wrpc_spll_locking_disable,
......@@ -62,9 +62,7 @@ static struct pp_servo servo;
static struct wr_data wr_ext_data; /* WR extension data */
static struct wr_dsport wr_dsport = {
.ops = &wrpc_wr_operations,
};
static struct wr_dsport wr_dsport;
#endif
static DSPort portDS ;
......@@ -118,6 +116,7 @@ int wrc_ptp_init()
ppi->ext_hooks = &wr_ext_hooks;
ppi->ext_data = &wr_ext_data;
wr_ext_data->servo_state.servo_head.extension=PPSI_EXT_WR;
GBLS(ppi)->global_ext_data=&wr_ext_data.servo_state; /* Updated for the WR monitor tools */
portDS.ext_dsport = &wr_dsport;
......
......@@ -39,7 +39,7 @@
#define WRSW_HAL_TIMEOUT 2000000 /* us */
static struct wr_operations wrs_wr_operations = {
struct wrh_operations wrh_oper = {
.locking_enable = wrs_locking_enable,
.locking_poll = wrs_locking_poll,
.locking_disable = wrs_locking_disable,
......@@ -239,23 +239,22 @@ int main(int argc, char **argv)
ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */
if (ppi->portDS) {
if ( CONFIG_EXT_WR == 1 && ppi->cfg.ext==PPSI_PROFILE_WR ) {
struct wr_dsport *wrp;
struct wr_data *wdata;
/* Add WR extension portDS */
if ( !(ppi->portDS->ext_dsport =
alloc_fn(ppsi_head, sizeof(struct wr_dsport))) ) {
goto exit_out_of_memory;
}
wrp = WR_DSPOR(ppi); /* just allocated above */
wrp->ops = &wrs_wr_operations;
/* Allocate WR data extension */
if (! (ppi->ext_data = alloc_fn(ppsi_head, sizeof(struct wr_data))) ) {
if (! (wdata=ppi->ext_data = alloc_fn(ppsi_head,sizeof(struct wr_data))) ) {
goto exit_out_of_memory;
}
wdata->servo_state.servo_head.extension=PPSI_EXT_WR;
/* Set WR extension hooks */
ppi->ext_hooks=&wr_ext_hooks;
ppg->global_ext_data=ppi->ext_data;
ppg->global_ext_data=wdata;
}
} else {
goto exit_out_of_memory;
......
/*
* Copyright (C) 2011 CERN (www.cern.ch)
* Author: Jean-Claude BAU
* Declarations common to WR switches and nodes.
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*/
#ifndef __WRH_H__
#define __WRH_H__
#include <stdint.h>
#include <ppsi/lib.h>
enum {
WRH_SERVO_ENTER, WRH_SERVO_LEAVE
};
struct wrh_servo_head {
int extension; /* Used to identify the servo extension. Useful for the monitoring tool */
};
/* White Rabbit hw-dependent functions (code in arch-wrpc and arch-wrs) */
struct wrh_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);
int (*adjust_counters)(int64_t adjust_sec, int32_t adjust_nsec);
int (*adjust_phase)(int32_t phase_ps);
int (*read_calib_data)(struct pp_instance *ppi,
uint32_t *deltaTx, uint32_t *deltaRx,
int32_t *fix_alpha, int32_t *clock_period);
int (*calib_disable)(struct pp_instance *ppi, int txrx);
int (*calib_enable)(struct pp_instance *ppi, int txrx);
int (*calib_poll)(struct pp_instance *ppi, int txrx, uint32_t *delta);
int (*calib_pattern_enable)(struct pp_instance *ppi,
unsigned int calibrationPeriod,
unsigned int calibrationPattern,
unsigned int calibrationPatternLen);
int (*calib_pattern_disable)(struct pp_instance *ppi);
int (*enable_timing_output)(struct pp_instance *ppi, int enable);
int (*servo_hook)(struct wrh_servo_head *s, int action);
int (*read_corr_data)(struct pp_instance *ppi, int64_t *delayCoeff,
int64_t *ingressLatency, int64_t *egressLatency,
int64_t *msgTPointLatency, int64_t *delayAsymmetry,
int64_t *fixAlpha, int32_t *clock_period );
};
extern struct wrh_operations wrh_oper;
static inline struct wrh_operations *WRH_OPER(void)
{
return &wrh_oper;
}
#endif /* __WRH_H__ */
......@@ -27,9 +27,9 @@ static int wr_init(struct pp_instance *ppi, void *buf, int len)
&& ptp_mode != 4 /* WRC_MODE_ABSCAL -- not defined in wrs build */
#endif
)
wrp->ops->enable_timing_output(ppi, 1);
WRH_OPER()->enable_timing_output(ppi, 1);
else
wrp->ops->enable_timing_output(ppi, 0);
WRH_OPER()->enable_timing_output(ppi, 0);
return 0;
}
......@@ -136,9 +136,9 @@ static int wr_handle_resp(struct pp_instance *ppi)
* pps always on if offset less than 1 second,
* until ve have a configurable threshold */
if (ofm->secs)
wrp->ops->enable_timing_output(ppi, 0);
WRH_OPER()->enable_timing_output(ppi, 0);
else
wrp->ops->enable_timing_output(ppi, 1);
WRH_OPER()->enable_timing_output(ppi, 1);
}
wr_servo_got_delay(ppi);
......@@ -241,9 +241,9 @@ static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi)
* pps always on if offset less than 1 second,
* until ve have a configurable threshold */
if (ofm->secs)
wrp->ops->enable_timing_output(ppi, 0);
WRH_OPER()->enable_timing_output(ppi, 0);
else
wrp->ops->enable_timing_output(ppi, 1);
WRH_OPER()->enable_timing_output(ppi, 1);
return 0;
}
......@@ -332,7 +332,7 @@ static void wr_state_change(struct pp_instance *ppi)
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
if (ppi->state == PPS_SLAVE)
wrp->ops->locking_reset(ppi);
WRH_OPER()->locking_reset(ppi);
}
}
......
......@@ -43,7 +43,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
switch (wrp->wrPortState) {
case WR_PORT_CALIBRATION_0:
/* enable pattern sending */
if (wrp->ops->calib_pattern_enable(ppi, 0, 0, 0) ==
if (WRH_OPER()->calib_pattern_enable(ppi, 0, 0, 0) ==
WR_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_1;
else
......@@ -51,7 +51,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_1:
/* enable Tx calibration */
if (wrp->ops->calib_enable(ppi, WR_HW_CALIB_TX)
if (WRH_OPER()->calib_enable(ppi, WR_HW_CALIB_TX)
== WR_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_2;
else
......@@ -59,7 +59,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_2:
/* wait until Tx calibration is finished */
if (wrp->ops->calib_poll(ppi, WR_HW_CALIB_TX, &delta) ==
if (WRH_OPER()->calib_poll(ppi, WR_HW_CALIB_TX, &delta) ==
WR_HW_CALIB_READY) {
wrp->deltaTx.scaledPicoseconds.msb =
0xFFFFFFFF & (((uint64_t)delta) >> 16);
......@@ -77,7 +77,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_3:
/* disable Tx calibration */
if (wrp->ops->calib_disable(ppi, WR_HW_CALIB_TX)
if (WRH_OPER()->calib_disable(ppi, WR_HW_CALIB_TX)
== WR_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_4;
else
......@@ -85,14 +85,14 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_4:
/* disable pattern sending */
if (wrp->ops->calib_pattern_disable(ppi) == WR_HW_CALIB_OK)
if (WRH_OPER()->calib_pattern_disable(ppi) == WR_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_5;
else
break;
case WR_PORT_CALIBRATION_5:
/* enable Rx calibration using the pattern sent by other port */
if (wrp->ops->calib_enable(ppi, WR_HW_CALIB_RX) ==
if (WRH_OPER()->calib_enable(ppi, WR_HW_CALIB_RX) ==
WR_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_6;
else
......@@ -100,7 +100,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_6:
/* wait until Rx calibration is finished */
if (wrp->ops->calib_poll(ppi, WR_HW_CALIB_RX, &delta) ==
if (WRH_OPER()->calib_poll(ppi, WR_HW_CALIB_RX, &delta) ==
WR_HW_CALIB_READY) {
pp_diag(ppi, ext, 1, "Rx fixed delay = %d\n", (int)delta);
wrp->deltaRx.scaledPicoseconds.msb =
......@@ -119,7 +119,7 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_7:
/* disable Rx calibration */
if (wrp->ops->calib_disable(ppi, WR_HW_CALIB_RX)
if (WRH_OPER()->calib_disable(ppi, WR_HW_CALIB_RX)
== WR_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_8;
else
......
......@@ -19,7 +19,7 @@ int wr_link_on(struct pp_instance *ppi, void *buf, int len)
int e = 0;
wrp->wrModeOn = TRUE;
wrp->ops->enable_ptracker(ppi);
WRH_OPER()->enable_ptracker(ppi);
if (wrp->wrMode == WR_MASTER)
e = msg_issue_wrsig(ppi, WR_MODE_ON);
......
......@@ -21,7 +21,7 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len)
enable = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
if (send_pattern)
wrp->ops->calib_pattern_disable(ppi);
WRH_OPER()->calib_pattern_disable(ppi);
if (wr_handshake_retry(ppi))
enable = 1;
else
......@@ -30,7 +30,7 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len)
if (enable) { /* first or retry */
if (send_pattern)
wrp->ops->calib_pattern_enable(ppi, 0, 0, 0);
WRH_OPER()->calib_pattern_enable(ppi, 0, 0, 0);
__pp_timeout_set(ppi, PP_TO_EXT_0,
wrp->wrStateTimeout / 1000);
}
......@@ -42,7 +42,7 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len)
if (wrp->msgTmpWrMessageID == CALIBRATED) {
if (send_pattern)
wrp->ops->calib_pattern_disable(ppi);
WRH_OPER()->calib_pattern_disable(ppi);
if (wrp->wrMode == WR_MASTER)
ppi->next_state = WRS_WR_LINK_ON;
else
......
......@@ -19,7 +19,7 @@ int wr_s_lock(struct pp_instance *ppi, void *buf, int len)
wrp->wrStateRetry = WR_STATE_RETRY;
enable = 1;
} else if (pp_timeout(ppi, PP_TO_EXT_0)) {
wrp->ops->locking_disable(ppi);
WRH_OPER()->locking_disable(ppi);
if (wr_handshake_retry(ppi))
enable = 1;
else
......@@ -27,16 +27,16 @@ int wr_s_lock(struct pp_instance *ppi, void *buf, int len)
}
if (enable) {
wrp->ops->locking_enable(ppi);
WRH_OPER()->locking_enable(ppi);
__pp_timeout_set(ppi, PP_TO_EXT_0, WR_S_LOCK_TIMEOUT_MS);
}
ppi->next_delay = wrp->wrStateTimeout;
poll_ret = wrp->ops->locking_poll(ppi, 0);
poll_ret = WRH_OPER()->locking_poll(ppi, 0);
if (poll_ret == WR_SPLL_READY) {
ppi->next_state = WRS_LOCKED;
wrp->ops->locking_disable(ppi);
WRH_OPER()->locking_disable(ppi);
} else if (poll_ret == WR_SPLL_CALIB_NOT_READY) {
/* rxts_calibration not ready, enter the same state without
* a delay */
......
......@@ -16,6 +16,7 @@
/* Don't include the Following when this file is included in assembler. */
#ifndef __ASSEMBLY__
#include <ppsi/lib.h>
#include <wrh/wrh.h>
#include "wr-constants.h"
/*
......@@ -23,7 +24,6 @@
* (see wrspec.v2-06-07-2011, page 17)
*/
struct wr_dsport {
struct wr_operations *ops; /* hardware-dependent, see below */
Enumeration8 wrConfig;
Enumeration8 wrMode;
Boolean wrModeOn;
......@@ -99,38 +99,6 @@ void wr_handshake_init(struct pp_instance *ppi, int mode);
void wr_handshake_fail(struct pp_instance *ppi); /* goto non-wr */
int wr_handshake_retry(struct pp_instance *ppi); /* 1 == retry; 0 == failed */
int wr_execute_slave(struct pp_instance *ppi);
struct wr_servo_state;
/* White Rabbit hw-dependent functions (code in arch-wrpc and arch-wrs) */
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);
int (*adjust_counters)(int64_t adjust_sec, int32_t adjust_nsec);
int (*adjust_phase)(int32_t phase_ps);
int (*read_calib_data)(struct pp_instance *ppi,
uint32_t *deltaTx, uint32_t *deltaRx,
int32_t *fix_alpha, int32_t *clock_period);
int (*calib_disable)(struct pp_instance *ppi, int txrx);
int (*calib_enable)(struct pp_instance *ppi, int txrx);
int (*calib_poll)(struct pp_instance *ppi, int txrx, uint32_t *delta);
int (*calib_pattern_enable)(struct pp_instance *ppi,
unsigned int calibrationPeriod,
unsigned int calibrationPattern,
unsigned int calibrationPatternLen);
int (*calib_pattern_disable)(struct pp_instance *ppi);
int (*enable_timing_output)(struct pp_instance *ppi, int enable);
int (*servo_hook)(struct wr_servo_state *s, int action);
};
enum {
WR_SERVO_ENTER, WR_SERVO_LEAVE
};
/* wr_servo interface */
......@@ -143,7 +111,8 @@ int wr_servo_got_delay(struct pp_instance *ppi);
int wr_servo_update(struct pp_instance *ppi);
struct wr_servo_state {
char if_name[16]; /* Informative, for wr_mon through shmem */
struct wrh_servo_head servo_head; /* Must be on top of the structure */
char if_name[16]; /* Informative, for the monitoring tool through shmem */
unsigned long flags;
#define WR_FLAG_VALID 1
......@@ -196,6 +165,5 @@ struct wr_data {
};
extern struct pp_ext_hooks wr_ext_hooks;
#endif /* __ASSEMBLY__ */
#endif /* __WREXT_WR_API_H__ */
......@@ -177,14 +177,14 @@ int wr_servo_init(struct pp_instance *ppi)
GLBS(ppi)->global_ext_data=&((struct wr_data *) ppi->ext_data)->servo_state; /* Updated for the WR monitor tool */
/* Determine the alpha coefficient */
if (wrp->ops->read_calib_data(ppi, 0, 0,
if (WRH_OPER()->read_calib_data(ppi, 0, 0,
&s->fiber_fix_alpha, &s->clock_period_ps) != WR_HW_CALIB_OK) {
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
return -1;
}
wrp->ops->enable_timing_output(ppi, 0);
WRH_OPER()->enable_timing_output(ppi, 0);
strncpy(s->if_name, ppi->cfg.iface_name, sizeof(s->if_name));
/*
......@@ -194,7 +194,7 @@ int wr_servo_init(struct pp_instance *ppi)
*/
if (s->cur_setpoint > s->clock_period_ps)
s->cur_setpoint %= s->clock_period_ps;
wrp->ops->adjust_phase(s->cur_setpoint);
WRH_OPER()->adjust_phase(s->cur_setpoint);
s->missed_iters = 0;
s->state = WR_UNINITIALIZED;
......@@ -339,7 +339,6 @@ int wr_p2p_offset(struct pp_instance *ppi,
int wr_e2e_offset(struct pp_instance *ppi,
struct wr_servo_state *s, struct pp_time *ts_offset)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
uint64_t big_delta_fix;
uint64_t delay_ms_fix;
static int errcount;
......@@ -355,8 +354,8 @@ int wr_e2e_offset(struct pp_instance *ppi,
return 0;
}
if (wrp->ops->servo_hook) /* FIXME: check this, missing in p2p */
wrp->ops->servo_hook(s, WR_SERVO_ENTER);
if (WRH_OPER()->servo_hook) /* FIXME: check this, missing in p2p */
WRH_OPER()->servo_hook(&s->servo_head, WRH_SERVO_ENTER);
errcount = 0;
......@@ -418,9 +417,7 @@ int wr_e2e_offset(struct pp_instance *ppi,
int wr_servo_update(struct pp_instance *ppi)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct wr_servo_state *s =
&((struct wr_data *)ppi->ext_data)->servo_state;
struct wr_servo_state *s = &((struct wr_data *)ppi->ext_data)->servo_state;
int remaining_offset;
int64_t picos_mu_prev = 0;
......@@ -450,17 +447,17 @@ int wr_servo_update(struct pp_instance *ppi)
(long)ts_offset.secs, (long)ts_offset_ticks,
(long)ts_offset_picos);
locking_poll_ret = wrp->ops->locking_poll(ppi, 0);
locking_poll_ret = WRH_OPER()->locking_poll(ppi, 0);
if (locking_poll_ret != WR_SPLL_READY
&& locking_poll_ret != WR_SPLL_CALIB_NOT_READY) {
pp_diag(ppi, servo, 1, "PLL OutOfLock, should restart sync\n");
wrp->ops->enable_timing_output(ppi, 0);
WRH_OPER()->enable_timing_output(ppi, 0);
/* TODO check
* DSPOR(ppi)->doRestart = TRUE; */
}
/* After each action on the hardware, we must verify if it is over. */
if (!wrp->ops->adjust_in_progress()) {
if (!WRH_OPER()->adjust_in_progress()) {
s->flags &= ~WR_FLAG_WAIT_HW;
} else {
pp_diag(ppi, servo, 1, "servo:busy\n");
......@@ -488,7 +485,7 @@ int wr_servo_update(struct pp_instance *ppi)
switch (s->state) {
case WR_SYNC_TAI:
wrp->ops->adjust_counters(ts_offset.secs, 0);
WRH_OPER()->adjust_counters(ts_offset.secs, 0);
s->flags |= WR_FLAG_WAIT_HW;
/*
* If nsec wrong, code above forces SYNC_NSEC,
......@@ -499,7 +496,7 @@ int wr_servo_update(struct pp_instance *ppi)
break;
case WR_SYNC_NSEC:
wrp->ops->adjust_counters(0, ts_offset_ticks);
WRH_OPER()->adjust_counters(0, ts_offset_ticks);
s->flags |= WR_FLAG_WAIT_HW;
s->state = WR_SYNC_PHASE;
break;
......@@ -509,7 +506,7 @@ int wr_servo_update(struct pp_instance *ppi)
s->cur_setpoint, ts_offset_ticks,
ts_offset_picos);
s->cur_setpoint += ts_offset_picos;
wrp->ops->adjust_phase(s->cur_setpoint);
WRH_OPER()->adjust_phase(s->cur_setpoint);
s->flags |= WR_FLAG_WAIT_HW;
s->state = WR_WAIT_OFFSET_STABLE;
......@@ -533,7 +530,7 @@ int wr_servo_update(struct pp_instance *ppi)
/* ts_to_picos() below returns phase alone */
remaining_offset = abs(ts_offset_picos);
if(remaining_offset < WR_SERVO_OFFSET_STABILITY_THRESHOLD) {
wrp->ops->enable_timing_output(ppi, 1);
WRH_OPER()->enable_timing_output(ppi, 1);
s->delta_ms_prev = s->delta_ms;
s->state = WR_TRACK_PHASE;
} else {
......@@ -559,7 +556,7 @@ int wr_servo_update(struct pp_instance *ppi)
// adjust phase towards offset = 0 make ck0 0
s->cur_setpoint += (ts_offset_picos / 4);
wrp->ops->adjust_phase(s->cur_setpoint);
WRH_OPER()->adjust_phase(s->cur_setpoint);
pp_diag(ppi, time, 1, "adjust phase %i\n",
s->cur_setpoint);
......@@ -587,8 +584,8 @@ out:
/* shmem unlock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
if (wrp->ops->servo_hook)
wrp->ops->servo_hook(s, WR_SERVO_LEAVE);
if (WRH_OPER()->servo_hook)
WRH_OPER()->servo_hook(&s->servo_head, WRH_SERVO_LEAVE);
return 0;
}
......@@ -219,10 +219,9 @@ static int wrs_time_set_utc_offset(struct pp_instance *ppi, int offset, int leap
static int wrs_time_get_servo_state(struct pp_instance *ppi, int *state)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
int locked;
locked = wrp->ops->locking_poll(ppi, 1);
locked = WRH_OPER()->locking_poll(ppi, 1);
if (locked == WR_SPLL_READY)
*state = PP_SERVO_LOCKED;
else
......@@ -264,7 +263,6 @@ static int wrs_time_get(struct pp_instance *ppi, struct pp_time *t)
static int wrs_time_set(struct pp_instance *ppi, const struct pp_time *t)
{
struct pp_time diff, now;
struct timex tx;
int msec;
/*
......
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