Re: [PATCH net-next,3/3] octeontx2-af: Handle CPT function level reset
From: Saeed Mahameed <saeed@kernel.org>
Date: 2021-01-15 00:00:45
On Wed, 2021-01-13 at 20:50 +0530, Srujana Challa wrote:
quoted hunk ↗ jump to hunk
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: Narayana Prasad Raju Atherya <redacted> Signed-off-by: Suheil Chandran <redacted> Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com> Signed-off-by: Srujana Challa <schalla@marvell.com> --- .../net/ethernet/marvell/octeontx2/af/rvu.c | 3 + .../net/ethernet/marvell/octeontx2/af/rvu.h | 2 + .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 74 +++++++++++++++++++ .../ethernet/marvell/octeontx2/af/rvu_reg.h | 8 ++ 4 files changed, 87 insertions(+)diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.cb/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index e8fd712860a1..0d538b39462d 100644--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c@@ -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); else if (block->addr == BLKADDR_NPA) 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); if (err) {diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.hb/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index b1a6ecfd563e..6f64a13e752a 100644--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h@@ -601,6 +601,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, int blkaddr, u16 src, struct mcam_entry *entry, u8 *intf, u8 *ena); +/* CPT APIs */ +int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot); #ifdef CONFIG_DEBUG_FS void rvu_dbg_init(struct rvu *rvu);diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.cb/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index b6de4b95a72a..ea435d7da975 100644--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c@@ -240,3 +240,77 @@ int rvu_mbox_handler_cpt_rd_wr_register(structrvu *rvu, return 0; } + +static void cpt_lf_disable_iqueue(struct rvu *rvu, int blkaddr, int slot) +{ + u64 inprog, grp_ptr; + int i = 0; + + /* 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)); + /* Check for partial entries (GRB_PARTIAL) */ + if (inprog & BIT_ULL(31)) + i = 0; + else + i++; + + grp_ptr = rvu_read64(rvu, blkaddr, + CPT_AF_BAR2_ALIASX(slot, + CPT_LF_Q_GRP_PT R)); + } while ((i < 10) && (((grp_ptr >> 32) & 0x7FFF) != + (grp_ptr & 0x7FFF)));
What prevents an infinite loop if the HW locks up and you get stuck on a partial entry ? Also it would be nice if you'd wrap this in a nice macro with an informative name: (grp_ptr >> 32) & 0x7FFF) != (grp_ptr & 0x7FFF))
+ i = 0;
+ do {
+ inprog = rvu_read64(rvu, blkaddr,
+ CPT_AF_BAR2_ALIASX(slot,
CPT_LF_INPROG));
+ /* GWB writes groups of 40. So below formula is used
for
+ * knowing that no more instructions will be scheduled
+ * (INFLIGHT == 0) && (GWB < 40) && (GRB == 0 OR 40)
+ */So why not replace the comment with macros that wrap the below conditions and the code will become self explanatory..
quoted hunk ↗ jump to hunk
+ if (((inprog & 0x1FF) == 0) && + (((inprog >> 40) & 0xFF) < 40) && + ((((inprog >> 32) & 0xFF) == 0) || + (((inprog >> 32) & 0xFF) == 40))) + i++; + else + i = 0; + } while (i < 10); +} +