Commit 62e0a991 authored by Maciej Lipinski's avatar Maciej Lipinski Committed by Adam Wujek

wrpc_diags: added writing of WRPC diagnostics to dedicated WB registers

this is a software part of new (additional) diagnostics for WR PTP Core.
It allows to access diagnostics values through WB registers (e.g. PCI
bus). This is useful for integration of WR with CERN cotrols infrastructure,
such as FESA. It allows the host machine (of SPEC/SVEC/etc) to easily
access information about the health of WR PTP Core.
parent c00a228c
......@@ -246,6 +246,20 @@ config VLAN_FOR_CLASS6
depends on VLAN
int "Route this VLAN too to fabric class 6 (Streamer/NIC)"
config WR_DIAG
depends on WR_NODE
boolean "Write of WRPC diagnostics to dedicated WB registers"
default n
help
This is a software part of new (additional) diagnostics for WR PTP
Core. It allows to access diagnostics values through WB registers
(e.g. PCI bus). It allows the host machine (of SPEC/SVEC/etc.) to
easily access information about the health of WR PTP Core.
Please note that other option to access the status of WRPC, which
is direct access to the WRPC's memory does not provide any mechanism
to ensure the data consistency.
config WR_NODE_SIM
depends on WR_NODE && !HOST_PROCESS
boolean "Build simple software for test of WR PTP Core in simulation"
......@@ -257,7 +271,6 @@ config WR_NODE_SIM
is avoided. The main function sends min-size frames to PTP
MAC address destination and expects the simulation to return
these frames.
#
# This is a set of configuration options that should not be changed by
# normal users. If the "developer" menu is used, the binary is tainted.
......
......@@ -41,6 +41,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -39,6 +39,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -39,6 +39,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -39,6 +39,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -39,6 +39,7 @@ CONFIG_FLASH_INIT=y
CONFIG_AUX_DIAG=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -33,6 +33,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -35,6 +35,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -36,6 +36,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
CONFIG_WR_NODE_SIM=y
#
......
......@@ -110,3 +110,79 @@ void net_rst(void)
syscon->GPSR |= SYSC_GPSR_NET_RST;
}
int wdiag_set_valid(int enable)
{
if(enable)
syscon->WDIAG_CTRL |= SYSC_WDIAG_CTRL_DATA_VALID;
if(!enable)
syscon->WDIAG_CTRL &= ~SYSC_WDIAG_CTRL_DATA_VALID;
return (int)(syscon->WDIAG_CTRL & SYSC_WDIAG_CTRL_DATA_VALID);
}
int wdiag_get_valid(void)
{
if(syscon->WDIAG_CTRL & SYSC_WDIAG_CTRL_DATA_VALID)
return 1;
else
return 0;
}
int wdiag_get_snapshot(void)
{
if(syscon->WDIAG_CTRL & SYSC_WDIAG_CTRL_DATA_SNAPSHOT)
return 1;
else
return 0;
}
void wdiags_write_servo_state(int wr_mode, uint8_t servostate, uint64_t mu,
uint64_t dms, int32_t asym, int32_t cko, int32_t setp,
int32_t ucnt)
{
syscon->WDIAG_SSTAT = wr_mode ? SYSC_WDIAG_SSTAT_WR_MODE:0;
syscon->WDIAG_SSTAT |= SYSC_WDIAG_SSTAT_SERVOSTATE_W(servostate);
syscon->WDIAG_MU_MSB = 0xFFFFFFFF & (mu>>32);
syscon->WDIAG_MU_LSB = 0xFFFFFFFF & mu;
syscon->WDIAG_DMS_MSB = 0xFFFFFFFF & (dms>>32);
syscon->WDIAG_DMS_LSB = 0xFFFFFFFF & dms;
syscon->WDIAG_ASYM = asym;
syscon->WDIAG_CKO = cko;
syscon->WDIAG_SETP = setp;
syscon->WDIAG_UCNT = ucnt;
}
void wdiags_write_port_state(int link, int locked)
{
uint32_t val = 0;
val = link ? SYSC_WDIAG_PSTAT_LINK : 0;
val |= locked ? SYSC_WDIAG_PSTAT_LOCKED : 0;
syscon->WDIAG_PSTAT = val;
}
void wdiags_write_ptp_state(uint8_t ptpstate)
{
syscon->WDIAG_PTPSTAT = SYSC_WDIAG_PTPSTAT_PTPSTATE_W(ptpstate);
}
void wdiags_write_aux_state(uint32_t aux_states)
{
syscon->WDIAG_ASTAT = SYSC_WDIAG_ASTAT_AUX_W(aux_states);
}
void wdiags_write_cnts(uint32_t tx, uint32_t rx)
{
syscon->WDIAG_TXFCNT = tx;
syscon->WDIAG_RXFCNT = rx;
}
void wdiags_write_time(uint64_t sec, uint32_t nsec)
{
syscon->WDIAG_SEC_MSB = 0xFFFFFFFF & (sec>>32);
syscon->WDIAG_SEC_LSB = 0xFFFFFFFF & sec;
syscon->WDIAG_NS = nsec;
}
void wdiags_write_temp(uint32_t temp)
{
syscon->WDIAG_TEMP=temp;
}
......@@ -3,7 +3,7 @@
* File : wrc_syscon_regs.h
* Author : auto-generated by wbgen2 from wrc_syscon_wb.wb
* Created : Mon Jul 11 14:59:51 2016
* Created : Mon Apr 24 17:41:58 2017
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb
......@@ -14,7 +14,11 @@
#ifndef __WBGEN2_REGDEFS_WRC_SYSCON_WB_WB
#define __WBGEN2_REGDEFS_WRC_SYSCON_WB_WB
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <inttypes.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
......@@ -176,6 +180,77 @@
#define SYSC_DIAG_CR_RW WBGEN2_GEN_MASK(31, 1)
/* definitions for register: User Diag: data to read/write */
/* definitions for register: WRPC Diag: ctrl */
/* definitions for field: WR DIAG data valid in reg: WRPC Diag: ctrl */
#define SYSC_WDIAG_CTRL_DATA_VALID WBGEN2_GEN_MASK(0, 1)
/* definitions for field: WR DIAG data snapshot in reg: WRPC Diag: ctrl */
#define SYSC_WDIAG_CTRL_DATA_SNAPSHOT WBGEN2_GEN_MASK(8, 1)
/* definitions for register: WRPC Diag: servo status */
/* definitions for field: WR valid in reg: WRPC Diag: servo status */
#define SYSC_WDIAG_SSTAT_WR_MODE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Servo State in reg: WRPC Diag: servo status */
#define SYSC_WDIAG_SSTAT_SERVOSTATE_MASK WBGEN2_GEN_MASK(8, 4)
#define SYSC_WDIAG_SSTAT_SERVOSTATE_SHIFT 8
#define SYSC_WDIAG_SSTAT_SERVOSTATE_W(value) WBGEN2_GEN_WRITE(value, 8, 4)
#define SYSC_WDIAG_SSTAT_SERVOSTATE_R(reg) WBGEN2_GEN_READ(reg, 8, 4)
/* definitions for register: WRPC Diag: Port status */
/* definitions for field: Link Status in reg: WRPC Diag: Port status */
#define SYSC_WDIAG_PSTAT_LINK WBGEN2_GEN_MASK(0, 1)
/* definitions for field: PLL Locked in reg: WRPC Diag: Port status */
#define SYSC_WDIAG_PSTAT_LOCKED WBGEN2_GEN_MASK(1, 1)
/* definitions for register: WRPC Diag: PTP state */
/* definitions for field: PTP State in reg: WRPC Diag: PTP state */
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_MASK WBGEN2_GEN_MASK(0, 8)
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_SHIFT 0
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: WRPC Diag: AUX state */
/* definitions for field: AUX channel in reg: WRPC Diag: AUX state */
#define SYSC_WDIAG_ASTAT_AUX_MASK WBGEN2_GEN_MASK(0, 8)
#define SYSC_WDIAG_ASTAT_AUX_SHIFT 0
#define SYSC_WDIAG_ASTAT_AUX_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define SYSC_WDIAG_ASTAT_AUX_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: WRPC Diag: Tx PTP Frame cnts */
/* definitions for register: WRPC Diag: Rx PTP Frame cnts */
/* definitions for register: WRPC Diag:local time [msb of s] */
/* definitions for register: WRPC Diag: local time [lsb of s] */
/* definitions for register: WRPC Diag: local time [ns] */
/* definitions for register: WRPC Diag: Round trip (mu) [msb of ps] */
/* definitions for register: WRPC Diag: Round trip (mu) [lsb of ps] */
/* definitions for register: WRPC Diag: Master-slave delay (dms) [msb of ps] */
/* definitions for register: WRPC Diag: Master-slave delay (dms) [lsb of ps] */
/* definitions for register: WRPC Diag: Total link asymmetry [ps] */
/* definitions for register: WRPC Diag: Clock offset (cko) [ps] */
/* definitions for register: WRPC Diag: Phase setpoint (setp) [ps] */
/* definitions for register: WRPC Diag: Update counter (ucnt) */
/* definitions for register: WRPC Diag: Board temperature [C degree] */
/* [0x0]: REG Syscon reset register */
#define SYSC_REG_RSTR 0x00000000
/* [0x4]: REG GPIO Set/Readback Register */
......@@ -196,4 +271,42 @@
#define SYSC_REG_DIAG_CR 0x00000020
/* [0x24]: REG User Diag: data to read/write */
#define SYSC_REG_DIAG_DAT 0x00000024
/* [0x28]: REG WRPC Diag: ctrl */
#define SYSC_REG_WDIAG_CTRL 0x00000028
/* [0x2c]: REG WRPC Diag: servo status */
#define SYSC_REG_WDIAG_SSTAT 0x0000002c
/* [0x30]: REG WRPC Diag: Port status */
#define SYSC_REG_WDIAG_PSTAT 0x00000030
/* [0x34]: REG WRPC Diag: PTP state */
#define SYSC_REG_WDIAG_PTPSTAT 0x00000034
/* [0x38]: REG WRPC Diag: AUX state */
#define SYSC_REG_WDIAG_ASTAT 0x00000038
/* [0x3c]: REG WRPC Diag: Tx PTP Frame cnts */
#define SYSC_REG_WDIAG_TXFCNT 0x0000003c
/* [0x40]: REG WRPC Diag: Rx PTP Frame cnts */
#define SYSC_REG_WDIAG_RXFCNT 0x00000040
/* [0x44]: REG WRPC Diag:local time [msb of s] */
#define SYSC_REG_WDIAG_SEC_MSB 0x00000044
/* [0x48]: REG WRPC Diag: local time [lsb of s] */
#define SYSC_REG_WDIAG_SEC_LSB 0x00000048
/* [0x4c]: REG WRPC Diag: local time [ns] */
#define SYSC_REG_WDIAG_NS 0x0000004c
/* [0x50]: REG WRPC Diag: Round trip (mu) [msb of ps] */
#define SYSC_REG_WDIAG_MU_MSB 0x00000050
/* [0x54]: REG WRPC Diag: Round trip (mu) [lsb of ps] */
#define SYSC_REG_WDIAG_MU_LSB 0x00000054
/* [0x58]: REG WRPC Diag: Master-slave delay (dms) [msb of ps] */
#define SYSC_REG_WDIAG_DMS_MSB 0x00000058
/* [0x5c]: REG WRPC Diag: Master-slave delay (dms) [lsb of ps] */
#define SYSC_REG_WDIAG_DMS_LSB 0x0000005c
/* [0x60]: REG WRPC Diag: Total link asymmetry [ps] */
#define SYSC_REG_WDIAG_ASYM 0x00000060
/* [0x64]: REG WRPC Diag: Clock offset (cko) [ps] */
#define SYSC_REG_WDIAG_CKO 0x00000064
/* [0x68]: REG WRPC Diag: Phase setpoint (setp) [ps] */
#define SYSC_REG_WDIAG_SETP 0x00000068
/* [0x6c]: REG WRPC Diag: Update counter (ucnt) */
#define SYSC_REG_WDIAG_UCNT 0x0000006c
/* [0x70]: REG WRPC Diag: Board temperature [C degree] */
#define SYSC_REG_WDIAG_TEMP 0x00000070
#endif
......@@ -55,6 +55,25 @@ struct SYSCON_WB {
uint32_t DIAG_NW;
uint32_t DIAG_CR;
uint32_t DIAG_DAT;
uint32_t WDIAG_CTRL;
uint32_t WDIAG_SSTAT;
uint32_t WDIAG_PSTAT;
uint32_t WDIAG_PTPSTAT;
uint32_t WDIAG_ASTAT;
uint32_t WDIAG_TXFCNT;
uint32_t WDIAG_RXFCNT;
uint32_t WDIAG_SEC_MSB;
uint32_t WDIAG_SEC_LSB;
uint32_t WDIAG_NS;
uint32_t WDIAG_MU_MSB;
uint32_t WDIAG_MU_LSB;
uint32_t WDIAG_DMS_MSB;
uint32_t WDIAG_DMS_LSB;
uint32_t WDIAG_ASYM;
uint32_t WDIAG_CKO;
uint32_t WDIAG_SETP;
uint32_t WDIAG_UCNT;
uint32_t WDIAG_TEMP;
};
/*GPIO pins*/
......@@ -113,5 +132,18 @@ int diag_write_word(uint32_t adr, uint32_t val);
void net_rst(void);
int wdiag_set_valid(int enable);
int wdiag_get_valid(void);
int wdiag_get_snapshot(void);
void wdiags_write_servo_state(int wr_mode, uint8_t servostate, uint64_t mu,
uint64_t dms, int32_t asym, int32_t cko, int32_t setp,
int32_t ucnt);
void wdiags_write_port_state(int link, int locked);
void wdiags_write_ptp_state(uint8_t ptpstate);
void wdiags_write_aux_state(uint32_t aux_states);
void wdiags_write_cnts(uint32_t tx, uint32_t rx);
void wdiags_write_time(uint64_t sec, uint32_t nsec);
void wdiags_write_temp(uint32_t temp);
#endif /* CONFIG_WR_NODE */
#endif
......@@ -25,12 +25,15 @@
#include "shell.h"
#include "revision.h"
#define WRC_DIAG_REFRESH_PERIOD (1 * TICS_PER_SECOND)
extern struct pp_servo servo;
extern struct pp_instance ppi_static;
struct pp_instance *ppi = &ppi_static;
const char *ptp_unknown_str= "unknown";
static void wrc_mon_std_servo(void);
int wrc_wr_diags(void);
#define PRINT64_FACTOR 1000000000LL
static char* print64(uint64_t x, int align)
......@@ -383,7 +386,120 @@ static int wrc_log_stats(void)
return 1;
}
DEFINE_WRC_TASK(stats) = {
.name = "stats",
.job = wrc_log_stats,
};
int wrc_wr_diags(void)
{
struct hal_port_state ps;
static uint32_t last_jiffies;
int tx, rx;
uint64_t sec;
uint32_t nsec;
int n_out;
uint32_t aux_stat=0;
int temp=0, valid=0, snapshot=0,i;
valid = wdiag_get_valid();
snapshot = wdiag_get_snapshot();
/* if the data is snapshot and there is already valid data, do not
* refresh */
if(valid & snapshot)
return 0;
/* ***************** lock data from reading by user **************** */
if (!last_jiffies)
last_jiffies = timer_get_tics() - 1 - WRC_DIAG_REFRESH_PERIOD;
/* stats update condition */
if (time_before(timer_get_tics(), last_jiffies + WRC_DIAG_REFRESH_PERIOD))
return 0;
last_jiffies = timer_get_tics();
/* ***************** lock data from reading by user **************** */
wdiag_set_valid(0);
/* frame statistics */
minic_get_stats(&tx, &rx);
wdiags_write_cnts(tx,rx);
/* local time */
shw_pps_gen_get_time(&sec, &nsec);
wdiags_write_time(sec, nsec);
/* port state (from hal) */
wrpc_get_port_state(&ps, NULL);
wdiags_write_port_state((ps.state ? 1 : 0), (ps.locked ? 1 : 0));
/* port PTP State (from ppsi)
* see:
ppsi/proto-ext-whiterabbit/wr-constants.h
ppsi/include/ppsi/ieee1588_types.h
0 : none
1 : PPS_INITIALIZING
2 : PPS_FAULTY
3 : PPS_DISABLED
4 : PPS_LISTENING
5 : PPS_PRE_MASTER
6 : PPS_MASTER
7 : PPS_PASSIVE
8 : PPS_UNCALIBRATED
9 : PPS_SLAVE
100: WRS_PRESENT
101: WRS_S_LOCK
102: WRS_M_LOCK
103: WRS_LOCKED
104, 108-116:WRS_CALIBRATION
105: WRS_CALIBRATED
106: WRS_RESP_CALIB_REQ
107: WRS_WR_LINK_ON
*/
wdiags_write_ptp_state((uint8_t )ppi->state);
/* servo state (if slave)s */
if(ptp_mode == WRC_MODE_SLAVE){
struct wr_servo_state *ss =
&((struct wr_data *)ppi->ext_data)->servo_state;
int32_t asym = (int32_t)(ss->picos_mu-2LL * ss->delta_ms);
int wr_mode = (ss->flags & WR_FLAG_VALID) ? 1 : 0;
int servostate = ss->state;
/* see ppsi/proto-ext-whiterabbit/wr-constants.c:
0: WR_UNINITIALIZED = 0,
1: WR_SYNC_NSEC,
2: WR_SYNC_TAI,
3: WR_SYNC_PHASE,
4: WR_TRACK_PHASE,
5: WR_WAIT_OFFSET_STABLE */
wdiags_write_servo_state(wr_mode, servostate, ss->picos_mu,
ss->delta_ms, asym, ss->offset,
ss->cur_setpoint,ss->update_count);
}
/* auxiliar channels (if any) */
spll_get_num_channels(NULL, &n_out);
if (n_out > 8) n_out = 8; /* hardware limit. */
for(i = 0; i < n_out; i++) {
aux_stat |= (0x1 & spll_get_aux_status(i)) << i;
}
wdiags_write_aux_state(aux_stat);
/* temperature */
temp = wrc_temp_get("pcb");
wdiags_write_temp(temp);
/* **************** unlock data from reading by user ************** */
wdiag_set_valid(1);
return 1;
}
#ifdef CONFIG_WR_DIAG
DEFINE_WRC_TASK(diags) = {
.name = "diags",
.job = wrc_wr_diags,
};
#endif
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