octeontx2-af: add mailbox interface for CPT
authorSrujana Challa <schalla@marvell.com>
Wed, 18 Nov 2020 11:44:15 +0000 (17:14 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 20 Nov 2020 19:01:13 +0000 (11:01 -0800)
On OcteonTX2 SoC, the admin function (AF) is the only one with all
priviliges to configure HW and alloc resources, PFs and it's VFs
have to request AF via mailbox for all their needs. This patch adds
a mailbox interface for CPT PFs and VFs to allocate resources
for cryptography. It also adds hardware CPT AF register defines.

Signed-off-by: Suheil Chandran <schandran@marvell.com>
Signed-off-by: Lukasz Bartosik <lbartosik@marvell.com>
Signed-off-by: Srujana Challa <schalla@marvell.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/marvell/octeontx2/af/Makefile
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c [new file with mode: 0644]
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h

index ffc681b67f1c8b734ba0aa502942c48493bde883..7100d1dd856e6782a9efacfbfd8bf7329e3eb061 100644 (file)
@@ -9,4 +9,5 @@ obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o
 
 octeontx2_mbox-y := mbox.o rvu_trace.o
 octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
-                 rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o
+                 rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \
+                 rvu_cpt.o
index cb4e3d86b58b2b2d548130338b3fdbd1a321f544..221fe5b7c093dae41131bb55aa7c30efc6f83bf8 100644 (file)
@@ -158,6 +158,11 @@ M(NPA_HWCTX_DISABLE,       0x403, npa_hwctx_disable, hwctx_disable_req, msg_rsp)\
 /* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */                          \
 /* TIM mbox IDs (range 0x800 - 0x9FF) */                               \
 /* CPT mbox IDs (range 0xA00 - 0xBFF) */                               \
+M(CPT_LF_ALLOC,                0xA00, cpt_lf_alloc, cpt_lf_alloc_req_msg,      \
+                              msg_rsp)                                 \
+M(CPT_LF_FREE,         0xA01, cpt_lf_free, msg_req, msg_rsp)           \
+M(CPT_RD_WR_REGISTER,  0xA02, cpt_rd_wr_register,  cpt_rd_wr_reg_msg,  \
+                              cpt_rd_wr_reg_msg)                       \
 /* NPC mbox IDs (range 0x6000 - 0x7FFF) */                             \
 M(NPC_MCAM_ALLOC_ENTRY,        0x6000, npc_mcam_alloc_entry, npc_mcam_alloc_entry_req,\
                                npc_mcam_alloc_entry_rsp)               \
@@ -1046,4 +1051,32 @@ struct ptp_rsp {
        u64 clk;
 };
 
+/* CPT mailbox error codes
+ * Range 901 - 1000.
+ */
+enum cpt_af_status {
+       CPT_AF_ERR_PARAM                = -901,
+       CPT_AF_ERR_GRP_INVALID          = -902,
+       CPT_AF_ERR_LF_INVALID           = -903,
+       CPT_AF_ERR_ACCESS_DENIED        = -904,
+       CPT_AF_ERR_SSO_PF_FUNC_INVALID  = -905,
+       CPT_AF_ERR_NIX_PF_FUNC_INVALID  = -906
+};
+
+/* CPT mbox message formats */
+struct cpt_rd_wr_reg_msg {
+       struct mbox_msghdr hdr;
+       u64 reg_offset;
+       u64 *ret_val;
+       u64 val;
+       u8 is_write;
+};
+
+struct cpt_lf_alloc_req_msg {
+       struct mbox_msghdr hdr;
+       u16 nix_pf_func;
+       u16 sso_pf_func;
+       u16 eng_grpmsk;
+};
+
 #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
new file mode 100644 (file)
index 0000000..35261d5
--- /dev/null
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2020 Marvell. */
+
+#include <linux/pci.h>
+#include "rvu_struct.h"
+#include "rvu_reg.h"
+#include "mbox.h"
+#include "rvu.h"
+
+/* CPT PF device id */
+#define        PCI_DEVID_OTX2_CPT_PF   0xA0FD
+
+static int get_cpt_pf_num(struct rvu *rvu)
+{
+       int i, domain_nr, cpt_pf_num = -1;
+       struct pci_dev *pdev;
+
+       domain_nr = pci_domain_nr(rvu->pdev->bus);
+       for (i = 0; i < rvu->hw->total_pfs; i++) {
+               pdev = pci_get_domain_bus_and_slot(domain_nr, i + 1, 0);
+               if (!pdev)
+                       continue;
+
+               if (pdev->device == PCI_DEVID_OTX2_CPT_PF) {
+                       cpt_pf_num = i;
+                       put_device(&pdev->dev);
+                       break;
+               }
+               put_device(&pdev->dev);
+       }
+       return cpt_pf_num;
+}
+
+static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc)
+{
+       int cpt_pf_num = get_cpt_pf_num(rvu);
+
+       if (rvu_get_pf(pcifunc) != cpt_pf_num)
+               return false;
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               return false;
+
+       return true;
+}
+
+static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc)
+{
+       int cpt_pf_num = get_cpt_pf_num(rvu);
+
+       if (rvu_get_pf(pcifunc) != cpt_pf_num)
+               return false;
+       if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+               return false;
+
+       return true;
+}
+
+int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu,
+                                 struct cpt_lf_alloc_req_msg *req,
+                                 struct msg_rsp *rsp)
+{
+       u16 pcifunc = req->hdr.pcifunc;
+       struct rvu_block *block;
+       int cptlf, blkaddr;
+       int num_lfs, slot;
+       u64 val;
+
+       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);
+       if (!num_lfs)
+               return CPT_AF_ERR_LF_INVALID;
+
+       /* Check if requested 'CPTLF <=> NIXLF' mapping is valid */
+       if (req->nix_pf_func) {
+               /* If default, use 'this' CPTLF's PFFUNC */
+               if (req->nix_pf_func == RVU_DEFAULT_PF_FUNC)
+                       req->nix_pf_func = pcifunc;
+               if (!is_pffunc_map_valid(rvu, req->nix_pf_func, BLKTYPE_NIX))
+                       return CPT_AF_ERR_NIX_PF_FUNC_INVALID;
+       }
+
+       /* Check if requested 'CPTLF <=> SSOLF' mapping is valid */
+       if (req->sso_pf_func) {
+               /* If default, use 'this' CPTLF's PFFUNC */
+               if (req->sso_pf_func == RVU_DEFAULT_PF_FUNC)
+                       req->sso_pf_func = pcifunc;
+               if (!is_pffunc_map_valid(rvu, req->sso_pf_func, BLKTYPE_SSO))
+                       return CPT_AF_ERR_SSO_PF_FUNC_INVALID;
+       }
+
+       for (slot = 0; slot < num_lfs; slot++) {
+               cptlf = rvu_get_lf(rvu, block, pcifunc, slot);
+               if (cptlf < 0)
+                       return CPT_AF_ERR_LF_INVALID;
+
+               /* Set CPT LF group and priority */
+               val = (u64)req->eng_grpmsk << 48 | 1;
+               rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), val);
+
+               /* Set CPT LF NIX_PF_FUNC and SSO_PF_FUNC */
+               val = (u64)req->nix_pf_func << 48 |
+                     (u64)req->sso_pf_func << 32;
+               rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf), val);
+       }
+
+       return 0;
+}
+
+int rvu_mbox_handler_cpt_lf_free(struct rvu *rvu, struct msg_req *req,
+                                struct msg_rsp *rsp)
+{
+       u16 pcifunc = req->hdr.pcifunc;
+       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;
+
+       for (slot = 0; slot < num_lfs; slot++) {
+               cptlf = rvu_get_lf(rvu, block, pcifunc, slot);
+               if (cptlf < 0)
+                       return CPT_AF_ERR_LF_INVALID;
+
+               /* Reset CPT LF group and priority */
+               rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), 0x0);
+               /* Reset CPT LF NIX_PF_FUNC and SSO_PF_FUNC */
+               rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf), 0x0);
+       }
+
+       return 0;
+}
+
+static bool is_valid_offset(struct rvu *rvu, struct cpt_rd_wr_reg_msg *req)
+{
+       u64 offset = req->reg_offset;
+       int blkaddr, num_lfs, lf;
+       struct rvu_block *block;
+       struct rvu_pfvf *pfvf;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0);
+
+       /* Registers that can be accessed from PF/VF */
+       if ((offset & 0xFF000) ==  CPT_AF_LFX_CTL(0) ||
+           (offset & 0xFF000) ==  CPT_AF_LFX_CTL2(0)) {
+               if (offset & 7)
+                       return false;
+
+               lf = (offset & 0xFFF) >> 3;
+               block = &rvu->hw->block[blkaddr];
+               pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
+               num_lfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
+               if (lf >= num_lfs)
+                       /* Slot is not valid for that PF/VF */
+                       return false;
+
+               /* Translate local LF used by VFs to global CPT LF */
+               lf = rvu_get_lf(rvu, &rvu->hw->block[blkaddr],
+                               req->hdr.pcifunc, lf);
+               if (lf < 0)
+                       return false;
+
+               return true;
+       } else if (!(req->hdr.pcifunc & RVU_PFVF_FUNC_MASK)) {
+               /* Registers that can be accessed from PF */
+               switch (offset) {
+               case CPT_AF_CTL:
+               case CPT_AF_PF_FUNC:
+               case CPT_AF_BLK_RST:
+               case CPT_AF_CONSTANTS1:
+                       return true;
+               }
+
+               switch (offset & 0xFF000) {
+               case CPT_AF_EXEX_STS(0):
+               case CPT_AF_EXEX_CTL(0):
+               case CPT_AF_EXEX_CTL2(0):
+               case CPT_AF_EXEX_UCODE_BASE(0):
+                       if (offset & 7)
+                               return false;
+                       break;
+               default:
+                       return false;
+               }
+               return true;
+       }
+       return false;
+}
+
+int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu,
+                                       struct cpt_rd_wr_reg_msg *req,
+                                       struct cpt_rd_wr_reg_msg *rsp)
+{
+       int blkaddr;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0);
+       if (blkaddr < 0)
+               return blkaddr;
+
+       /* This message is accepted only if sent from CPT PF/VF */
+       if (!is_cpt_pf(rvu, req->hdr.pcifunc) &&
+           !is_cpt_vf(rvu, req->hdr.pcifunc))
+               return CPT_AF_ERR_ACCESS_DENIED;
+
+       rsp->reg_offset = req->reg_offset;
+       rsp->ret_val = req->ret_val;
+       rsp->is_write = req->is_write;
+
+       if (!is_valid_offset(rvu, req))
+               return CPT_AF_ERR_ACCESS_DENIED;
+
+       if (req->is_write)
+               rvu_write64(rvu, blkaddr, req->reg_offset, req->val);
+       else
+               rsp->val = rvu_read64(rvu, blkaddr, req->reg_offset);
+
+       return 0;
+}
index 1f3379f12b81507adb67acdd04485b183f6d9528..0fb2aa909a23fe2c84a91999a836a434357c9c2e 100644 (file)
 #define TIM_AF_LF_RST                  (0x20)
 
 /* CPT */
