octeontx2-af: recover CPT engine when it gets fault
When CPT engine has uncorrectable errors, it will get halted and must be disabled and re-enabled. This patch adds code for the same. Signed-off-by: Srujana Challa <schalla@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6c977c5c2e
commit
07ea567d84
@ -37,34 +37,60 @@
|
||||
(_rsp)->free_sts_##etype = free_sts; \
|
||||
})
|
||||
|
||||
static irqreturn_t rvu_cpt_af_flt_intr_handler(int irq, void *ptr)
|
||||
static irqreturn_t cpt_af_flt_intr_handler(int vec, void *ptr)
|
||||
{
|
||||
struct rvu_block *block = ptr;
|
||||
struct rvu *rvu = block->rvu;
|
||||
int blkaddr = block->addr;
|
||||
u64 reg0, reg1, reg2;
|
||||
u64 reg, val;
|
||||
int i, eng;
|
||||
u8 grp;
|
||||
|
||||
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0));
|
||||
reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1));
|
||||
if (!is_rvu_otx2(rvu)) {
|
||||
reg2 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(2));
|
||||
dev_err_ratelimited(rvu->dev,
|
||||
"Received CPTAF FLT irq : 0x%llx, 0x%llx, 0x%llx",
|
||||
reg0, reg1, reg2);
|
||||
} else {
|
||||
dev_err_ratelimited(rvu->dev,
|
||||
"Received CPTAF FLT irq : 0x%llx, 0x%llx",
|
||||
reg0, reg1);
|
||||
reg = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(vec));
|
||||
dev_err_ratelimited(rvu->dev, "Received CPTAF FLT%d irq : 0x%llx", vec, reg);
|
||||
|
||||
i = -1;
|
||||
while ((i = find_next_bit((unsigned long *)®, 64, i + 1)) < 64) {
|
||||
switch (vec) {
|
||||
case 0:
|
||||
eng = i;
|
||||
break;
|
||||
case 1:
|
||||
eng = i + 64;
|
||||
break;
|
||||
case 2:
|
||||
eng = i + 128;
|
||||
break;
|
||||
}
|
||||
grp = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng)) & 0xFF;
|
||||
/* Disable and enable the engine which triggers fault */
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), 0x0);
|
||||
val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng));
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val & ~1ULL);
|
||||
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), grp);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val | 1ULL);
|
||||
}
|
||||
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(0), reg0);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(1), reg1);
|
||||
if (!is_rvu_otx2(rvu))
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(2), reg2);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(vec), reg);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t rvu_cpt_af_flt0_intr_handler(int irq, void *ptr)
|
||||
{
|
||||
return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT0, ptr);
|
||||
}
|
||||
|
||||
static irqreturn_t rvu_cpt_af_flt1_intr_handler(int irq, void *ptr)
|
||||
{
|
||||
return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT1, ptr);
|
||||
}
|
||||
|
||||
static irqreturn_t rvu_cpt_af_flt2_intr_handler(int irq, void *ptr)
|
||||
{
|
||||
return cpt_af_flt_intr_handler(CPT_10K_AF_INT_VEC_FLT2, ptr);
|
||||
}
|
||||
|
||||
static irqreturn_t rvu_cpt_af_rvu_intr_handler(int irq, void *ptr)
|
||||
{
|
||||
struct rvu_block *block = ptr;
|
||||
@ -119,8 +145,10 @@ static void cpt_10k_unregister_interrupts(struct rvu_block *block, int off)
|
||||
int i;
|
||||
|
||||
/* Disable all CPT AF interrupts */
|
||||
for (i = 0; i < CPT_10K_AF_INT_VEC_RVU; i++)
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(0), ~0ULL);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(1), ~0ULL);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(2), 0xFFFF);
|
||||
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1);
|
||||
|
||||
@ -151,7 +179,7 @@ static void cpt_unregister_interrupts(struct rvu *rvu, int blkaddr)
|
||||
|
||||
/* Disable all CPT AF interrupts */
|
||||
for (i = 0; i < CPT_AF_INT_VEC_RVU; i++)
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), ~0ULL);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1);
|
||||
|
||||
@ -172,16 +200,31 @@ static int cpt_10k_register_interrupts(struct rvu_block *block, int off)
|
||||
{
|
||||
struct rvu *rvu = block->rvu;
|
||||
int blkaddr = block->addr;
|
||||
irq_handler_t flt_fn;
|
||||
int i, ret;
|
||||
|
||||
for (i = CPT_10K_AF_INT_VEC_FLT0; i < CPT_10K_AF_INT_VEC_RVU; i++) {
|
||||
sprintf(&rvu->irq_name[(off + i) * NAME_SIZE], "CPTAF FLT%d", i);
|
||||
|
||||
switch (i) {
|
||||
case CPT_10K_AF_INT_VEC_FLT0:
|
||||
flt_fn = rvu_cpt_af_flt0_intr_handler;
|
||||
break;
|
||||
case CPT_10K_AF_INT_VEC_FLT1:
|
||||
flt_fn = rvu_cpt_af_flt1_intr_handler;
|
||||
break;
|
||||
case CPT_10K_AF_INT_VEC_FLT2:
|
||||
flt_fn = rvu_cpt_af_flt2_intr_handler;
|
||||
break;
|
||||
}
|
||||
ret = rvu_cpt_do_register_interrupt(block, off + i,
|
||||
rvu_cpt_af_flt_intr_handler,
|
||||
&rvu->irq_name[(off + i) * NAME_SIZE]);
|
||||
flt_fn, &rvu->irq_name[(off + i) * NAME_SIZE]);
|
||||
if (ret)
|
||||
goto err;
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1);
|
||||
if (i == CPT_10K_AF_INT_VEC_FLT2)
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0xFFFF);
|
||||
else
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL);
|
||||
}
|
||||
|
||||
ret = rvu_cpt_do_register_interrupt(block, off + CPT_10K_AF_INT_VEC_RVU,
|
||||
@ -208,8 +251,8 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr)
|
||||
{
|
||||
struct rvu_hwinfo *hw = rvu->hw;
|
||||
struct rvu_block *block;
|
||||
irq_handler_t flt_fn;
|
||||
int i, offs, ret = 0;
|
||||
char irq_name[16];
|
||||
|
||||
if (!is_block_implemented(rvu->hw, blkaddr))
|
||||
return 0;
|
||||
@ -226,13 +269,20 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr)
|
||||
return cpt_10k_register_interrupts(block, offs);
|
||||
|
||||
for (i = CPT_AF_INT_VEC_FLT0; i < CPT_AF_INT_VEC_RVU; i++) {
|
||||
snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i);
|
||||
sprintf(&rvu->irq_name[(offs + i) * NAME_SIZE], "CPTAF FLT%d", i);
|
||||
switch (i) {
|
||||
case CPT_AF_INT_VEC_FLT0:
|
||||
flt_fn = rvu_cpt_af_flt0_intr_handler;
|
||||
break;
|
||||
case CPT_AF_INT_VEC_FLT1:
|
||||
flt_fn = rvu_cpt_af_flt1_intr_handler;
|
||||
break;
|
||||
}
|
||||
ret = rvu_cpt_do_register_interrupt(block, offs + i,
|
||||
rvu_cpt_af_flt_intr_handler,
|
||||
irq_name);
|
||||
flt_fn, &rvu->irq_name[(offs + i) * NAME_SIZE]);
|
||||
if (ret)
|
||||
goto err;
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1);
|
||||
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL);
|
||||
}
|
||||
|
||||
ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RVU,
|
||||
|
Loading…
x
Reference in New Issue
Block a user