Commit e3a99db4 authored by li hongming's avatar li hongming

Add a new mode "cascaded" for dualport.

    Separate the PPS_out with time_valid.
parent 4e567b8e
......@@ -141,11 +141,13 @@ int wrc_ptp_set_mode(int mode, int port)
{
uint32_t start_tics, lock_timeout = 0;
struct pp_globals *ppg = &ppg_static;
struct pp_instance *ppi;
struct wr_dsport *wrp;
struct pp_instance *ppi[wr_num_ports];
struct wr_dsport *wrp[wr_num_ports];
ppi = INST(ppg, port);
wrp = WR_DSPOR(ppi);
for (port=0; port<wr_num_ports;port++) {
ppi[port] = INST(ppg, port);
wrp[port] = WR_DSPOR(ppi[port]);
}
typeof(ppg->rt_opts->clock_quality.clockClass) *class_ptr;
int error = 0;
......@@ -155,57 +157,75 @@ int wrc_ptp_set_mode(int mode, int port)
*/
class_ptr = &__pp_default_rt_opts.clock_quality.clockClass;
ptp_mode[port] = WRC_MODE_UNKNOWN;
wrc_ptp_stop(port);
ppi->cfg.ext = PPSI_EXT_WR; // Enable WR mode
for (port=0; port<wr_num_ports;port++) {
ptp_mode[port] = WRC_MODE_UNKNOWN;
ptp_enabled[port] = 0;
wr_servo_reset(ppi[port]);
ppi[port]->cfg.ext = PPSI_EXT_WR; // Enable WR mode
}
switch (mode) {
case WRC_MODE_GM:
case WRC_MODE_ABSCAL: /* absolute calibration, gm-lookalike */
wrp->wrConfig = WR_M_ONLY;
ppi->role = PPSI_ROLE_MASTER;
for (port=0; port<wr_num_ports;port++) {
wrp[port]->wrConfig = WR_M_ONLY;
ppi[port]->role = PPSI_ROLE_MASTER;
DSDEF(ppi[port])->clockQuality.clockClass = PP_CLASS_WR_GM_LOCKED;
m1(ppi[port]); // port0 and por1 share one pp_global
}
*class_ptr = PP_CLASS_WR_GM_LOCKED;
spll_init(SPLL_MODE_GRAND_MASTER, 0, 1);
shw_pps_gen_unmask_output(1);
spll_init(SPLL_MODE_GRAND_MASTER, 0, 1);
lock_timeout = LOCK_TIMEOUT_GM;
DSDEF(ppi)->clockQuality.clockClass = PP_CLASS_WR_GM_LOCKED;
m1(ppi); // port0 and por1 share one pp_global
break;
case WRC_MODE_MASTER:
ppi->role = PPSI_ROLE_MASTER;
if (port==0) {
*class_ptr = PP_CLASS_WR_GM_LOCKED;
wrp->wrConfig = WR_M_ONLY;
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
lock_timeout = LOCK_TIMEOUT_FM;
shw_pps_gen_unmask_output(1);
DSDEF(ppi)->clockQuality.clockClass = PP_CLASS_WR_GM_LOCKED;
m1(ppi);
} else {
*class_ptr = PP_CLASS_DEFAULT;
wrp->wrConfig = WR_M_AND_S;
DSDEF(ppi)->clockQuality.clockClass = PP_CLASS_DEFAULT;
for (port=0; port<wr_num_ports;port++) {
ppi[port]->role = PPSI_ROLE_MASTER;
wrp[port]->wrConfig = WR_M_ONLY;
DSDEF(ppi[port])->clockQuality.clockClass = PP_CLASS_DEFAULT;
m1(ppi[port]);
}
*class_ptr = PP_CLASS_DEFAULT;
shw_pps_gen_unmask_output(1);
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
lock_timeout = LOCK_TIMEOUT_FM;
break;
case WRC_MODE_CASCADED:
for (port=1; port<wr_num_ports;port++) {
ppi[port]->role = PPSI_ROLE_MASTER;
wrp[port]->wrConfig = WR_M_AND_S;
DSDEF(ppi[port])->clockQuality.clockClass = PP_CLASS_DEFAULT;
m1(ppi[port]);
}
ppi[0]->role = PPSI_ROLE_SLAVE;
wrp[0]->wrConfig = WR_M_AND_S;
DSDEF(ppi[0])->clockQuality.clockClass = PP_CLASS_DEFAULT;
case WRC_MODE_SLAVE:
wrp->wrConfig = WR_M_AND_S;
ppi->role = PPSI_ROLE_SLAVE;
// *class_ptr = PP_CLASS_SLAVE_ONLY;
*class_ptr = PP_CLASS_DEFAULT;
shw_pps_gen_unmask_output(1);
spll_init(SPLL_MODE_SLAVE, 0, 1);
break;
case WRC_MODE_SLAVE:
for (port=0; port<wr_num_ports;port++) {
ppi[port]->role = PPSI_ROLE_SLAVE;
wrp[port]->wrConfig = WR_S_ONLY;
DSDEF(ppi[port])->clockQuality.clockClass = PP_CLASS_DEFAULT;
m1(ppi[port]);
}
*class_ptr = PP_CLASS_SLAVE_ONLY;
spll_init(SPLL_MODE_SLAVE, 0, 1);
shw_pps_gen_unmask_output(0);
break;
}
start_tics = timer_get_tics();
pp_printf("Locking PLL");
wrp->ops->enable_timing_output(ppi, 0); /* later, wr_init chooses */
for (port=0; port<wr_num_ports;port++) {
wrp[port]->ops->enable_timing_output(ppi[port], 0); /* later, wr_init chooses */
}
while (!spll_check_lock(0) && lock_timeout) {
spll_update();
......@@ -218,12 +238,27 @@ int wrc_ptp_set_mode(int mode, int port)
pp_printf(".");
}
pp_printf("\n");
shw_pps_gen_enable_output(1);
/* If we can't lock to the atomic/gps, we say it in the class */
if (error && mode == WRC_MODE_GM)
if (error && (mode == WRC_MODE_GM))
*class_ptr = PP_CLASS_WR_GM_UNLOCKED;
ptp_mode[port] = mode;
switch (mode) {
case WRC_MODE_GM:
case WRC_MODE_ABSCAL: /* absolute calibration, gm-lookalike */
case WRC_MODE_MASTER:
case WRC_MODE_SLAVE:
for (port=0; port<wr_num_ports;port++)
ptp_mode[port] = mode;
break;
case WRC_MODE_CASCADED:
ptp_mode[0] = WRC_MODE_SLAVE;
for (port=1; port<wr_num_ports;port++)
ptp_mode[port] = WRC_MODE_MASTER;
break;
}
return error;
}
......@@ -288,13 +323,14 @@ int wrc_ptp_stop(int port)
wrp = WR_DSPOR(ppi);
pp_printf("Port %d PTP stop\n",port);
/* Moving fiber: forget about this parent (FIXME: shouldn't be here) */
wrp->parentWrConfig = wrp->parentWrModeOn = 0;
memset(ppi->frgn_master, 0, sizeof(ppi->frgn_master));
ppi->frgn_rec_num = 0; /* no known master */
if(port==0) {
wrp->parentWrConfig = wrp->parentWrModeOn = 0;
memset(ppi->frgn_master, 0, sizeof(ppi->frgn_master));
ppi->frgn_rec_num = 0; /* no known master */
}
ptp_enabled[port] = 0;
wr_servo_reset(ppi);
pp_close_globals(&ppg_static);
// pp_close_globals(&ppg_static); -- this function does nothing
return 0;
}
......
......@@ -69,6 +69,7 @@ int wrpc_enable_timing_output(struct pp_instance *ppi, int enable)
WR_DSPOR(ppi)->ppsOutputOn = enable;
shw_pps_gen_enable_output(enable);
shw_pps_gen_time_valid(enable);
return WR_SPLL_OK;
}
......
......@@ -19,6 +19,8 @@
#define WRC_MODE_MASTER 2
#define WRC_MODE_SLAVE 3
#define WRC_MODE_ABSCAL 4
#define WRC_MODE_CASCADED 5
extern int ptp_mode[2];
int wrc_ptp_init(void);
......
......@@ -16,10 +16,10 @@ static int wr_init(struct pp_instance *ppi, unsigned char *pkt, int plen)
wrp->parentWrModeOn = 0;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
if ((wrp->wrConfig & WR_M_AND_S) == WR_M_ONLY)
wrp->ops->enable_timing_output(ppi, 1);
else
wrp->ops->enable_timing_output(ppi, 0);
// if ((wrp->wrConfig & WR_M_AND_S) == WR_M_ONLY)
// wrp->ops->enable_timing_output(ppi, 1);
// else
// wrp->ops->enable_timing_output(ppi, 0);
return 0;
}
......@@ -141,10 +141,10 @@ 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);
else
wrp->ops->enable_timing_output(ppi, 1);
// if (ofm->secs)
// wrp->ops->enable_timing_output(ppi, 0);
// else
// wrp->ops->enable_timing_output(ppi, 1);
}
wr_servo_got_delay(ppi);
......@@ -230,10 +230,10 @@ 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);
else
wrp->ops->enable_timing_output(ppi, 1);
// if (ofm->secs)
// wrp->ops->enable_timing_output(ppi, 0);
// else
// wrp->ops->enable_timing_output(ppi, 1);
return 0;
}
......
......@@ -139,6 +139,9 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
* to transmit it for real, if we want to get back our
* hardware stamp. Thus, remember if we drop, and use this info.
*/
if(link_status[port]!=LINK_UP)
return PP_SEND_DROP;
if (CONFIG_HAS_WRPC_FAULTS)
drop = ppsi_drop_tx();
......
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