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

Infrastructure changes: Allow to have port instances using different

extensions
parent 2dc1b909
......@@ -28,6 +28,8 @@ static struct pp_runtime_opts sim_master_rt_opts = {
.ttl = PP_DEFAULT_TTL,
};
extern struct pp_ext_hooks pp_hooks;
/*
* In arch-sim we use two pp_instaces in the same pp_globals to represent
* two different machines. This means *completely differnt* machines, with
......@@ -58,6 +60,7 @@ static int sim_ppi_init(struct pp_instance *ppi, int which_ppi)
ppi->__rx_buffer = malloc(PP_MAX_FRAME_LENGTH);
ppi->arch_data = calloc(1, sizeof(struct sim_ppi_arch_data));
ppi->portDS = calloc(1, sizeof(*ppi->portDS));
ppi->ext_hooks=&pp_hooks;
if ((!ppi->arch_data) || (!ppi->portDS))
return -1;
data = SIM_PPI_ARCH(ppi);
......
......@@ -31,6 +31,8 @@ static DSParent parentDS;
static DSTimeProperties timePropertiesDS;
static struct pp_servo servo;
extern struct pp_ext_hooks pp_hooks;
int main(int argc, char **argv)
{
struct pp_globals *ppg;
......@@ -93,6 +95,7 @@ int main(int argc, char **argv)
ppi->iface_name = ppi->cfg.iface_name;
ppi->port_name = ppi->cfg.port_name;
ppi->mech = ppi->cfg.mech;
ppi->ext_hooks= &pp_hooks;
/* The following default names depend on TIME= at build time */
ppi->n_ops = &DEFAULT_NET_OPS;
......
......@@ -11,8 +11,6 @@
#include <ppsi/ppsi.h>
#include "wrpc.h"
#include <common-fun.h>
#include "../proto-ext-whiterabbit/wr-api.h"
#include "../proto-ext-whiterabbit/wr-constants.h"
/* All of these live in wrpc-sw/include */
#include "minic.h"
......@@ -55,15 +53,21 @@ static DSCurrent currentDS;
static DSParent parentDS;
static DSTimeProperties timePropertiesDS;
static struct pp_servo servo;
static struct wr_servo_state servo_state;
#if CONFIG_EXT_WR == 1
/* WR extension declaration */
#include "../proto-ext-whiterabbit/wr-api.h"
#include "../proto-ext-whiterabbit/wr-constants.h"
static struct wr_data wr_ext_data; /* WR extension data */
static struct wr_dsport wr_dsport = {
.ops = &wrpc_wr_operations,
};
static DSPort portDS = {
.ext_dsport = &wr_dsport
};
#endif
static DSPort portDS ;
static int delay_ms = PP_DEFAULT_NEXT_DELAY_MS;
static int start_tics = 0;
......@@ -83,8 +87,8 @@ struct pp_instance ppi_static = {
.mech = PP_E2E_MECH, /* until changed by cfg */
.iface_name = "wr1",
.port_name = "wr1",
.__tx_buffer = __tx_buffer,
.__rx_buffer = __rx_buffer,
.__tx_buffer = __tx_buffer,
.__rx_buffer = __rx_buffer,
};
/* We now have a structure with all globals, and multiple ppi inside */
......@@ -95,17 +99,29 @@ static struct pp_globals ppg_static = {
.currentDS = &currentDS,
.parentDS = &parentDS,
.timePropertiesDS = &timePropertiesDS,
.global_ext_data = &servo_state,
};
extern struct pp_ext_hooks pp_hooks;
int wrc_ptp_init()
{
struct pp_instance *ppi = &ppi_static;
sdb_find_devices();
uart_init_hw();
pp_printf("PPSi for WRPC. Commit %s, built on " __DATE__ "\n",
PPSI_VERSION);
ppi->ext_hooks =&pp_hooks; /* default value */
if ( CONFIG_EXT_WR == 1 ) {
ppi->ext_hooks = &wr_ext_hooks;
ppi->ext_data = &wr_ext_data;
GBLS(ppi)->global_ext_data=&wr_ext_data.servo_state; /* Updated for the WR monitor tools */
portDS.ext_dsport = &wr_dsport;
}
return 0;
}
......
......@@ -28,6 +28,13 @@
#include <ppsi-wrs.h>
#include <libwr/shmem.h>
#if CONFIG_EXT_WR == 1
/* WR extension declaration */
#include "../proto-ext-whiterabbit/wr-api.h"
#include "../proto-ext-whiterabbit/wr-constants.h"
#endif
# define WRSW_HAL_RETRIES 1000
#define WRSW_HAL_TIMEOUT 2000000 /* us */
......@@ -58,6 +65,9 @@ struct minipc_ch *ppsi_ch;
struct hal_port_state *hal_ports;
int hal_nports;
struct wrs_shm_head *ppsi_head;
extern struct pp_ext_hooks pp_hooks;
/*
* we need to call calloc, to reset all stuff that used to be static,
* but we'd better have a simple prototype, compatilble with wrs_shm_alloc()
......@@ -75,7 +85,6 @@ int main(int argc, char **argv)
{
struct pp_globals *ppg;
struct pp_instance *ppi;
struct wr_dsport *wrp;
unsigned long seed;
struct timex t;
int i, hal_retries;
......@@ -176,8 +185,7 @@ int main(int argc, char **argv)
ppg->rt_opts = &__pp_default_rt_opts;
ppg->max_links = PP_MAX_LINKS;
ppg->global_ext_data = alloc_fn(ppsi_head,
sizeof(struct wr_servo_state));
/* NOTE: arch_data is not in shmem */
ppg->arch_data = malloc( sizeof(struct unix_arch_data));
ppg->pp_instances = alloc_fn(ppsi_head,
......@@ -228,16 +236,30 @@ int main(int argc, char **argv)
ppi->port_name = ppi->cfg.port_name;
ppi->mech = ppi->cfg.mech;
ppi->portDS = alloc_fn(ppsi_head, sizeof(*ppi->portDS));
ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */
if (ppi->portDS) {
ppi->portDS->ext_dsport =
alloc_fn(ppsi_head, sizeof(struct wr_dsport));
}
if (!ppi->portDS || !ppi->portDS->ext_dsport) {
fprintf(stderr, "ppsi: out of memory\n");
exit(1);
if ( CONFIG_EXT_WR == 1 && ppi->cfg.ext==PPSI_EXT_WR ) {
struct wr_dsport *wrp;
/* 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))) ) {
goto exit_out_of_memory;
}
/* Set WR extension hooks */
ppi->ext_hooks=&wr_ext_hooks;
ppg->global_ext_data=ppi->ext_data;
}
} else {
goto exit_out_of_memory;
}
wrp = WR_DSPOR(ppi); /* just allocated above */
wrp->ops = &wrs_wr_operations;
/* The following default names depend on TIME= at build time */
ppi->n_ops = &DEFAULT_NET_OPS;
......@@ -247,8 +269,7 @@ int main(int argc, char **argv)
ppi->__rx_buffer = malloc(PP_MAX_FRAME_LENGTH);
if (!ppi->__tx_buffer || !ppi->__rx_buffer) {
fprintf(stderr, "ppsi: out of memory\n");
exit(1);
goto exit_out_of_memory;
}
}
......@@ -264,4 +285,9 @@ int main(int argc, char **argv)
wrs_main_loop(ppg);
return 0; /* never reached */
exit_out_of_memory:;
fprintf(stderr, "ppsi: out of memory\n");
exit(1);
}
......@@ -88,8 +88,8 @@ get_current_state_table_item(struct pp_instance *ppi)
int pp_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 ( ppi->ext_hooks->state_change)
ppi->ext_hooks->state_change(ppi);
/* if the next or old state is non standard PTP reset all timeouts */
if ((ppi->state > PPS_LAST_STATE) || (ppi->next_state > PPS_LAST_STATE))
......
......@@ -132,6 +132,7 @@ struct pp_instance {
struct pp_state_table_item *current_state_item;
void *arch_data; /* if arch needs it */
void *ext_data; /* if protocol ext needs it */
struct pp_ext_hooks *ext_hooks; /* if protocol ext needs it */
unsigned long d_flags; /* diagnostics, ppi-specific flags */
unsigned char flags; /* protocol flags (see below) */
int role, /* same as in config file */
......
......@@ -163,6 +163,7 @@ static inline struct pp_servo *SRV(struct pp_instance *ppi)
return GLBS(ppi)->servo;
}
extern void pp_prepare_pointers(struct pp_instance *ppi);
/*
......@@ -175,8 +176,8 @@ extern void pp_prepare_pointers(struct pp_instance *ppi);
*/
struct pp_ext_hooks {
int (*init)(struct pp_instance *ppg, void *buf, int len);
int (*open)(struct pp_globals *ppi, struct pp_runtime_opts *rt_opts);
int (*close)(struct pp_globals *ppg);
int (*open)(struct pp_instance *ppi, struct pp_runtime_opts *rt_opts);
int (*close)(struct pp_instance *ppi);
int (*listening)(struct pp_instance *ppi, void *buf, int len);
int (*master_msg)(struct pp_instance *ppi, void *buf,
int len, int msgtype);
......@@ -194,9 +195,6 @@ struct pp_ext_hooks {
void (*state_change)(struct pp_instance *ppi);
};
extern struct pp_ext_hooks pp_hooks; /* The one for the extension we build */
/*
* Network methods are encapsulated in a structure, so each arch only needs
* to provide that structure. This simplifies management overall.
......@@ -411,7 +409,7 @@ extern int __attribute__((warn_unused_result))
msg_unpack_header(struct pp_instance *ppi, void *buf, int len);
extern void msg_unpack_sync(void *buf, MsgSync *sync);
extern int msg_pack_sync(struct pp_instance *ppi, struct pp_time *orig_tstamp);
extern void msg_unpack_announce(void *buf, MsgAnnounce *ann);
extern void msg_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *ann);
extern void msg_unpack_follow_up(void *buf, MsgFollowUp *flwup);
extern void msg_unpack_delay_req(void *buf, MsgDelayReq *delay_req);
extern void msg_unpack_delay_resp(void *buf, MsgDelayResp *resp);
......
......@@ -33,42 +33,29 @@ static int wr_init(struct pp_instance *ppi, void *buf, int len)
return 0;
}
static int wr_open(struct pp_globals *ppg, struct pp_runtime_opts *rt_opts)
/* open hook called only for each WR pp_instances */
static int wr_open(struct pp_instance *ppi, struct pp_runtime_opts *rt_opts)
{
int i;
pp_diag(NULL, ext, 2, "hook: %s\n", __func__);
/* If current arch (e.g. wrpc) is not using the 'pp_links style'
* configuration, just assume there is one ppi instance,
* already configured properly by the arch's main loop */
if (ppg->nlinks == 0) {
INST(ppg, 0)->ext_data = ppg->global_ext_data;
return 0;
}
for (i = 0; i < ppg->nlinks; i++) {
struct pp_instance *ppi = INST(ppg, i);
/* FIXME check if correct: assign to each instance the same
* wr_data. May I move it to pp_globals? */
INST(ppg, i)->ext_data = ppg->global_ext_data;
if (ppi->cfg.ext == PPSI_EXT_WR) {
switch (ppi->role) {
case PPSI_ROLE_MASTER:
WR_DSPOR(ppi)->wrConfig = WR_M_ONLY;
break;
case PPSI_ROLE_SLAVE:
WR_DSPOR(ppi)->wrConfig = WR_S_ONLY;
break;
default:
WR_DSPOR(ppi)->wrConfig = WR_M_AND_S;
}
if (ppi->cfg.ext == PPSI_EXT_WR) {
switch (ppi->role) {
case PPSI_ROLE_MASTER:
WR_DSPOR(ppi)->wrConfig = WR_M_ONLY;
break;
case PPSI_ROLE_SLAVE:
WR_DSPOR(ppi)->wrConfig = WR_S_ONLY;
break;
default:
WR_DSPOR(ppi)->wrConfig = WR_M_AND_S;
}
else
WR_DSPOR(ppi)->wrConfig = NON_WR;
return 0;
}
else {
WR_DSPOR(ppi)->wrConfig = NON_WR;
pp_diag(ppi, ext, 1, "hook: %s called but is not a WR extension \n", __func__);
return 1;
}
return 0;
}
static int wr_listening(struct pp_instance *ppi, void *buf, int len)
......@@ -349,7 +336,7 @@ static void wr_state_change(struct pp_instance *ppi)
}
}
struct pp_ext_hooks pp_hooks = {
struct pp_ext_hooks wr_ext_hooks = {
.init = wr_init,
.open = wr_open,
.listening = wr_listening,
......
......@@ -195,5 +195,7 @@ struct wr_data {
struct wr_servo_state servo_state;
};
extern struct pp_ext_hooks wr_ext_hooks;
#endif /* __ASSEMBLY__ */
#endif /* __WREXT_WR_API_H__ */
......@@ -173,6 +173,9 @@ int wr_servo_init(struct pp_instance *ppi)
&((struct wr_data *)ppi->ext_data)->servo_state;
/* shmem lock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_BEGIN);
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,
&s->fiber_fix_alpha, &s->clock_period_ps) != WR_HW_CALIB_OK) {
......
......@@ -282,8 +282,8 @@ void bmc_s1(struct pp_instance *ppi,
prop->ptpTimescale = ((frgn_master->flagField[1] & FFB_PTP) != 0);
prop->timeSource = frgn_master->timeSource;
if (pp_hooks.s1)
pp_hooks.s1(ppi, frgn_master);
if (ppi->ext_hooks->s1)
ppi->ext_hooks->s1(ppi, frgn_master);
}
void bmc_p1(struct pp_instance *ppi)
......@@ -832,7 +832,7 @@ void bmc_store_frgn_master(struct pp_instance *ppi,
* header and announce field of each Foreign Master are
* useful to run Best Master Clock Algorithm
*/
msg_unpack_announce(buf, &ann);
msg_unpack_announce(ppi, buf, &ann);
memcpy(&frgn_master->receivePortIdentity,
&DSPOR(ppi)->portIdentity, sizeof(PortIdentity));
......@@ -1457,8 +1457,8 @@ int bmc(struct pp_instance *ppi)
}
/* Extra states handled here */
if (pp_hooks.state_decision)
next_state = pp_hooks.state_decision(ppi, next_state);
if (ppi->ext_hooks->state_decision)
next_state = ppi->ext_hooks->state_decision(ppi, next_state);
return next_state;
}
......@@ -72,8 +72,8 @@ static int presp_call_servo(struct pp_instance *ppi)
return 0; /* not an error, just no data */
pp_timeout_set(ppi, PP_TO_FAULT);
if (pp_hooks.handle_presp)
ret = pp_hooks.handle_presp(ppi);
if (ppi->ext_hooks->handle_presp)
ret = ppi->ext_hooks->handle_presp(ppi);
else
pp_servo_got_presp(ppi);
......@@ -200,8 +200,8 @@ int st_com_peer_handle_preq(struct pp_instance *ppi, void *buf,
if (!CONFIG_HAS_P2P || ppi->mech != PP_P2P_MECH)
return 0;
if (pp_hooks.handle_preq)
e = pp_hooks.handle_preq(ppi);
if (ppi->ext_hooks->handle_preq)
e = ppi->ext_hooks->handle_preq(ppi);
if (e)
return e;
......@@ -215,8 +215,8 @@ int st_com_handle_announce(struct pp_instance *ppi, void *buf, int len)
{
bmc_add_frgn_master(ppi, buf, len);
if (pp_hooks.handle_announce)
return pp_hooks.handle_announce(ppi);
if (ppi->ext_hooks->handle_announce)
return ppi->ext_hooks->handle_announce(ppi);
return 0;
}
......
#include <ppsi/ppsi.h>
/* proto-standard offers all-null hooks as a default extension */
struct pp_ext_hooks __attribute__((weak)) pp_hooks;
struct pp_ext_hooks pp_hooks;
......@@ -187,13 +187,13 @@ static int msg_pack_announce(struct pp_instance *ppi)
*(UInteger8 *) (buf + 62) = (UInteger8)DSCUR(ppi)->stepsRemoved;
*(Enumeration8 *) (buf + 63) = DSPRO(ppi)->timeSource;
if (pp_hooks.pack_announce)
len = pp_hooks.pack_announce(ppi);
if (ppi->ext_hooks->pack_announce)
len = ppi->ext_hooks->pack_announce(ppi);
return len;
}
/* Unpack Announce message from in buffer of ppi to internal structure */
void msg_unpack_announce(void *buf, MsgAnnounce *ann)
void msg_unpack_announce(struct pp_instance *ppi, void *buf, MsgAnnounce *ann)
{
ann->originTimestamp.secondsField.msb =
htons(*(UInteger16 *) (buf + 34));
......@@ -218,8 +218,8 @@ void msg_unpack_announce(void *buf, MsgAnnounce *ann)
ann->timeSource = *(Enumeration8 *) (buf + 63);
/* this can fill in extention specific flags otherwise just zero them*/
if (pp_hooks.unpack_announce)
pp_hooks.unpack_announce(buf, ann);
if (ppi->ext_hooks->unpack_announce)
ppi->ext_hooks->unpack_announce(buf, ann);
else
ann->ext_specific = 0;
}
......
......@@ -40,7 +40,7 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
/*
* Initialize default data set
*/
int i;
int i,ret=0;
struct DSDefault *def = ppg->defaultDS;
def->twoStepFlag = TRUE;
......@@ -85,14 +85,30 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
def->clockQuality.clockClass);
}
if (pp_hooks.open)
return pp_hooks.open(ppg, rt_opts);
return 0;
for (i = 0; i < def->numberPorts; i++) {
struct pp_instance *ppi = INST(ppg, i);
int r;
if (ppi->ext_hooks->open) {
ret=(r=ppi->ext_hooks->open(ppi, rt_opts))==0 ? ret : r;
}
}
return ret;
}
int pp_close_globals(struct pp_globals *ppg)
{
if (pp_hooks.close)
return pp_hooks.close(ppg);
return 0;
int i,ret=0;;
struct DSDefault *def = ppg->defaultDS;
for (i = 0; i < def->numberPorts; i++) {
struct pp_instance *ppi = INST(ppg, i);
int r;
if (ppi->ext_hooks->close) {
ret=(r=ppi->ext_hooks->close(ppi))==0 ? ret : r;
}
}
return ret;
}
......@@ -106,8 +106,8 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
pp_timeout_init(ppi);
pp_timeout_setall(ppi);
if (pp_hooks.init)
ret = pp_hooks.init(ppi, buf, len);
if (ppi->ext_hooks->init)
ret = ppi->ext_hooks->init(ppi, buf, len);
if (ret) {
pp_diag(ppi, ext, 1, "%s: can't init extension\n", __func__);
goto failure;
......
......@@ -29,8 +29,8 @@ int pp_listening(struct pp_instance *ppi, void *buf, int len)
MsgHeader *hdr = &ppi->received_ptp_header;
pp_timeout_set(ppi, PP_TO_FAULT); /* no fault as long as we listen */
if (pp_hooks.listening)
e = pp_hooks.listening(ppi, buf, len);
if (ppi->ext_hooks->listening)
e = ppi->ext_hooks->listening(ppi, buf, len);
if (e)
goto out;
......
......@@ -76,8 +76,8 @@ int pp_master(struct pp_instance *ppi, void *buf, int len)
* PPM_NO_MESSAGE
*/
msgtype = ppi->received_ptp_header.messageType;
if (pp_hooks.master_msg)
msgtype = pp_hooks.master_msg(ppi, buf, len, msgtype);
if (ppi->ext_hooks->master_msg)
msgtype = ppi->ext_hooks->master_msg(ppi, buf, len, msgtype);
if (msgtype < 0) {
e = msgtype;
len = 0;
......
......@@ -99,8 +99,8 @@ static int slave_handle_followup(struct pp_instance *ppi, void *buf,
ppi->syncCF = hdr->cField.scaled_nsecs; /* for diag about TC */
/* Call the extension; it may do it all and ask to return */
if (pp_hooks.handle_followup)
ret = pp_hooks.handle_followup(ppi, &ppi->t1);
if (ppi->ext_hooks->handle_followup)
ret = ppi->ext_hooks->handle_followup(ppi, &ppi->t1);
if (ret == 1)
return 0;
if (ret < 0)
......@@ -141,8 +141,8 @@ static int slave_handle_response(struct pp_instance *ppi, void *buf,
/* WARNING: should be "sub" (see README-cfield::BUG) */
pp_timeout_set(ppi, PP_TO_FAULT);
if (pp_hooks.handle_resp)
e = pp_hooks.handle_resp(ppi);
if (ppi->ext_hooks->handle_resp)
e = ppi->ext_hooks->handle_resp(ppi);
else
pp_servo_got_resp(ppi);
if (e)
......@@ -183,8 +183,8 @@ static int slave_execute(struct pp_instance *ppi)
{
int ret = 0;
if (pp_hooks.execute_slave)
ret = pp_hooks.execute_slave(ppi);
if (ppi->ext_hooks->execute_slave)
ret = ppi->ext_hooks->execute_slave(ppi);
if (ret == 1) /* done: just return */
return 0;
if (ret < 0)
......@@ -221,8 +221,8 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n");
pp_servo_init(ppi);
if (pp_hooks.new_slave)
e = pp_hooks.new_slave(ppi, buf, len);
if (ppi->ext_hooks->new_slave)
e = ppi->ext_hooks->new_slave(ppi, buf, len);
if (e)
goto out;
}
......
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