-#define CPT_AF_CONSTANTS0              (0x0000)
-#define CPT_PRIV_LFX_CFG               (0x41000)
-#define CPT_PRIV_LFX_INT_CFG           (0x43000)
-#define CPT_AF_RVU_LF_CFG_DEBUG                (0x45000)
-#define CPT_AF_LF_RST                  (0x44000)
-#define CPT_AF_BLK_RST                 (0x46000)
+#define CPT_AF_CONSTANTS0               (0x0000)
+#define CPT_AF_CONSTANTS1               (0x1000)
+#define CPT_AF_DIAG                     (0x3000)
+#define CPT_AF_ECO                      (0x4000)
+#define CPT_AF_FLTX_INT(a)              (0xa000ull | (u64)(a) << 3)
+#define CPT_AF_FLTX_INT_W1S(a)          (0xb000ull | (u64)(a) << 3)
+#define CPT_AF_FLTX_INT_ENA_W1C(a)      (0xc000ull | (u64)(a) << 3)
+#define CPT_AF_FLTX_INT_ENA_W1S(a)      (0xd000ull | (u64)(a) << 3)
+#define CPT_AF_PSNX_EXE(a)              (0xe000ull | (u64)(a) << 3)
+#define CPT_AF_PSNX_EXE_W1S(a)          (0xf000ull | (u64)(a) << 3)
+#define CPT_AF_PSNX_LF(a)               (0x10000ull | (u64)(a) << 3)
+#define CPT_AF_PSNX_LF_W1S(a)           (0x11000ull | (u64)(a) << 3)
+#define CPT_AF_EXEX_CTL2(a)             (0x12000ull | (u64)(a) << 3)
+#define CPT_AF_EXEX_STS(a)              (0x13000ull | (u64)(a) << 3)
+#define CPT_AF_EXE_ERR_INFO             (0x14000)
+#define CPT_AF_EXEX_ACTIVE(a)           (0x16000ull | (u64)(a) << 3)
+#define CPT_AF_INST_REQ_PC              (0x17000)
+#define CPT_AF_INST_LATENCY_PC          (0x18000)
+#define CPT_AF_RD_REQ_PC                (0x19000)
+#define CPT_AF_RD_LATENCY_PC            (0x1a000)
+#define CPT_AF_RD_UC_PC                 (0x1b000)
+#define CPT_AF_ACTIVE_CYCLES_PC         (0x1c000)
+#define CPT_AF_EXE_DBG_CTL              (0x1d000)
+#define CPT_AF_EXE_DBG_DATA             (0x1e000)
+#define CPT_AF_EXE_REQ_TIMER            (0x1f000)
+#define CPT_AF_EXEX_CTL(a)              (0x20000ull | (u64)(a) << 3)
+#define CPT_AF_EXE_PERF_CTL             (0x21000)
+#define CPT_AF_EXE_DBG_CNTX(a)          (0x22000ull | (u64)(a) << 3)
+#define CPT_AF_EXE_PERF_EVENT_CNT       (0x23000)
+#define CPT_AF_EXE_EPCI_INBX_CNT(a)     (0x24000ull | (u64)(a) << 3)
+#define CPT_AF_EXE_EPCI_OUTBX_CNT(a)    (0x25000ull | (u64)(a) << 3)
+#define CPT_AF_EXEX_UCODE_BASE(a)       (0x26000ull | (u64)(a) << 3)
+#define CPT_AF_LFX_CTL(a)               (0x27000ull | (u64)(a) << 3)
+#define CPT_AF_LFX_CTL2(a)              (0x29000ull | (u64)(a) << 3)
+#define CPT_AF_CPTCLK_CNT               (0x2a000)
+#define CPT_AF_PF_FUNC                  (0x2b000)
+#define CPT_AF_LFX_PTR_CTL(a)           (0x2c000ull | (u64)(a) << 3)
+#define CPT_AF_GRPX_THR(a)              (0x2d000ull | (u64)(a) << 3)
+#define CPT_AF_CTL                      (0x2e000ull)
+#define CPT_AF_XEX_THR(a)               (0x2f000ull | (u64)(a) << 3)
+#define CPT_PRIV_LFX_CFG                (0x41000)
+#define CPT_PRIV_AF_INT_CFG             (0x42000)
+#define CPT_PRIV_LFX_INT_CFG            (0x43000)
+#define CPT_AF_LF_RST                   (0x44000)
+#define CPT_AF_RVU_LF_CFG_DEBUG         (0x45000)
+#define CPT_AF_BLK_RST                  (0x46000)
+#define CPT_AF_RVU_INT                  (0x47000)
+#define CPT_AF_RVU_INT_W1S              (0x47008)
+#define CPT_AF_RVU_INT_ENA_W1S          (0x47010)
+#define CPT_AF_RVU_INT_ENA_W1C          (0x47018)
+#define CPT_AF_RAS_INT                  (0x47020)
+#define CPT_AF_RAS_INT_W1S              (0x47028)
+#define CPT_AF_RAS_INT_ENA_W1S          (0x47030)
+#define CPT_AF_RAS_INT_ENA_W1C          (0x47038)
+
+#define CPT_AF_LF_CTL2_SHIFT 3
+#define CPT_AF_LF_SSO_PF_FUNC_SHIFT 32
 
 #define NPC_AF_BLK_RST                  (0x00040)