Commit b5fb0b1b authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'add-support-for-marvell-octeontx2-cryptographic'

Srujana Challa says:

====================
Add Support for Marvell OcteonTX2 Cryptographic

This patchset adds support for CPT in OcteonTX2 admin function(AF).
CPT is a cryptographic accelerator unit and it includes microcoded
Giga Cipher engines.

OcteonTX2 SOC's resource virtualization unit (RVU) supports multiple
physical and virtual functions. Each of the PF/VF's functionality is
determined by what kind of resources are attached to it. When the CPT
block is attached to a VF, it can function as a security device.
The following document provides an overview of the hardware and
different drivers for the OcteonTX2 SOC:
https://www.kernel.org/doc/Documentation/networking/device_drivers/marvell/octeontx2.rst

This patch series includes:
- Patch to update existing Marvell sources to support CPT.
- Patch that adds mailbox messages to the admin function (AF) driver,
to configure CPT HW registers.
- Patch to provide debug information about CPT.
====================

Link: https://lore.kernel.org/r/20201118114416.28307-1-schalla@marvell.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1a0058cf 76638a2e
......@@ -10453,6 +10453,7 @@ M: Srujana Challa <schalla@marvell.com>
L: linux-crypto@vger.kernel.org
S: Maintained
F: drivers/crypto/marvell/
F: include/linux/soc/marvell/octeontx2/
MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
M: Mirko Lindner <mlindner@marvell.com>
......@@ -10525,6 +10526,7 @@ M: hariprasad <hkelam@marvell.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/marvell/octeontx2/nic/
F: include/linux/soc/marvell/octeontx2/
MARVELL OCTEONTX2 RVU ADMIN FUNCTION DRIVER
M: Sunil Goutham <sgoutham@marvell.com>
......
......@@ -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
......@@ -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 */
......@@ -52,6 +52,7 @@ struct rvu_debugfs {
struct dentry *npa;
struct dentry *nix;
struct dentry *npc;
struct dentry *cpt;
struct dump_ctx npa_aura_ctx;
struct dump_ctx npa_pool_ctx;
struct dump_ctx nix_cq_ctx;
......
// 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;
}
......@@ -109,6 +109,12 @@ static char *cgx_tx_stats_fields[] = {
[CGX_STAT17] = "Control/PAUSE packets sent",
};
enum cpt_eng_type {
CPT_AE_TYPE = 1,
CPT_SE_TYPE = 2,
CPT_IE_TYPE = 3,
};
#define NDC_MAX_BANK(rvu, blk_addr) (rvu_read64(rvu, \
blk_addr, NDC_AF_CONST) & 0xFF)
......@@ -1993,6 +1999,271 @@ static void rvu_dbg_npc_init(struct rvu *rvu)
debugfs_remove_recursive(rvu->rvu_dbg.npc);
}
/* CPT debugfs APIs */
static int cpt_eng_sts_display(struct seq_file *filp, u8 eng_type)
{
struct rvu *rvu = 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;
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;
max_aes = (reg >> 32) & 0xffff;
switch (eng_type) {
case CPT_AE_TYPE:
e_min = max_ses + max_ies;
e_max = max_ses + max_ies + max_aes;
break;
case CPT_SE_TYPE:
e_min = 0;
e_max = max_ses;
break;
case CPT_IE_TYPE:
e_min = max_ses;
e_max = max_ses + max_ies;
break;
default:
return -EINVAL;
}
for (e = e_min, i = 0; e < e_max; e++, i++) {
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_STS(e));
if (reg & 0x1)
busy_sts |= 1ULL << i;
if (reg & 0x2)
free_sts |= 1ULL << i;
}
seq_printf(filp, "FREE STS : 0x%016llx\n", free_sts);
seq_printf(filp, "BUSY STS : 0x%016llx\n", busy_sts);
return 0;
}
static int rvu_dbg_cpt_ae_sts_display(struct seq_file *filp, void *unused)
{
return cpt_eng_sts_display(filp, CPT_AE_TYPE);
}
RVU_DEBUG_SEQ_FOPS(cpt_ae_sts, cpt_ae_sts_display, NULL);
static int rvu_dbg_cpt_se_sts_display(struct seq_file *filp, void *unused)
{
return cpt_eng_sts_display(filp, CPT_SE_TYPE);
}
RVU_DEBUG_SEQ_FOPS(cpt_se_sts, cpt_se_sts_display, NULL);
static int rvu_dbg_cpt_ie_sts_display(struct seq_file *filp, void *unused)
{
return cpt_eng_sts_display(filp, CPT_IE_TYPE);
}
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;
u16 max_ses, max_ies, max_aes;
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;
max_aes = (reg >> 32) & 0xffff;
e_max = max_ses + max_ies + max_aes;
seq_puts(filp, "===========================================\n");
for (e = 0; e < e_max; e++) {
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(e));
seq_printf(filp, "CPT Engine[%u] Group Enable 0x%02llx\n", e,
reg & 0xff);
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_ACTIVE(e));
seq_printf(filp, "CPT Engine[%u] Active Info 0x%llx\n", e,
reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(e));
seq_printf(filp, "CPT Engine[%u] Control 0x%llx\n", e,
reg);
seq_puts(filp, "===========================================\n");
}
return 0;
}
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 rvu_block *block;
int blkaddr;
u64 reg;
u32 lf;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0);
if (blkaddr < 0)
return -ENODEV;
block = &hw->block[blkaddr];
if (!block->lf.bmap)
return -ENODEV;
seq_puts(filp, "===========================================\n");
for (lf = 0; lf < block->lf.max; lf++) {
reg = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL(lf));
seq_printf(filp, "CPT Lf[%u] CTL 0x%llx\n", lf, reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL2(lf));
seq_printf(filp, "CPT Lf[%u] CTL2 0x%llx\n", lf, reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_LFX_PTR_CTL(lf));
seq_printf(filp, "CPT Lf[%u] PTR_CTL 0x%llx\n", lf, reg);
reg = rvu_read64(rvu, blkaddr, block->lfcfg_reg |
(lf << block->lfshift));
seq_printf(filp, "CPT Lf[%u] CFG 0x%llx\n", lf, reg);
seq_puts(filp, "===========================================\n");
}
return 0;
}
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;
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));
seq_printf(filp, "CPT_AF_FLTX_INT: 0x%llx 0x%llx\n", reg0, reg1);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_PSNX_EXE(0));
reg1 = rvu_read64(rvu, blkaddr, CPT_AF_PSNX_EXE(1));
seq_printf(filp, "CPT_AF_PSNX_EXE: 0x%llx 0x%llx\n", reg0, reg1);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_PSNX_LF(0));
seq_printf(filp, "CPT_AF_PSNX_LF: 0x%llx\n", reg0);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_RVU_INT);
seq_printf(filp, "CPT_AF_RVU_INT: 0x%llx\n", reg0);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_RAS_INT);
seq_printf(filp, "CPT_AF_RAS_INT: 0x%llx\n", reg0);
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_EXE_ERR_INFO);
seq_printf(filp, "CPT_AF_EXE_ERR_INFO: 0x%llx\n", reg0);
return 0;
}
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;
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);
seq_printf(filp, "CPT instruction latency %llu\n", reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_RD_REQ_PC);
seq_printf(filp, "CPT NCB read requests %llu\n", reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_RD_LATENCY_PC);
seq_printf(filp, "CPT NCB read latency %llu\n", reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_RD_UC_PC);
seq_printf(filp, "CPT read requests caused by UC fills %llu\n", reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_ACTIVE_CYCLES_PC);
seq_printf(filp, "CPT active cycles pc %llu\n", reg);
reg = rvu_read64(rvu, blkaddr, CPT_AF_CPTCLK_CNT);
seq_printf(filp, "CPT clock count pc %llu\n", reg);
return 0;
}
RVU_DEBUG_SEQ_FOPS(cpt_pc, cpt_pc_display, NULL);
static void rvu_dbg_cpt_init(struct rvu *rvu)
{
const struct device *dev = &rvu->pdev->dev;
struct dentry *pfile;
if (!is_block_implemented(rvu->hw, BLKADDR_CPT0))
return;
rvu->rvu_dbg.cpt = debugfs_create_dir("cpt", rvu->rvu_dbg.root);
if (!rvu->rvu_dbg.cpt)
return;
pfile = debugfs_create_file("cpt_pc", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_pc_fops);
if (!pfile)
goto create_failed;
pfile = debugfs_create_file("cpt_ae_sts", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_ae_sts_fops);
if (!pfile)
goto create_failed;
pfile = debugfs_create_file("cpt_se_sts", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_se_sts_fops);
if (!pfile)
goto create_failed;
pfile = debugfs_create_file("cpt_ie_sts", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_ie_sts_fops);
if (!pfile)
goto create_failed;
pfile = debugfs_create_file("cpt_engines_info", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_engines_info_fops);
if (!pfile)
goto create_failed;
pfile = debugfs_create_file("cpt_lfs_info", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_lfs_info_fops);
if (!pfile)
goto create_failed;
pfile = debugfs_create_file("cpt_err_info", 0600,
rvu->rvu_dbg.cpt, rvu,
&rvu_dbg_cpt_err_info_fops);
if (!pfile)
goto create_failed;
return;
create_failed:
dev_err(dev, "Failed to create debugfs dir/file for CPT\n");
debugfs_remove_recursive(rvu->rvu_dbg.cpt);
}
void rvu_dbg_init(struct rvu *rvu)
{
struct device *dev = &rvu->pdev->dev;
......@@ -2019,6 +2290,7 @@ 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);
return;
......
......@@ -429,12 +429,63 @@
#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)
......
......@@ -16,6 +16,7 @@
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <linux/soc/marvell/octeontx2/asm.h>
#include <mbox.h>
#include <npc.h>
......@@ -462,21 +463,9 @@ static inline u64 otx2_atomic64_add(u64 incr, u64 *ptr)
return result;
}
static inline u64 otx2_lmt_flush(uint64_t addr)
{
u64 result = 0;
__asm__ volatile(".cpu generic+lse\n"
"ldeor xzr,%x[rf],[%[rs]]"
: [rf]"=r"(result)
: [rs]"r"(addr));
return result;
}
#else
#define otx2_write128(lo, hi, addr)
#define otx2_atomic64_add(incr, ptr) ({ *ptr += incr; })
#define otx2_lmt_flush(addr) ({ 0; })
#endif
/* Alloc pointer from pool/aura */
......
/* SPDX-License-Identifier: GPL-2.0-only
* Copyright (C) 2020 Marvell.
*/
#ifndef __SOC_OTX2_ASM_H
#define __SOC_OTX2_ASM_H
#if defined(CONFIG_ARM64)
/*
* otx2_lmt_flush is used for LMT store operation.
* On octeontx2 platform CPT instruction enqueue and
* NIX packet send are only possible via LMTST
* operations and it uses LDEOR instruction targeting
* the coprocessor address.
*/
#define otx2_lmt_flush(ioaddr) \
({ \
u64 result = 0; \
__asm__ volatile(".cpu generic+lse\n" \
"ldeor xzr, %x[rf], [%[rs]]" \
: [rf]"=r" (result) \
: [rs]"r" (ioaddr)); \
(result); \
})
#else
#define otx2_lmt_flush(ioaddr) ({ 0; })
#endif
#endif /* __SOC_OTX2_ASM_H */
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