From 0351e9eb5004b17df27e62948cf1b71f880b714e Mon Sep 17 00:00:00 2001 From: Adam Wujek <dev_public@wujek.eu> Date: Wed, 9 Aug 2023 15:15:25 +0200 Subject: [PATCH] arch-wrs: add support for changing extension in runtime Signed-off-by: Adam Wujek <dev_public@wujek.eu> --- Kconfig_ppsi | 6 - arch-wrs/include/ppsi-wrs.h | 2 + arch-wrs/include/ppsi_exports.h | 6 + arch-wrs/wrs-ipcserver.c | 49 ++++++ arch-wrs/wrs-startup.c | 281 ++++++++++++++++++++++---------- include/ppsi/pp-instance.h | 11 ++ include/ppsi/ppsi.h | 10 +- proto-ext-l1sync/l1e-api.h | 7 +- proto-ext-whiterabbit/wr-api.h | 5 + proto-standard/open-close.c | 17 +- tools/ppsi_conf.c | 47 ++++++ tools/wrs_dump_shmem_ppsi.c | 1 + 12 files changed, 342 insertions(+), 100 deletions(-) diff --git a/Kconfig_ppsi b/Kconfig_ppsi index 860a37a2..18d2a984 100644 --- a/Kconfig_ppsi +++ b/Kconfig_ppsi @@ -244,12 +244,6 @@ config HAS_EXT_L1SYNC default 1 if PROFILE_HA default 0 -config HAS_EXT_NONE - int - range 0 1 - default 1 if !(PROFILE_WR || PROFILE_HA || PROFILE_CUSTOM) - default 0 - config HAS_PROFILE_PTP int range 0 1 diff --git a/arch-wrs/include/ppsi-wrs.h b/arch-wrs/include/ppsi-wrs.h index 35c1fb8c..bbbad8a8 100644 --- a/arch-wrs/include/ppsi-wrs.h +++ b/arch-wrs/include/ppsi-wrs.h @@ -79,6 +79,8 @@ int32_t wrs_get_clock_period(void); /* wrs-startup.c */ void enable_asymmetryCorrection(struct pp_instance *ppi, Boolean enable ); +int set_profile(struct pp_instance *ppi, int profile); +int set_extension(struct pp_instance *ppi, int extension); /* wrs-time.c (some should moce to wrs-spll.c) */ void wrs_init_rts_addr(uint32_t addr,const char *devname); diff --git a/arch-wrs/include/ppsi_exports.h b/arch-wrs/include/ppsi_exports.h index 28a27d59..c7553b77 100644 --- a/arch-wrs/include/ppsi_exports.h +++ b/arch-wrs/include/ppsi_exports.h @@ -26,10 +26,16 @@ /* Commands for ppsiexp_update_param_instance_cmd */ #define PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD 1 #define PPSIEXP_PARAM_INST_SYNC_INT_CMD 2 +#define PPSIEXP_PARAM_INST_EXTENSION_CMD 3 /* Commands for ppsiexp_update_param_str_instance_cmd */ #define PPSIEXP_PARAM_INST_STR_DIAG_CMD 1 +/* Values for PPSIEXP_PARAM_INST_EXTENSION_CMD */ +#define PPSIEXP_PARAM_EXTENSION_NONE PPSI_EXT_NONE +#define PPSIEXP_PARAM_EXTENSION_WR PPSI_EXT_WR +#define PPSIEXP_PARAM_EXTENSION_L1SYNC PPSI_EXT_L1S + #define PPSI_INSTANCE_USE_PORT 0x80000000 /* Export structures, shared by server and client for argument matching */ diff --git a/arch-wrs/wrs-ipcserver.c b/arch-wrs/wrs-ipcserver.c index 352c1baa..a8662ef2 100644 --- a/arch-wrs/wrs-ipcserver.c +++ b/arch-wrs/wrs-ipcserver.c @@ -144,8 +144,57 @@ static int update_param_instance(struct pp_instance *ppi, int ppi_i, int param_type, int param_val) { int rval = PPSIEXP_RET_OK; + int tmp = 0; switch (param_type) { + case PPSIEXP_PARAM_INST_EXTENSION_CMD: + pp_diag(ppi, config, 2, + "%s: cmd %d (PPSIEXP_PARAM_INST_EXTENSION_CMD) " + "instance %d, port %s, value %d\n", __func__, param_type, + ppi_i, ppi->iface_name, param_val); + + switch (param_val) { + case PPSIEXP_PARAM_EXTENSION_NONE: + case PPSIEXP_PARAM_EXTENSION_WR: + case PPSIEXP_PARAM_EXTENSION_L1SYNC: + /* Known value */ + break; + default: + /* Value not known */ + pp_diag(ppi, config, 1, + "Param update Error: value of " + "extension (%d) not in range! " + "cmd %d (PPSIEXP_PARAM_INST_EXTENSION_CMD) " + "instance %d, port %s\n", + param_val, param_type, ppi_i, ppi->iface_name); + return PPSIEXP_RET_ERROR_VAL; + } + + set_extension(ppi, param_val); + /* Default value for PTP. Can be overwritten in specific init */ + ppi->pdstate = PP_PDSTATE_NONE; + ppi->extState = + (ppi->protocol_extension == PPSI_EXT_NONE) + ? PP_EXSTATE_DISABLE : PP_EXSTATE_ACTIVE; + /* TODO: set wrModeOn and wrMode with something better, or + * check if WR ext is set */ + wr_reset_process(ppi, WR_ROLE_NONE); + if (is_ext_hook_available(ppi, init)) + tmp = ppi->ext_hooks->init(ppi, NULL, 0); + if (tmp) { + pp_diag(ppi, ext, 1, "%s: can't init extension\n", + __func__); + rval = PPSIEXP_RET_ERROR_VAL; + break; + } + /* When the extension/profile is changed the servo is not reset + * nor initialized initialization of servo (wrh_servo_init) is + * done via new_slave */ + pp_servo_init(ppi); + if (is_ext_hook_available(ppi,new_slave)) + ppi->ext_hooks->new_slave(ppi, NULL, 0); + break; + case PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD: pp_diag(ppi, config, 2, "%s: cmd %d (PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD) " diff --git a/arch-wrs/wrs-startup.c b/arch-wrs/wrs-startup.c index a2aa3b49..aee81e61 100644 --- a/arch-wrs/wrs-startup.c +++ b/arch-wrs/wrs-startup.c @@ -57,33 +57,200 @@ struct wrs_shm_head *ppsi_head; extern struct pp_ext_hooks pp_hooks; +static int init_extensions(struct pp_instance *ppi) +{ + struct pp_ext_mem *ppi_ext_data; + + if (!(ppi_ext_data = + wrs_shm_alloc(ppsi_head, + sizeof(struct pp_ext_mem) * (PPSI_EXT_N))) + ) { + return -1; + } + + /* Clean the allocated memory */ + memset(ppi_ext_data, 0, sizeof(struct pp_ext_mem) * PPSI_EXT_N); + + ppi->ext_mem = ppi_ext_data; + +#if CONFIG_HAS_EXT_WR + /* Add WR extension portDS */ + if (!(ppi_ext_data[PPSI_EXT_WR].ext_dsport = + wrs_shm_alloc(ppsi_head, sizeof(struct wr_dsport))) + ) { + return -1; + } + + /* Allocate WR data extension */ + if (!(ppi_ext_data[PPSI_EXT_WR].ext_data = + wrs_shm_alloc(ppsi_head, sizeof(struct wr_data))) + ) { + return -1; + } + + /* Set WR extension hooks */ + ppi_ext_data[PPSI_EXT_WR].ext_hooks = &wr_ext_hooks; +#endif + #if CONFIG_HAS_EXT_L1SYNC -/** - * Enable the l1sync extension for a given ppsi instance - */ -static int enable_l1Sync(struct pp_instance *ppi, Boolean enable) { - if ( enable ) { + if (!(ppi_ext_data[PPSI_EXT_L1S].ext_dsport = + wrs_shm_alloc(ppsi_head, sizeof(l1e_ext_portDS_t))) + ) { + return -1; + } + + /* Allocate L1SYNC data extension */ + if (!(ppi_ext_data[PPSI_EXT_L1S].ext_data = + wrs_shm_alloc(ppsi_head,sizeof(struct l1e_data))) + ) { + return -1; + } + + /* Set L1SYNC extension hooks */ + ppi_ext_data[PPSI_EXT_L1S].ext_hooks = &l1e_ext_hooks; +#endif + + return 0; +} + +int set_extension(struct pp_instance *ppi, int extension) +{ + pp_diag(ppi, config, 3, "%s: set extension: %s (%d)\n", + __func__, lut_extension_name[extension], extension); + + switch (extension) { +#if CONFIG_HAS_EXT_WR + case PPSI_EXT_WR: + ppi->portDS->ext_dsport = ppi->ext_mem[PPSI_EXT_WR].ext_dsport; + ppi->ext_data = ppi->ext_mem[PPSI_EXT_WR].ext_data; + ppi->ext_hooks = ppi->ext_mem[PPSI_EXT_WR].ext_hooks; + ppi->protocol_extension = PPSI_EXT_WR; + break; +#endif + +#if CONFIG_HAS_EXT_L1SYNC + case PPSI_EXT_L1S: + ppi->portDS->ext_dsport = ppi->ext_mem[PPSI_EXT_L1S].ext_dsport; + ppi->ext_data = ppi->ext_mem[PPSI_EXT_L1S].ext_data; + ppi->ext_hooks = ppi->ext_mem[PPSI_EXT_L1S].ext_hooks; + ppi->protocol_extension=PPSI_EXT_L1S; - /* Add L1SYNC extension portDS */ - if ( !(ppi->portDS->ext_dsport =wrs_shm_alloc(ppsi_head, sizeof(l1e_ext_portDS_t))) ) { - return 0; - } - /* Allocate L1SYNC data extension */ - if (! (ppi->ext_data = wrs_shm_alloc(ppsi_head,sizeof(struct l1e_data))) ) { - return 0; - } - /* Set L1SYNC state. Must be done here because the init hook is called only in the initializing state. If - * the port is not connected, the initializing is then never called so the L1SYNC state is invalid (0) + /* Set L1SYNC state. Must be done here because the init hook is + * called only in the initializing state. If the port is not + * connected, the initializing is then never called so the + * L1SYNC state is invalid (0) */ - L1E_DSPOR_BS(ppi)->L1SyncState=L1SYNC_DISABLED; - L1E_DSPOR_BS(ppi)->L1SyncEnabled=TRUE; - /* Set L1SYNC extension hooks */ - ppi->ext_hooks=&l1e_ext_hooks; + L1E_DSPOR_BS(ppi)->L1SyncState = L1SYNC_DISABLED; + L1E_DSPOR_BS(ppi)->L1SyncEnabled = TRUE; + break; +#endif + + case PPSI_EXT_NONE: + ppi->portDS->ext_dsport = NULL; + ppi->ext_data = NULL; + ppi->ext_hooks = &pp_hooks; + ppi->protocol_extension = PPSI_EXT_NONE; + break; + + default: + fprintf(stderr, "ppsi: Extension not supported\n"); + return -1; + break; } - return 1; + + return 0; } + +int set_profile(struct pp_instance *ppi, int profile) +{ + + switch (profile) { + case PPSI_PROFILE_PTP : + /* Disable extension */ + if (set_extension(ppi, PPSI_EXT_NONE) < 0) { + /* Error */ + return -1; + } + + /* Do not take care of L1SYNC */ + enable_asymmetryCorrection(ppi, ppi->cfg.asymmetryCorrectionEnable); + break; + + case PPSI_PROFILE_WR : +#if CONFIG_HAS_PROFILE_WR + if (set_extension(ppi, PPSI_EXT_WR) < 0) { + /* Error */ + return -1; + } + + /* Set WR extension hooks */ + enable_asymmetryCorrection(ppi, TRUE); + +#else + fprintf(stderr, "ppsi: Profile WR not supported\n"); + return -1; +#endif /* CONFIG_HAS_PROFILE_WR */ + break; + + case PPSI_PROFILE_HA : +#if CONFIG_HAS_PROFILE_HA + if (set_extension(ppi, PPSI_EXT_L1S) < 0) { + /* Error */ + return -1; + } + + /* Force mandatory attributes - Do not take care of the configuration */ + L1E_DSPOR_BS(ppi)->rxCoherentIsRequired = TRUE; + L1E_DSPOR_BS(ppi)->txCoherentIsRequired = TRUE; + L1E_DSPOR_BS(ppi)->congruentIsRequired = TRUE; + L1E_DSPOR_BS(ppi)->L1SyncEnabled = TRUE; + L1E_DSPOR_BS(ppi)->optParamsEnabled = FALSE; + enable_asymmetryCorrection(ppi, TRUE); + + break; +#else + fprintf(stderr, "ppsi: Profile HA not supported\n"); + return -1; +#endif /* CONFIG_HAS_PROFILE_HA */ + + case PPSI_PROFILE_CUSTOM : +#if CONFIG_HAS_PROFILE_CUSTOM + if (set_extension(ppi, PPSI_EXT_NONE) < 0) { + /* Error */ + return -1; + } +#if CONFIG_HAS_EXT_L1SYNC + if (ppi->cfg.l1SyncEnabled ) { + if (set_extension(ppi, PPSI_EXT_L1S) < 0) { + /* Error */ + return -1; + } + + /* Read L1SYNC parameters */ + L1E_DSPOR_BS(ppi)->rxCoherentIsRequired = ppi->cfg.l1SyncRxCoherentIsRequired; + L1E_DSPOR_BS(ppi)->txCoherentIsRequired = ppi->cfg.l1SyncTxCoherentIsRequired; + L1E_DSPOR_BS(ppi)->congruentIsRequired = ppi->cfg.l1SyncCongruentIsRequired; + L1E_DSPOR_BS(ppi)->optParamsEnabled = ppi->cfg.l1SyncOptParamsEnabled; + if (L1E_DSPOR_BS(ppi)->optParamsEnabled) { + L1E_DSPOR_OP(ppi)->timestampsCorrectedTx = ppi->cfg.l1SyncOptParamsTimestampsCorrectedTx; + } + } +#endif /* CONFIG_HAS_EXT_L1SYNC*/ + enable_asymmetryCorrection(ppi, ppi->cfg.asymmetryCorrectionEnable); +#else + fprintf(stderr, "ppsi: Profile CUSTOM not supported\n"); + return -1; #endif + break; + + default: + fprintf(stderr, "ppsi: Not supported profile %d\n", profile); + return -1; + } + + return 0; +} /** * Enable/disable asymmetry correction @@ -264,7 +431,7 @@ int main(int argc, char **argv) /* And create your own channel, until we move to shmem too */ ppsi_ch = minipc_server_create("ptpd", 0); if (!ppsi_ch) { /* FIXME should we retry ? */ - pp_printf("ppsi: could not create minipc server"); + pp_printf("ppsi: could not create minipc server\n"); exit(1); } @@ -343,74 +510,16 @@ int main(int argc, char **argv) ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */ ppi->ptp_support=TRUE; if (ppi->portDS) { - switch (ppi->cfg.profile) { - case PPSI_PROFILE_WR : -#if CONFIG_HAS_PROFILE_WR - ppi->protocol_extension=PPSI_EXT_WR; - /* Add WR extension portDS */ - if ( !(ppi->portDS->ext_dsport = - wrs_shm_alloc(ppsi_head, sizeof(struct wr_dsport))) ) { - goto exit_out_of_memory; - } - - /* Allocate WR data extension */ - if (! (ppi->ext_data = wrs_shm_alloc(ppsi_head,sizeof(struct wr_data))) ) { - goto exit_out_of_memory; - } - /* Set WR extension hooks */ - ppi->ext_hooks=&wr_ext_hooks; - enable_asymmetryCorrection(ppi,TRUE); -#else - fprintf(stderr, "ppsi: Profile WR not supported"); - exit(1); -#endif - break; - case PPSI_PROFILE_HA : -#if CONFIG_HAS_PROFILE_HA - if ( !enable_l1Sync(ppi,TRUE) ) - goto exit_out_of_memory; - /* Force mandatory attributes - Do not take care of the configuration */ - L1E_DSPOR_BS(ppi)->rxCoherentIsRequired = TRUE; - L1E_DSPOR_BS(ppi)->txCoherentIsRequired = TRUE; - L1E_DSPOR_BS(ppi)->congruentIsRequired = TRUE; - L1E_DSPOR_BS(ppi)->L1SyncEnabled = TRUE; - L1E_DSPOR_BS(ppi)->optParamsEnabled = FALSE; - enable_asymmetryCorrection(ppi,TRUE); + if (init_extensions(ppi) < 0) + goto exit_out_of_memory; -#else - fprintf(stderr, "ppsi: Profile HA not supported"); + if (set_profile(ppi, ppi->cfg.profile) < 0) { + fprintf(stderr, + "ppsi: Profile %d not supported\n", + ppi->cfg.profile); exit(1); -#endif - break; - case PPSI_PROFILE_PTP : - /* Do not take care of L1SYNC */ - enable_asymmetryCorrection(ppi,ppi->cfg.asymmetryCorrectionEnable); - ppi->protocol_extension=PPSI_EXT_NONE; - break; - case PPSI_PROFILE_CUSTOM : -#if CONFIG_HAS_PROFILE_CUSTOM - ppi->protocol_extension=PPSI_EXT_NONE; /* can be changed ...*/ -#if CONFIG_HAS_EXT_L1SYNC - if (ppi->cfg.l1SyncEnabled ) { - if ( !enable_l1Sync(ppi,TRUE) ) - goto exit_out_of_memory; - /* Read L1SYNC parameters */ - L1E_DSPOR_BS(ppi)->rxCoherentIsRequired =ppi->cfg.l1SyncRxCoherentIsRequired; - L1E_DSPOR_BS(ppi)->txCoherentIsRequired =ppi->cfg.l1SyncTxCoherentIsRequired; - L1E_DSPOR_BS(ppi)->congruentIsRequired =ppi->cfg.l1SyncCongruentIsRequired; - L1E_DSPOR_BS(ppi)->optParamsEnabled=ppi->cfg.l1SyncOptParamsEnabled; - if ( L1E_DSPOR_BS(ppi)->optParamsEnabled ) { - L1E_DSPOR_OP(ppi)->timestampsCorrectedTx=ppi->cfg.l1SyncOptParamsTimestampsCorrectedTx; - } - } - enable_asymmetryCorrection(ppi,ppi->cfg.asymmetryCorrectionEnable); -#endif -#else - fprintf(stderr, "ppsi: Profile CUSTOM not supported"); - exit(1); -#endif - break; } + /* Parameters profile independent */ ppi->timestampCorrectionPortDS.egressLatency=picos_to_interval(ppi->cfg.egressLatency_ps); ppi->timestampCorrectionPortDS.ingressLatency=picos_to_interval(ppi->cfg.ingressLatency_ps); diff --git a/include/ppsi/pp-instance.h b/include/ppsi/pp-instance.h index a2abb66a..e480ceca 100644 --- a/include/ppsi/pp-instance.h +++ b/include/ppsi/pp-instance.h @@ -210,6 +210,13 @@ typedef enum { PP_EXSTATE_ACTIVE, /* Extension active */ PP_EXSTATE_PTP /* Extension uses only PTP protocol */ } pp_exstate_t; + +struct pp_ext_mem { + void *ext_dsport; + void *ext_data; + const struct pp_ext_hooks *ext_hooks; +}; + /* * Structure for the individual ppsi link */ @@ -294,6 +301,10 @@ struct pp_instance { Boolean bmca_execute; /* True: Ask fsm to run bmca state decision */ pp_pdstate_t pdstate; /* Protocol detection state */ pp_exstate_t extState; /* Extension state */ +#if CONFIG_ARCH_IS_WRS + /* Several extensions are supported only in WRS */ + struct pp_ext_mem *ext_mem; /* memory needed to when using several extensions */ +#endif }; /* The following things used to be bit fields. Other flags are now enums */ diff --git a/include/ppsi/ppsi.h b/include/ppsi/ppsi.h index 426499da..84fa7452 100644 --- a/include/ppsi/ppsi.h +++ b/include/ppsi/ppsi.h @@ -25,9 +25,6 @@ #include <arch/arch.h> /* ntohs and so on -- and wr-api.h for wr archs */ -/* Protocol extensions */ -#include "../proto-ext-whiterabbit/wr-api.h" -#include "../proto-ext-l1sync/l1e-api.h" /* At this point in time, we need ARRAY_SIZE to conditionally build vlan code */ #undef ARRAY_SIZE @@ -242,7 +239,7 @@ struct pp_ext_hooks { struct pp_frgn_master *frgn_master); /* Called at the end of the S1 treatment in the BMCA */ }; -#define is_ext_hook_available(p, c) ( /*p->ext_enabled && */ p->ext_hooks->c) +#define is_ext_hook_available(p, c) ( /*p->ext_enabled && */ p->ext_hooks && p->ext_hooks->c) /* * Network methods are encapsulated in a structure, so each arch only needs @@ -317,6 +314,7 @@ extern int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv); #define PPSI_EXT_NONE 0 #define PPSI_EXT_WR 1 /* WR extension */ #define PPSI_EXT_L1S 2 /* L1SYNC extension */ +#define PPSI_EXT_N 3 /* Number of extensions */ /* Define the PPSI profiles */ #define PPSI_PROFILE_PTP 0 /* Default PTP profile without extensions */ @@ -457,6 +455,10 @@ extern void pdstate_set_state_pdetection(struct pp_instance * ppi); extern void pdstate_set_state_pdetected(struct pp_instance * ppi); extern void pdstate_enable_extension(struct pp_instance * ppi); +/* Protocol extensions */ +#include "../proto-ext-whiterabbit/wr-api.h" +#include "../proto-ext-l1sync/l1e-api.h" + #include <ppsi/faults.h> #include <ppsi/timeout_prot.h> #include <ppsi/conf.h> diff --git a/proto-ext-l1sync/l1e-api.h b/proto-ext-l1sync/l1e-api.h index fe07317e..44e2c066 100644 --- a/proto-ext-l1sync/l1e-api.h +++ b/proto-ext-l1sync/l1e-api.h @@ -102,7 +102,12 @@ typedef struct { static inline l1e_ext_portDS_t *L1E_DSPOR(struct pp_instance *ppi) { - return (l1e_ext_portDS_t *) ppi->portDS->ext_dsport; +#if CONFIG_ARCH_IS_WRS + /* Several extensions are supported only in WRS */ + return ppi->ext_mem[PPSI_EXT_L1S].ext_dsport; +#else + return ppi->portDS->ext_dsport; +#endif } static inline L1SyncBasicPortDS_t *L1E_DSPOR_BS(struct pp_instance *ppi) diff --git a/proto-ext-whiterabbit/wr-api.h b/proto-ext-whiterabbit/wr-api.h index 1db46cf6..4f2157b9 100644 --- a/proto-ext-whiterabbit/wr-api.h +++ b/proto-ext-whiterabbit/wr-api.h @@ -64,7 +64,12 @@ struct wr_dsport { /* This uppercase name matches "DSPOR(ppi)" used by standard protocol */ static inline struct wr_dsport *WR_DSPOR(struct pp_instance *ppi) { +#if CONFIG_ARCH_IS_WRS + /* Several extensions are supported only in WRS */ return ppi->portDS->ext_dsport; +#else + return ppi->ext_mem[PPSI_EXT_WR].ext_dsport; +#endif } static inline Integer32 phase_to_cf_units(Integer32 phase) diff --git a/proto-standard/open-close.c b/proto-standard/open-close.c index bf0d210e..5790abdb 100644 --- a/proto-standard/open-close.c +++ b/proto-standard/open-close.c @@ -176,10 +176,21 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts) for (i = 0; i < get_numberPorts(def); i++) { struct pp_instance *ppi = INST(ppg, i); int r; - - if (is_ext_hook_available(ppi,open)) { - ret=(r=ppi->ext_hooks->open(ppi, rt_opts))==0 ? ret : r; + int ext; +#if CONFIG_ARCH_IS_WRS + /* Several extensions are supported only in WRS */ + for (ext = 0; ext < PPSI_EXT_N; ext++) { + if (ppi->ext_mem[ext].ext_hooks && ppi->ext_mem[ext].ext_hooks->open) { + r = ppi->ext_mem[ext].ext_hooks->open(ppi, rt_opts); + ret = (r == 0) ? ret : r; + } } +#else + if (is_ext_hook_available(ppi, open)) { + r = ppi->ext_hooks->open(ppi, rt_opts); + ret = (r == 0) ? ret : r; + } +#endif } return ret; } diff --git a/tools/ppsi_conf.c b/tools/ppsi_conf.c index 4a371f19..e9751fc3 100644 --- a/tools/ppsi_conf.c +++ b/tools/ppsi_conf.c @@ -30,6 +30,7 @@ enum input_arg { arg_delay_req_interval, arg_diags, arg_diags_inst, + arg_extension, arg_instance, arg_port, arg_prio1, @@ -45,6 +46,7 @@ static struct option long_opts[] = { {"delay-req-interval", required_argument, NULL, arg_delay_req_interval}, {"diags", required_argument, NULL, arg_diags}, {"diags-inst", required_argument, NULL, arg_diags_inst}, + {"extension", required_argument, NULL, arg_extension}, {"instance", required_argument, NULL, arg_instance}, {"ppi", required_argument, NULL, arg_instance}, {"port", required_argument, NULL, arg_port}, @@ -91,6 +93,8 @@ void help(char *prgname) " --diags-inst=<num>\n" " - change PPSI's instance/port diagnostics to <num>\n" " order: FSM, Time, Frames, Servo, BMC, Extension, Configuration\n" + " --extension=<none|wr|l1s|l1sync>\n" + " - sets the extension; extension has to be supported by a selected profile\n" " --sync-interval=<num>\n" " - sets logarithm to the base 2 of the mean interval of sync\n" " message transmission; used when a port is in Master state\n" @@ -204,6 +208,7 @@ int main(int argc, char *argv[]) { int opt; int tmp; + char *tmp_str; int ret; int ppsi_instance = -1; int ppsi_port = -1; @@ -318,6 +323,48 @@ int main(int argc, char *argv[]) } break; + case arg_extension: + /* Check if an instance is set. If not exit. */ + check_instance(ppsi_instance); + if (!strcmp(optarg, "none") || !strcmp(optarg, "0")) { + tmp = PPSIEXP_PARAM_EXTENSION_NONE; + tmp_str = "none"; + } else if (!strcmp(optarg, "wr") || !strcmp(optarg, "1")) { + tmp = PPSIEXP_PARAM_EXTENSION_WR; + tmp_str = "wr"; + } else if (!strcmp(optarg, "l1s") + || !strcmp(optarg, "l1sync") + || !strcmp(optarg, "2")) { + tmp = PPSIEXP_PARAM_EXTENSION_L1SYNC; + tmp_str = "l1sync"; + } else { + fprintf(stderr, "Error setting extension for %s" + " %d to %s, wrong value\n", + ppsi_port == -1 ? "instance" : "port", + ppsi_instance & ~PPSI_INSTANCE_USE_PORT, + optarg); + exit (1); + } + + if (verbose) + printf("Setting extension for %s %d to %s\n", + ppsi_port == -1 ? "instance" : "port", + ppsi_instance & ~PPSI_INSTANCE_USE_PORT, + tmp_str); + ret = ppsi_set_param_instance( + PPSIEXP_PARAM_INST_EXTENSION_CMD, + ppsi_instance, + tmp); + if (ret) { + fprintf(stderr, "Error setting extension for %s" + " %d to %s, ret %d\n", + ppsi_port == -1 ? "instance" : "port", + ppsi_instance & ~PPSI_INSTANCE_USE_PORT, + tmp_str, ret); + exit (1); + } + break; + case arg_instance: ppsi_instance = atoi(optarg); if (ppsi_instance == 0 && strcmp("0", optarg) diff --git a/tools/wrs_dump_shmem_ppsi.c b/tools/wrs_dump_shmem_ppsi.c index 97b02827..60554cd3 100644 --- a/tools/wrs_dump_shmem_ppsi.c +++ b/tools/wrs_dump_shmem_ppsi.c @@ -239,6 +239,7 @@ struct dump_info ppi_info [] = { DUMP_FIELD(pp_pdstate,pdstate), DUMP_FIELD(pointer, arch_inst_data), DUMP_FIELD(pointer, ext_data), + DUMP_FIELD(pointer, ext_mem), DUMP_FIELD(protocol_extension, protocol_extension), DUMP_FIELD(pointer, ext_hooks), DUMP_FIELD(pointer, servo), /* FIXME: follow this */ -- GitLab