Skip to content

Commit 07ea567

Browse files
SruChalladavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6c977c5 commit 07ea567

File tree

1 file changed

+80
-30
lines changed
  • drivers/net/ethernet/marvell/octeontx2/af

1 file changed

+80
-30
lines changed

drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,60 @@
3737
(_rsp)->free_sts_##etype = free_sts; \
3838
})
3939

40-
static irqreturn_t rvu_cpt_af_flt_intr_handler(int irq, void *ptr)
40+
static irqreturn_t cpt_af_flt_intr_handler(int vec, void *ptr)
4141
{
4242
struct rvu_block *block = ptr;
4343
struct rvu *rvu = block->rvu;
4444
int blkaddr = block->addr;
45-
u64 reg0, reg1, reg2;
46-
47-
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0));
48-
reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1));
49-
if (!is_rvu_otx2(rvu)) {
50-
reg2 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(2));
51-
dev_err_ratelimited(rvu->dev,
52-
"Received CPTAF FLT irq : 0x%llx, 0x%llx, 0x%llx",
53-
reg0, reg1, reg2);
54-
} else {
55-
dev_err_ratelimited(rvu->dev,
56-
"Received CPTAF FLT irq : 0x%llx, 0x%llx",
57-
reg0, reg1);
45+
u64 reg, val;
46+
int i, eng;
47+
u8 grp;
48+
49+
reg = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(vec));
50+
dev_err_ratelimited(rvu->dev, "Received CPTAF FLT%d irq : 0x%llx", vec, reg);
51+
52+
i = -1;
53+
while ((i = find_next_bit((unsigned long *)&reg, 64, i + 1)) < 64) {
54+
switch (vec) {
55+
case 0:
56+
eng = i;
57+
break;
58+
case 1:
59+
eng = i + 64;
60+
break;
61+
case 2:
62+
eng = i + 128;
63+
break;
64+
}
65+
grp = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng)) & 0xFF;
66+
/* Disable and enable the engine which triggers fault */
67+
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), 0x0);
68+
val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng));
69+
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val & ~1ULL);
70+
71+
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), grp);
72+
rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val | 1ULL);
5873
}
59-
60-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(0), reg0);
61-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(1), reg1);
62-
if (!is_rvu_otx2(rvu))
63-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(2), reg2);
74+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(vec), reg);
6475

6576
return IRQ_HANDLED;
6677
}
6778

79+
static irqreturn_t rvu_cpt_af_flt0_intr_handler(int irq, void *ptr)
80+
{
81+
return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT0, ptr);
82+
}
83+
84+
static irqreturn_t rvu_cpt_af_flt1_intr_handler(int irq, void *ptr)
85+
{
86+
return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT1, ptr);
87+
}
88+
89+
static irqreturn_t rvu_cpt_af_flt2_intr_handler(int irq, void *ptr)
90+
{
91+
return cpt_af_flt_intr_handler(CPT_10K_AF_INT_VEC_FLT2, ptr);
92+
}
93+
6894
static irqreturn_t rvu_cpt_af_rvu_intr_handler(int irq, void *ptr)
6995
{
7096
struct rvu_block *block = ptr;
@@ -119,8 +145,10 @@ static void cpt_10k_unregister_interrupts(struct rvu_block *block, int off)
119145
int i;
120146

121147
/* Disable all CPT AF interrupts */
122-
for (i = 0; i < CPT_10K_AF_INT_VEC_RVU; i++)
123-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1);
148+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(0), ~0ULL);
149+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(1), ~0ULL);
150+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(2), 0xFFFF);
151+
124152
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1);
125153
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1);
126154

@@ -151,7 +179,7 @@ static void cpt_unregister_interrupts(struct rvu *rvu, int blkaddr)
151179

152180
/* Disable all CPT AF interrupts */
153181
for (i = 0; i < CPT_AF_INT_VEC_RVU; i++)
154-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1);
182+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), ~0ULL);
155183
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1);
156184
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1);
157185

@@ -172,16 +200,31 @@ static int cpt_10k_register_interrupts(struct rvu_block *block, int off)
172200
{
173201
struct rvu *rvu = block->rvu;
174202
int blkaddr = block->addr;
203+
irq_handler_t flt_fn;
175204
int i, ret;
176205

177206
for (i = CPT_10K_AF_INT_VEC_FLT0; i < CPT_10K_AF_INT_VEC_RVU; i++) {
178207
sprintf(&rvu->irq_name[(off + i) * NAME_SIZE], "CPTAF FLT%d", i);
208+
209+
switch (i) {
210+
case CPT_10K_AF_INT_VEC_FLT0:
211+
flt_fn = rvu_cpt_af_flt0_intr_handler;
212+
break;
213+
case CPT_10K_AF_INT_VEC_FLT1:
214+
flt_fn = rvu_cpt_af_flt1_intr_handler;
215+
break;
216+
case CPT_10K_AF_INT_VEC_FLT2:
217+
flt_fn = rvu_cpt_af_flt2_intr_handler;
218+
break;
219+
}
179220
ret = rvu_cpt_do_register_interrupt(block, off + i,
180-
rvu_cpt_af_flt_intr_handler,
181-
&rvu->irq_name[(off + i) * NAME_SIZE]);
221+
flt_fn, &rvu->irq_name[(off + i) * NAME_SIZE]);
182222
if (ret)
183223
goto err;
184-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1);
224+
if (i == CPT_10K_AF_INT_VEC_FLT2)
225+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0xFFFF);
226+
else
227+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL);
185228
}
186229

187230
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)
208251
{
209252
struct rvu_hwinfo *hw = rvu->hw;
210253
struct rvu_block *block;
254+
irq_handler_t flt_fn;
211255
int i, offs, ret = 0;
212-
char irq_name[16];
213256

214257
if (!is_block_implemented(rvu->hw, blkaddr))
215258
return 0;
@@ -226,13 +269,20 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr)
226269
return cpt_10k_register_interrupts(block, offs);
227270

228271
for (i = CPT_AF_INT_VEC_FLT0; i < CPT_AF_INT_VEC_RVU; i++) {
229-
snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i);
272+
sprintf(&rvu->irq_name[(offs + i) * NAME_SIZE], "CPTAF FLT%d", i);
273+
switch (i) {
274+
case CPT_AF_INT_VEC_FLT0:
275+
flt_fn = rvu_cpt_af_flt0_intr_handler;
276+
break;
277+
case CPT_AF_INT_VEC_FLT1:
278+
flt_fn = rvu_cpt_af_flt1_intr_handler;
279+
break;
280+
}
230281
ret = rvu_cpt_do_register_interrupt(block, offs + i,
231-
rvu_cpt_af_flt_intr_handler,
232-
irq_name);
282+
flt_fn, &rvu->irq_name[(offs + i) * NAME_SIZE]);
233283
if (ret)
234284
goto err;
235-
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1);
285+
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL);
236286
}
237287

238288
ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RVU,

0 commit comments

Comments
 (0)