From de2854c87c64788f94e34217d06e60422e4a1842 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Tue, 2 Feb 2021 20:57:07 +0530 Subject: [PATCH 1/3] octeontx2-af: Mailbox changes for 98xx CPT block This patch changes CPT mailbox message format to support new block CPT1 in 98xx silicon. cpt_rd_wr_reg -> Modify cpt_rd_wr_reg mailbox and its handler to accommodate new block CPT1. cpt_lf_alloc -> Modify cpt_lf_alloc mailbox and its handler to configure LFs from a block address out of multiple blocks of same type. If a PF/VF needs to configure LFs from both the blocks then this mbox should be called twice. Signed-off-by: Mahipal Challa Signed-off-by: Srujana Challa Signed-off-by: Jakub Kicinski --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 2 + .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 41 +++++++++++-------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index 89e93eb46ab7..a0fa44941204 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1073,6 +1073,7 @@ struct cpt_rd_wr_reg_msg { u64 *ret_val; u64 val; u8 is_write; + int blkaddr; }; struct cpt_lf_alloc_req_msg { @@ -1080,6 +1081,7 @@ struct cpt_lf_alloc_req_msg { u16 nix_pf_func; u16 sso_pf_func; u16 eng_grpmsk; + int blkaddr; }; #endif /* MBOX_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index 35261d52c997..b6de4b95a72a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -65,13 +65,13 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu, int num_lfs, slot; u64 val; + blkaddr = req->blkaddr ? req->blkaddr : BLKADDR_CPT0; + if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1) + return -ENODEV; + if (req->eng_grpmsk == 0x0) return CPT_AF_ERR_GRP_INVALID; - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return blkaddr; - block = &rvu->hw->block[blkaddr]; num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, pcifunc), block->addr); @@ -114,23 +114,17 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu, return 0; } -int rvu_mbox_handler_cpt_lf_free(struct rvu *rvu, struct msg_req *req, - struct msg_rsp *rsp) +static int cpt_lf_free(struct rvu *rvu, struct msg_req *req, int blkaddr) { u16 pcifunc = req->hdr.pcifunc; + int num_lfs, cptlf, slot; struct rvu_block *block; - int cptlf, blkaddr; - int num_lfs, slot; - - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return blkaddr; block = &rvu->hw->block[blkaddr]; num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, pcifunc), block->addr); if (!num_lfs) - return CPT_AF_ERR_LF_INVALID; + return 0; for (slot = 0; slot < num_lfs; slot++) { cptlf = rvu_get_lf(rvu, block, pcifunc, slot); @@ -146,6 +140,21 @@ int rvu_mbox_handler_cpt_lf_free(struct rvu *rvu, struct msg_req *req, return 0; } +int rvu_mbox_handler_cpt_lf_free(struct rvu *rvu, struct msg_req *req, + struct msg_rsp *rsp) +{ + int ret; + + ret = cpt_lf_free(rvu, req, BLKADDR_CPT0); + if (ret) + return ret; + + if (is_block_implemented(rvu->hw, BLKADDR_CPT1)) + ret = cpt_lf_free(rvu, req, BLKADDR_CPT1); + + return ret; +} + static bool is_valid_offset(struct rvu *rvu, struct cpt_rd_wr_reg_msg *req) { u64 offset = req->reg_offset; @@ -208,9 +217,9 @@ int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu, { int blkaddr; - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return blkaddr; + blkaddr = req->blkaddr ? req->blkaddr : BLKADDR_CPT0; + if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1) + return -ENODEV; /* This message is accepted only if sent from CPT PF/VF */ if (!is_cpt_pf(rvu, req->hdr.pcifunc) && From b0f60fab7805cb013311ede0127f8abbf1bdc986 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Tue, 2 Feb 2021 20:57:08 +0530 Subject: [PATCH 2/3] octeontx2-af: Add support for CPT1 in debugfs Adds support to display block CPT1 stats at "/sys/kernel/debug/octeontx2/cpt1". Signed-off-by: Mahipal Challa Signed-off-by: Srujana Challa Signed-off-by: Jakub Kicinski --- .../net/ethernet/marvell/octeontx2/af/rvu.h | 7 ++ .../marvell/octeontx2/af/rvu_debugfs.c | 86 +++++++++---------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index b1a6ecfd563e..aabf6d5ee020 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -33,6 +33,7 @@ #define NAME_SIZE 32 #define MAX_NIX_BLKS 2 +#define MAX_CPT_BLKS 2 /* PF_FUNC */ #define RVU_PFVF_PF_SHIFT 10 @@ -47,6 +48,11 @@ struct dump_ctx { bool all; }; +struct cpt_ctx { + int blkaddr; + struct rvu *rvu; +}; + struct rvu_debugfs { struct dentry *root; struct dentry *cgx_root; @@ -61,6 +67,7 @@ struct rvu_debugfs { struct dump_ctx nix_cq_ctx; struct dump_ctx nix_rq_ctx; struct dump_ctx nix_sq_ctx; + struct cpt_ctx cpt_ctx[MAX_CPT_BLKS]; int npa_qsize_id; int nix_qsize_id; }; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c index f60499562d2e..80e964330de3 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c @@ -1904,20 +1904,16 @@ static void rvu_dbg_npc_init(struct rvu *rvu) &rvu_dbg_npc_rx_miss_act_fops); } -/* CPT debugfs APIs */ static int cpt_eng_sts_display(struct seq_file *filp, u8 eng_type) { - struct rvu *rvu = filp->private; + struct cpt_ctx *ctx = filp->private; u64 busy_sts = 0, free_sts = 0; u32 e_min = 0, e_max = 0, e, i; u16 max_ses, max_ies, max_aes; - int blkaddr; + struct rvu *rvu = ctx->rvu; + int blkaddr = ctx->blkaddr; u64 reg; - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return -ENODEV; - reg = rvu_read64(rvu, blkaddr, CPT_AF_CONSTANTS1); max_ses = reg & 0xffff; max_ies = (reg >> 16) & 0xffff; @@ -1977,16 +1973,13 @@ RVU_DEBUG_SEQ_FOPS(cpt_ie_sts, cpt_ie_sts_display, NULL); static int rvu_dbg_cpt_engines_info_display(struct seq_file *filp, void *unused) { - struct rvu *rvu = filp->private; + struct cpt_ctx *ctx = filp->private; u16 max_ses, max_ies, max_aes; + struct rvu *rvu = ctx->rvu; + int blkaddr = ctx->blkaddr; u32 e_max, e; - int blkaddr; u64 reg; - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return -ENODEV; - reg = rvu_read64(rvu, blkaddr, CPT_AF_CONSTANTS1); max_ses = reg & 0xffff; max_ies = (reg >> 16) & 0xffff; @@ -2014,17 +2007,15 @@ RVU_DEBUG_SEQ_FOPS(cpt_engines_info, cpt_engines_info_display, NULL); static int rvu_dbg_cpt_lfs_info_display(struct seq_file *filp, void *unused) { - struct rvu *rvu = filp->private; - struct rvu_hwinfo *hw = rvu->hw; + struct cpt_ctx *ctx = filp->private; + int blkaddr = ctx->blkaddr; + struct rvu *rvu = ctx->rvu; struct rvu_block *block; - int blkaddr; + struct rvu_hwinfo *hw; u64 reg; u32 lf; - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return -ENODEV; - + hw = rvu->hw; block = &hw->block[blkaddr]; if (!block->lf.bmap) return -ENODEV; @@ -2049,13 +2040,10 @@ RVU_DEBUG_SEQ_FOPS(cpt_lfs_info, cpt_lfs_info_display, NULL); static int rvu_dbg_cpt_err_info_display(struct seq_file *filp, void *unused) { - struct rvu *rvu = filp->private; + struct cpt_ctx *ctx = filp->private; + struct rvu *rvu = ctx->rvu; + int blkaddr = ctx->blkaddr; u64 reg0, reg1; - int blkaddr; - - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return -ENODEV; reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0)); reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1)); @@ -2079,15 +2067,11 @@ RVU_DEBUG_SEQ_FOPS(cpt_err_info, cpt_err_info_display, NULL); static int rvu_dbg_cpt_pc_display(struct seq_file *filp, void *unused) { - struct rvu *rvu; - int blkaddr; + struct cpt_ctx *ctx = filp->private; + struct rvu *rvu = ctx->rvu; + int blkaddr = ctx->blkaddr; u64 reg; - rvu = filp->private; - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); - if (blkaddr < 0) - return -ENODEV; - reg = rvu_read64(rvu, blkaddr, CPT_AF_INST_REQ_PC); seq_printf(filp, "CPT instruction requests %llu\n", reg); reg = rvu_read64(rvu, blkaddr, CPT_AF_INST_LATENCY_PC); @@ -2108,26 +2092,39 @@ static int rvu_dbg_cpt_pc_display(struct seq_file *filp, void *unused) RVU_DEBUG_SEQ_FOPS(cpt_pc, cpt_pc_display, NULL); -static void rvu_dbg_cpt_init(struct rvu *rvu) +static void rvu_dbg_cpt_init(struct rvu *rvu, int blkaddr) { - if (!is_block_implemented(rvu->hw, BLKADDR_CPT0)) + struct cpt_ctx *ctx; + + if (!is_block_implemented(rvu->hw, blkaddr)) return; - rvu->rvu_dbg.cpt = debugfs_create_dir("cpt", rvu->rvu_dbg.root); + if (blkaddr == BLKADDR_CPT0) { + rvu->rvu_dbg.cpt = debugfs_create_dir("cpt", rvu->rvu_dbg.root); + ctx = &rvu->rvu_dbg.cpt_ctx[0]; + ctx->blkaddr = BLKADDR_CPT0; + ctx->rvu = rvu; + } else { + rvu->rvu_dbg.cpt = debugfs_create_dir("cpt1", + rvu->rvu_dbg.root); + ctx = &rvu->rvu_dbg.cpt_ctx[1]; + ctx->blkaddr = BLKADDR_CPT1; + ctx->rvu = rvu; + } - debugfs_create_file("cpt_pc", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_pc", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_pc_fops); - debugfs_create_file("cpt_ae_sts", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_ae_sts", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_ae_sts_fops); - debugfs_create_file("cpt_se_sts", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_se_sts", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_se_sts_fops); - debugfs_create_file("cpt_ie_sts", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_ie_sts", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_ie_sts_fops); - debugfs_create_file("cpt_engines_info", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_engines_info", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_engines_info_fops); - debugfs_create_file("cpt_lfs_info", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_lfs_info", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_lfs_info_fops); - debugfs_create_file("cpt_err_info", 0600, rvu->rvu_dbg.cpt, rvu, + debugfs_create_file("cpt_err_info", 0600, rvu->rvu_dbg.cpt, ctx, &rvu_dbg_cpt_err_info_fops); } @@ -2146,7 +2143,8 @@ void rvu_dbg_init(struct rvu *rvu) rvu_dbg_nix_init(rvu, BLKADDR_NIX1); rvu_dbg_cgx_init(rvu); rvu_dbg_npc_init(rvu); - rvu_dbg_cpt_init(rvu); + rvu_dbg_cpt_init(rvu, BLKADDR_CPT0); + rvu_dbg_cpt_init(rvu, BLKADDR_CPT1); } void rvu_dbg_exit(struct rvu *rvu) From c57c58fd5c4fd288f5aca0970982c9bd547d6288 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Tue, 2 Feb 2021 20:57:09 +0530 Subject: [PATCH 3/3] 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: Narayana Prasad Raju Atherya Signed-off-by: Suheil Chandran Signed-off-by: Sunil Kovvuri Goutham Signed-off-by: Srujana Challa Signed-off-by: Jakub Kicinski --- .../net/ethernet/marvell/octeontx2/af/rvu.c | 3 + .../net/ethernet/marvell/octeontx2/af/rvu.h | 2 + .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 89 +++++++++++++++++++ .../ethernet/marvell/octeontx2/af/rvu_reg.h | 8 ++ 4 files changed, 102 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index 4ef7fc8bbb19..50c2a1d800f4 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.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index aabf6d5ee020..ce931d86600b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -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, 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.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index b6de4b95a72a..0945c3a3b180 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -240,3 +240,92 @@ int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu, 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; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h index 0fb2aa909a23..79a6dcf0e3c0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h @@ -484,9 +484,17 @@ #define CPT_AF_RAS_INT_ENA_W1S (0x47030) #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_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) /* NPC */