forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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++;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user