Commit c57c58fd authored by Srujana Challa's avatar Srujana Challa Committed by Jakub Kicinski

octeontx2-af: Handle CPT function level reset

When FLR is initiated for a VF (PCI function level reset),
the parent PF gets a interrupt. PF then sends a message to
admin function (AF), which then cleans up all resources
attached to that VF. This patch adds support to handle
CPT FLR.
Signed-off-by: default avatarNarayana Prasad Raju Atherya <pathreya@marvell.com>
Signed-off-by: default avatarSuheil Chandran <schandran@marvell.com>
Signed-off-by: default avatarSunil Kovvuri Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarSrujana Challa <schalla@marvell.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b0f60fab
...@@ -2150,6 +2150,9 @@ static void rvu_blklf_teardown(struct rvu *rvu, u16 pcifunc, u8 blkaddr) ...@@ -2150,6 +2150,9 @@ static void rvu_blklf_teardown(struct rvu *rvu, u16 pcifunc, u8 blkaddr)
rvu_nix_lf_teardown(rvu, pcifunc, block->addr, lf); rvu_nix_lf_teardown(rvu, pcifunc, block->addr, lf);
else if (block->addr == BLKADDR_NPA) else if (block->addr == BLKADDR_NPA)
rvu_npa_lf_teardown(rvu, pcifunc, lf); rvu_npa_lf_teardown(rvu, pcifunc, lf);
else if ((block->addr == BLKADDR_CPT0) ||
(block->addr == BLKADDR_CPT1))
rvu_cpt_lf_teardown(rvu, pcifunc, lf, slot);
err = rvu_lf_reset(rvu, block, lf); err = rvu_lf_reset(rvu, block, lf);
if (err) { if (err) {
......
...@@ -608,6 +608,8 @@ void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, ...@@ -608,6 +608,8 @@ void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 src, struct mcam_entry *entry, int blkaddr, u16 src, struct mcam_entry *entry,
u8 *intf, u8 *ena); u8 *intf, u8 *ena);
/* CPT APIs */
int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot);
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
void rvu_dbg_init(struct rvu *rvu); void rvu_dbg_init(struct rvu *rvu);
......
...@@ -240,3 +240,92 @@ int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu, ...@@ -240,3 +240,92 @@ int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu,
return 0; return 0;
} }
#define INPROG_INFLIGHT(reg) ((reg) & 0x1FF)
#define INPROG_GRB_PARTIAL(reg) ((reg) & BIT_ULL(31))
#define INPROG_GRB(reg) (((reg) >> 32) & 0xFF)
#define INPROG_GWB(reg) (((reg) >> 40) & 0xFF)
static void cpt_lf_disable_iqueue(struct rvu *rvu, int blkaddr, int slot)
{
int i = 0, hard_lp_ctr = 100000;
u64 inprog, grp_ptr;
u16 nq_ptr, dq_ptr;
/* Disable instructions enqueuing */
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_CTL), 0x0);
/* Disable executions in the LF's queue */
inprog = rvu_read64(rvu, blkaddr,
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
inprog &= ~BIT_ULL(16);
rvu_write64(rvu, blkaddr,
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), inprog);
/* Wait for CPT queue to become execution-quiescent */
do {
inprog = rvu_read64(rvu, blkaddr,
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
if (INPROG_GRB_PARTIAL(inprog)) {
i = 0;
hard_lp_ctr--;
} else {
i++;
}
grp_ptr = rvu_read64(rvu, blkaddr,
CPT_AF_BAR2_ALIASX(slot,
CPT_LF_Q_GRP_PTR));
nq_ptr = (grp_ptr >> 32) & 0x7FFF;
dq_ptr = grp_ptr & 0x7FFF;
} while (hard_lp_ctr && (i < 10) && (nq_ptr != dq_ptr));
if (hard_lp_ctr == 0)
dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n");
i = 0;
hard_lp_ctr = 100000;
do {
inprog = rvu_read64(rvu, blkaddr,
CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
if ((INPROG_INFLIGHT(inprog) == 0) &&
(INPROG_GWB(inprog) < 40) &&
((INPROG_GRB(inprog) == 0) ||
(INPROG_GRB((inprog)) == 40))) {
i++;
} else {
i = 0;
hard_lp_ctr--;
}
} while (hard_lp_ctr && (i < 10));
if (hard_lp_ctr == 0)
dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n");
}
int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot)
{
int blkaddr;
u64 reg;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, pcifunc);
if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1)
return -EINVAL;
/* Enable BAR2 ALIAS for this pcifunc. */
reg = BIT_ULL(16) | pcifunc;
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg);
cpt_lf_disable_iqueue(rvu, blkaddr, slot);
/* Set group drop to help clear out hardware */
reg = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG));
reg |= BIT_ULL(17);
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), reg);
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0);
return 0;
}
...@@ -484,9 +484,17 @@ ...@@ -484,9 +484,17 @@
#define CPT_AF_RAS_INT_ENA_W1S (0x47030) #define CPT_AF_RAS_INT_ENA_W1S (0x47030)
#define CPT_AF_RAS_INT_ENA_W1C (0x47038) #define CPT_AF_RAS_INT_ENA_W1C (0x47038)
#define AF_BAR2_ALIASX(a, b) (0x9100000ull | (a) << 12 | (b))
#define CPT_AF_BAR2_SEL 0x9000000
#define CPT_AF_BAR2_ALIASX(a, b) AF_BAR2_ALIASX(a, b)
#define CPT_AF_LF_CTL2_SHIFT 3 #define CPT_AF_LF_CTL2_SHIFT 3
#define CPT_AF_LF_SSO_PF_FUNC_SHIFT 32 #define CPT_AF_LF_SSO_PF_FUNC_SHIFT 32
#define CPT_LF_CTL 0x10
#define CPT_LF_INPROG 0x40
#define CPT_LF_Q_GRP_PTR 0x120
#define NPC_AF_BLK_RST (0x00040) #define NPC_AF_BLK_RST (0x00040)
/* NPC */ /* NPC */
......
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