diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2016-03-22 15:51:13 +0100 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2017-03-06 07:54:55 +0100 |
commit | ac7da5bcb00abcd2f424118fdabe231cf5520d00 (patch) | |
tree | 8f6b3008788381807f958f1891f411bd14632bce | |
parent | leon, grspw_pkt: added link_ctrl options (diff) | |
download | rtems-ac7da5bcb00abcd2f424118fdabe231cf5520d00.tar.bz2 |
leon, grspw_pkt: Manual handling of link status events
Added functionality for manual handling of link status events,
configurable via grspw_link_ctrl.
Added statistics counter for disconnect error.
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h | 12 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c | 17 |
2 files changed, 26 insertions, 3 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h b/c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h index ea0ae9ae40..17bbee8038 100644 --- a/c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h +++ b/c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h @@ -184,6 +184,7 @@ struct grspw_core_stats { int err_eeop; int err_addr; int err_parity; + int err_disconnect; int err_escape; int err_wsync; /* only in GRSPW1 */ }; @@ -216,6 +217,15 @@ struct grspw_core_stats { * channels. */ +#define LINKSTS_CE 0x002 /* Credit error */ +#define LINKSTS_ER 0x004 /* Escape error */ +#define LINKSTS_DE 0x008 /* Disconnect error */ +#define LINKSTS_PE 0x010 /* Parity error */ +#define LINKSTS_WE 0x040 /* Write synchonization error (GRSPW1 only) */ +#define LINKSTS_IA 0x080 /* Invalid address */ +#define LINKSTS_EE 0x100 /* Early EOP/EEP */ +#define LINKSTS_MASK 0x1de + /* grspw_tc_ctrl() options */ #define TCOPTS_EN_RXIRQ 0x0001 /* Tick-Out IRQ */ @@ -325,7 +335,7 @@ extern spw_link_state_t grspw_link_state(void *d); * bits 7..0 : Clock Div RUN (only run-state) * bits 15..8 : Clock Div During Startup (all link states except run-state) */ -extern void grspw_link_ctrl(void *d, int *options, int *clkdiv); +extern void grspw_link_ctrl(void *d, int *options, int *stscfg, int *clkdiv); /* Read the current value of the status register */ extern unsigned int grspw_link_status(void *d); /* Clear bits in the status register */ diff --git a/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c b/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c index 1827fbd744..22fcda3724 100644 --- a/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c +++ b/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c @@ -472,6 +472,9 @@ struct grspw_priv { /* Bit mask representing events which shall cause link disable. */ unsigned int dis_link_on_err; + /* Bit mask for link status bits to clear by ISR */ + unsigned int stscfg; + /* "Core Global" Statistics gathered, not dependent on DMA channel */ struct grspw_core_stats stats; }; @@ -538,6 +541,7 @@ void *grspw_open(int dev_no) priv->tcisr_arg = NULL; priv->icisr = NULL; priv->icisr_arg = NULL; + priv->stscfg = LINKSTS_MASK; grspw_stats_clr(priv); @@ -745,7 +749,7 @@ static inline int grspw_is_irqsource_set(unsigned int ctrl, unsigned int icctrl) /* options and clkdiv [in/out]: set to -1 to only read current config */ -void grspw_link_ctrl(void *d, int *options, int *clkdiv) +void grspw_link_ctrl(void *d, int *options, int *stscfg, int *clkdiv) { struct grspw_priv *priv = d; struct grspw_regs *regs = priv->regs; @@ -782,6 +786,12 @@ void grspw_link_ctrl(void *d, int *options, int *clkdiv) SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); *options = (ctrl & GRSPW_LINK_CFG) | priv->dis_link_on_err; } + if (stscfg) { + if (*stscfg != -1) { + priv->stscfg = *stscfg & LINKSTS_MASK; + } + *stscfg = priv->stscfg; + } } /* Generate Tick-In (increment Time Counter, Send Time Code) */ @@ -2494,7 +2504,7 @@ STATIC void grspw_isr(void *data) /* Get Status from Hardware */ stat = REG_READ(&priv->regs->status); - stat_clrmsk = stat & (GRSPW_STS_TO | GRSPW_STAT_ERROR); + stat_clrmsk = stat & (GRSPW_STS_TO | GRSPW_STAT_ERROR) & priv->stscfg; /* Make sure to put the timecode handling first in order to get the * smallest possible interrupt latency @@ -2550,6 +2560,9 @@ STATIC void grspw_isr(void *data) if (stat & GRSPW_STS_PE) priv->stats.err_parity++; + if (stat & GRSPW_STS_DE) + priv->stats.err_disconnect++; + if (stat & GRSPW_STS_ER) priv->stats.err_escape++; |