Commit 40088915 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'octeontx2-af-miscellaneous-changes-for-cpt'

Srujana Challa says:

====================
octeontx2-af: Miscellaneous changes for CPT

This patchset consists of miscellaneous changes for CPT.
First patch enables the CPT HW interrupts, second patch
adds support for CPT LF teardown in non FLR path and
final patch does CPT CTX flush in FLR handler.

v2:
- Fixed a warning reported by kernel test robot.
====================

Link: https://lore.kernel.org/r/20211013055621.1812301-1-schalla@marvell.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a3d70892 149f3b73
......@@ -191,6 +191,7 @@ M(CPT_INLINE_IPSEC_CFG, 0xA04, cpt_inline_ipsec_cfg, \
M(CPT_STATS, 0xA05, cpt_sts, cpt_sts_req, cpt_sts_rsp) \
M(CPT_RXC_TIME_CFG, 0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req, \
msg_rsp) \
M(CPT_CTX_CACHE_SYNC, 0xA07, cpt_ctx_cache_sync, msg_req, msg_rsp) \
/* SDP mbox IDs (range 0x1000 - 0x11FF) */ \
M(SET_SDP_CHAN_INFO, 0x1000, set_sdp_chan_info, sdp_chan_info_msg, msg_rsp) \
M(GET_SDP_CHAN_INFO, 0x1001, get_sdp_chan_info, msg_req, sdp_get_chan_info_msg) \
......@@ -292,10 +293,14 @@ M(NIX_BANDPROF_GET_HWINFO, 0x801f, nix_bandprof_get_hwinfo, msg_req, \
#define MBOX_UP_CGX_MESSAGES \
M(CGX_LINK_EVENT, 0xC00, cgx_link_event, cgx_link_info_msg, msg_rsp)
#define MBOX_UP_CPT_MESSAGES \
M(CPT_INST_LMTST, 0xD00, cpt_inst_lmtst, cpt_inst_lmtst_req, msg_rsp)
enum {
#define M(_name, _id, _1, _2, _3) MBOX_MSG_ ## _name = _id,
MBOX_MESSAGES
MBOX_UP_CGX_MESSAGES
MBOX_UP_CPT_MESSAGES
#undef M
};
......@@ -1562,6 +1567,13 @@ struct cpt_rxc_time_cfg_req {
u16 active_limit;
};
/* Mailbox message request format to request for CPT_INST_S lmtst. */
struct cpt_inst_lmtst_req {
struct mbox_msghdr hdr;
u64 inst[8];
u64 rsvd;
};
struct sdp_node_info {
/* Node to which this PF belons to */
u8 node_id;
......
......@@ -854,6 +854,7 @@ static int rvu_setup_nix_hw_resource(struct rvu *rvu, int blkaddr)
block->lfcfg_reg = NIX_PRIV_LFX_CFG;
block->msixcfg_reg = NIX_PRIV_LFX_INT_CFG;
block->lfreset_reg = NIX_AF_LF_RST;
block->rvu = rvu;
sprintf(block->name, "NIX%d", blkid);
rvu->nix_blkaddr[blkid] = blkaddr;
return rvu_alloc_bitmap(&block->lf);
......@@ -883,6 +884,7 @@ static int rvu_setup_cpt_hw_resource(struct rvu *rvu, int blkaddr)
block->lfcfg_reg = CPT_PRIV_LFX_CFG;
block->msixcfg_reg = CPT_PRIV_LFX_INT_CFG;
block->lfreset_reg = CPT_AF_LF_RST;
block->rvu = rvu;
sprintf(block->name, "CPT%d", blkid);
return rvu_alloc_bitmap(&block->lf);
}
......@@ -940,6 +942,7 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
block->lfcfg_reg = NPA_PRIV_LFX_CFG;
block->msixcfg_reg = NPA_PRIV_LFX_INT_CFG;
block->lfreset_reg = NPA_AF_LF_RST;
block->rvu = rvu;
sprintf(block->name, "NPA");
err = rvu_alloc_bitmap(&block->lf);
if (err) {
......@@ -979,6 +982,7 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
block->lfcfg_reg = SSO_PRIV_LFX_HWGRP_CFG;
block->msixcfg_reg = SSO_PRIV_LFX_HWGRP_INT_CFG;
block->lfreset_reg = SSO_AF_LF_HWGRP_RST;
block->rvu = rvu;
sprintf(block->name, "SSO GROUP");
err = rvu_alloc_bitmap(&block->lf);
if (err) {
......@@ -1003,6 +1007,7 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
block->lfcfg_reg = SSOW_PRIV_LFX_HWS_CFG;
block->msixcfg_reg = SSOW_PRIV_LFX_HWS_INT_CFG;
block->lfreset_reg = SSOW_AF_LF_HWS_RST;
block->rvu = rvu;
sprintf(block->name, "SSOWS");
err = rvu_alloc_bitmap(&block->lf);
if (err) {
......@@ -1028,6 +1033,7 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
block->lfcfg_reg = TIM_PRIV_LFX_CFG;
block->msixcfg_reg = TIM_PRIV_LFX_INT_CFG;
block->lfreset_reg = TIM_AF_LF_RST;
block->rvu = rvu;
sprintf(block->name, "TIM");
err = rvu_alloc_bitmap(&block->lf);
if (err) {
......@@ -2526,7 +2532,8 @@ static void rvu_blklf_teardown(struct rvu *rvu, u16 pcifunc, u8 blkaddr)
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);
rvu_cpt_lf_teardown(rvu, pcifunc, block->addr, lf,
slot);
err = rvu_lf_reset(rvu, block, lf);
if (err) {
......@@ -2724,6 +2731,8 @@ static void rvu_unregister_interrupts(struct rvu *rvu)
{
int irq;
rvu_cpt_unregister_interrupts(rvu);
/* Disable the Mbox interrupt */
rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT_ENA_W1C,
INTR_MASK(rvu->hw->total_pfs) & ~1ULL);
......@@ -2933,6 +2942,11 @@ static int rvu_register_interrupts(struct rvu *rvu)
goto fail;
}
rvu->irq_allocated[offset] = true;
ret = rvu_cpt_register_interrupts(rvu);
if (ret)
goto fail;
return 0;
fail:
......
......@@ -101,6 +101,7 @@ struct rvu_block {
u64 msixcfg_reg;
u64 lfreset_reg;
unsigned char name[NAME_SIZE];
struct rvu *rvu;
};
struct nix_mcast {
......@@ -812,7 +813,11 @@ bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
int index);
/* CPT APIs */
int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot);
int rvu_cpt_register_interrupts(struct rvu *rvu);
void rvu_cpt_unregister_interrupts(struct rvu *rvu);
int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf,
int slot);
int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc);
/* CN10K RVU */
int rvu_set_channels_base(struct rvu *rvu);
......
......@@ -37,6 +37,236 @@
(_rsp)->free_sts_##etype = free_sts; \
})
static irqreturn_t rvu_cpt_af_flt_intr_handler(int irq, void *ptr)
{
struct rvu_block *block = ptr;
struct rvu *rvu = block->rvu;
int blkaddr = block->addr;
u64 reg0, reg1, reg2;
reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0));
reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1));
if (!is_rvu_otx2(rvu)) {
reg2 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(2));
dev_err_ratelimited(rvu->dev,
"Received CPTAF FLT irq : 0x%llx, 0x%llx, 0x%llx",
reg0, reg1, reg2);
} else {
dev_err_ratelimited(rvu->dev,
"Received CPTAF FLT irq : 0x%llx, 0x%llx",
reg0, reg1);
}
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(0), reg0);
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(1), reg1);
if (!is_rvu_otx2(rvu))
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(2), reg2);
return IRQ_HANDLED;
}
static irqreturn_t rvu_cpt_af_rvu_intr_handler(int irq, void *ptr)
{
struct rvu_block *block = ptr;
struct rvu *rvu = block->rvu;
int blkaddr = block->addr;
u64 reg;
reg = rvu_read64(rvu, blkaddr, CPT_AF_RVU_INT);
dev_err_ratelimited(rvu->dev, "Received CPTAF RVU irq : 0x%llx", reg);
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT, reg);
return IRQ_HANDLED;
}
static irqreturn_t rvu_cpt_af_ras_intr_handler(int irq, void *ptr)
{
struct rvu_block *block = ptr;
struct rvu *rvu = block->rvu;
int blkaddr = block->addr;
u64 reg;
reg = rvu_read64(rvu, blkaddr, CPT_AF_RAS_INT);
dev_err_ratelimited(rvu->dev, "Received CPTAF RAS irq : 0x%llx", reg);
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT, reg);
return IRQ_HANDLED;
}
static int rvu_cpt_do_register_interrupt(struct rvu_block *block, int irq_offs,
irq_handler_t handler,
const char *name)
{
struct rvu *rvu = block->rvu;
int ret;
ret = request_irq(pci_irq_vector(rvu->pdev, irq_offs), handler, 0,
name, block);
if (ret) {
dev_err(rvu->dev, "RVUAF: %s irq registration failed", name);
return ret;
}
WARN_ON(rvu->irq_allocated[irq_offs]);
rvu->irq_allocated[irq_offs] = true;
return 0;
}
static void cpt_10k_unregister_interrupts(struct rvu_block *block, int off)
{
struct rvu *rvu = block->rvu;
int blkaddr = block->addr;
int i;
/* Disable all CPT AF interrupts */
for (i = 0; i < CPT_10K_AF_INT_VEC_RVU; i++)
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1);
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1);
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1);
for (i = 0; i < CPT_10K_AF_INT_VEC_CNT; i++)
if (rvu->irq_allocated[off + i]) {
free_irq(pci_irq_vector(rvu->pdev, off + i), block);
rvu->irq_allocated[off + i] = false;
}
}
static void cpt_unregister_interrupts(struct rvu *rvu, int blkaddr)
{
struct rvu_hwinfo *hw = rvu->hw;
struct rvu_block *block;
int i, offs;
if (!is_block_implemented(rvu->hw, blkaddr))
return;
offs = rvu_read64(rvu, blkaddr, CPT_PRIV_AF_INT_CFG) & 0x7FF;
if (!offs) {
dev_warn(rvu->dev,
"Failed to get CPT_AF_INT vector offsets\n");
return;
}
block = &hw->block[blkaddr];
if (!is_rvu_otx2(rvu))
return cpt_10k_unregister_interrupts(block, offs);
/* Disable all CPT AF interrupts */
for (i = 0; i < CPT_AF_INT_VEC_RVU; i++)
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1);
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1);
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1);
for (i = 0; i < CPT_AF_INT_VEC_CNT; i++)
if (rvu->irq_allocated[offs + i]) {
free_irq(pci_irq_vector(rvu->pdev, offs + i), block);
rvu->irq_allocated[offs + i] = false;
}
}
void rvu_cpt_unregister_interrupts(struct rvu *rvu)
{
cpt_unregister_interrupts(rvu, BLKADDR_CPT0);
cpt_unregister_interrupts(rvu, BLKADDR_CPT1);
}
static int cpt_10k_register_interrupts(struct rvu_block *block, int off)
{
struct rvu *rvu = block->rvu;
int blkaddr = block->addr;
char irq_name[16];
int i, ret;
for (i = CPT_10K_AF_INT_VEC_FLT0; i < CPT_10K_AF_INT_VEC_RVU; i++) {
snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i);
ret = rvu_cpt_do_register_interrupt(block, off + i,
rvu_cpt_af_flt_intr_handler,
irq_name);
if (ret)
goto err;
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1);
}
ret = rvu_cpt_do_register_interrupt(block, off + CPT_10K_AF_INT_VEC_RVU,
rvu_cpt_af_rvu_intr_handler,
"CPTAF RVU");
if (ret)
goto err;
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1S, 0x1);
ret = rvu_cpt_do_register_interrupt(block, off + CPT_10K_AF_INT_VEC_RAS,
rvu_cpt_af_ras_intr_handler,
"CPTAF RAS");
if (ret)
goto err;
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1S, 0x1);
return 0;
err:
rvu_cpt_unregister_interrupts(rvu);
return ret;
}
static int cpt_register_interrupts(struct rvu *rvu, int blkaddr)
{
struct rvu_hwinfo *hw = rvu->hw;
struct rvu_block *block;
int i, offs, ret = 0;
char irq_name[16];
if (!is_block_implemented(rvu->hw, blkaddr))
return 0;
block = &hw->block[blkaddr];
offs = rvu_read64(rvu, blkaddr, CPT_PRIV_AF_INT_CFG) & 0x7FF;
if (!offs) {
dev_warn(rvu->dev,
"Failed to get CPT_AF_INT vector offsets\n");
return 0;
}
if (!is_rvu_otx2(rvu))
return cpt_10k_register_interrupts(block, offs);
for (i = CPT_AF_INT_VEC_FLT0; i < CPT_AF_INT_VEC_RVU; i++) {
snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i);
ret = rvu_cpt_do_register_interrupt(block, offs + i,
rvu_cpt_af_flt_intr_handler,
irq_name);
if (ret)
goto err;
rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1);
}
ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RVU,
rvu_cpt_af_rvu_intr_handler,
"CPTAF RVU");
if (ret)
goto err;
rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1S, 0x1);
ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RAS,
rvu_cpt_af_ras_intr_handler,
"CPTAF RAS");
if (ret)
goto err;
rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1S, 0x1);
return 0;
err:
rvu_cpt_unregister_interrupts(rvu);
return ret;
}
int rvu_cpt_register_interrupts(struct rvu *rvu)
{
int ret;
ret = cpt_register_interrupts(rvu, BLKADDR_CPT0);
if (ret)
return ret;
return cpt_register_interrupts(rvu, BLKADDR_CPT1);
}
static int get_cpt_pf_num(struct rvu *rvu)
{
int i, domain_nr, cpt_pf_num = -1;
......@@ -147,9 +377,13 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu,
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;
/* Set CPT LF NIX_PF_FUNC and SSO_PF_FUNC. EXE_LDWB is set
* on reset.
*/
val = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf));
val &= ~(GENMASK_ULL(63, 48) | GENMASK_ULL(47, 32));
val |= ((u64)req->nix_pf_func << 48 |
(u64)req->sso_pf_func << 32);
rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf), val);
}
......@@ -159,7 +393,7 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu,
static int cpt_lf_free(struct rvu *rvu, struct msg_req *req, int blkaddr)
{
u16 pcifunc = req->hdr.pcifunc;
int num_lfs, cptlf, slot;
int num_lfs, cptlf, slot, err;
struct rvu_block *block;
block = &rvu->hw->block[blkaddr];
......@@ -173,10 +407,15 @@ static int cpt_lf_free(struct rvu *rvu, struct msg_req *req, int blkaddr)
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);
/* Perform teardown */
rvu_cpt_lf_teardown(rvu, pcifunc, blkaddr, cptlf, slot);
/* Reset LF */
err = rvu_lf_reset(rvu, block, cptlf);
if (err) {
dev_err(rvu->dev, "Failed to reset blkaddr %d LF%d\n",
block->addr, cptlf);
}
}
return 0;
......@@ -556,6 +795,58 @@ int rvu_mbox_handler_cpt_rxc_time_cfg(struct rvu *rvu,
return 0;
}
int rvu_mbox_handler_cpt_ctx_cache_sync(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp)
{
return rvu_cpt_ctx_flush(rvu, req->hdr.pcifunc);
}
static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr)
{
struct cpt_rxc_time_cfg_req req;
int timeout = 2000;
u64 reg;
if (is_rvu_otx2(rvu))
return;
/* Set time limit to minimum values, so that rxc entries will be
* flushed out quickly.
*/
req.step = 1;
req.zombie_thres = 1;
req.zombie_limit = 1;
req.active_thres = 1;
req.active_limit = 1;
cpt_rxc_time_cfg(rvu, &req, blkaddr);
do {
reg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_ACTIVE_STS);
udelay(1);
if (FIELD_GET(RXC_ACTIVE_COUNT, reg))
timeout--;
else
break;
} while (timeout);
if (timeout == 0)
dev_warn(rvu->dev, "Poll for RXC active count hits hard loop counter\n");
timeout = 2000;
do {
reg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_ZOMBIE_STS);
udelay(1);
if (FIELD_GET(RXC_ZOMBIE_COUNT, reg))
timeout--;
else
break;
} while (timeout);
if (timeout == 0)
dev_warn(rvu->dev, "Poll for RXC zombie count hits hard loop counter\n");
}
#define INPROG_INFLIGHT(reg) ((reg) & 0x1FF)
#define INPROG_GRB_PARTIAL(reg) ((reg) & BIT_ULL(31))
#define INPROG_GRB(reg) (((reg) >> 32) & 0xFF)
......@@ -620,14 +911,12 @@ static void cpt_lf_disable_iqueue(struct rvu *rvu, int blkaddr, int slot)
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 rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, 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;
if (is_cpt_pf(rvu, pcifunc) || is_cpt_vf(rvu, pcifunc))
cpt_rxc_teardown(rvu, blkaddr);
/* Enable BAR2 ALIAS for this pcifunc. */
reg = BIT_ULL(16) | pcifunc;
......@@ -644,3 +933,154 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot)
return 0;
}
#define CPT_RES_LEN 16
#define CPT_SE_IE_EGRP 1ULL
static int cpt_inline_inb_lf_cmd_send(struct rvu *rvu, int blkaddr,
int nix_blkaddr)
{
int cpt_pf_num = get_cpt_pf_num(rvu);
struct cpt_inst_lmtst_req *req;
dma_addr_t res_daddr;
int timeout = 3000;
u8 cpt_idx;
u64 *inst;
u16 *res;
int rc;
res = kzalloc(CPT_RES_LEN, GFP_KERNEL);
if (!res)
return -ENOMEM;
res_daddr = dma_map_single(rvu->dev, res, CPT_RES_LEN,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(rvu->dev, res_daddr)) {
dev_err(rvu->dev, "DMA mapping failed for CPT result\n");
rc = -EFAULT;
goto res_free;
}
*res = 0xFFFF;
/* Send mbox message to CPT PF */
req = (struct cpt_inst_lmtst_req *)
otx2_mbox_alloc_msg_rsp(&rvu->afpf_wq_info.mbox_up,
cpt_pf_num, sizeof(*req),
sizeof(struct msg_rsp));
if (!req) {
rc = -ENOMEM;
goto res_daddr_unmap;
}
req->hdr.sig = OTX2_MBOX_REQ_SIG;
req->hdr.id = MBOX_MSG_CPT_INST_LMTST;
inst = req->inst;
/* Prepare CPT_INST_S */
inst[0] = 0;
inst[1] = res_daddr;
/* AF PF FUNC */
inst[2] = 0;
/* Set QORD */
inst[3] = 1;
inst[4] = 0;
inst[5] = 0;
inst[6] = 0;
/* Set EGRP */
inst[7] = CPT_SE_IE_EGRP << 61;
/* Subtract 1 from the NIX-CPT credit count to preserve
* credit counts.
*/
cpt_idx = (blkaddr == BLKADDR_CPT0) ? 0 : 1;
rvu_write64(rvu, nix_blkaddr, NIX_AF_RX_CPTX_CREDIT(cpt_idx),
BIT_ULL(22) - 1);
otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, cpt_pf_num);
rc = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, cpt_pf_num);
if (rc)
dev_warn(rvu->dev, "notification to pf %d failed\n",
cpt_pf_num);
/* Wait for CPT instruction to be completed */
do {
mdelay(1);
if (*res == 0xFFFF)
timeout--;
else
break;
} while (timeout);
if (timeout == 0)
dev_warn(rvu->dev, "Poll for result hits hard loop counter\n");
res_daddr_unmap:
dma_unmap_single(rvu->dev, res_daddr, CPT_RES_LEN, DMA_BIDIRECTIONAL);
res_free:
kfree(res);
return 0;
}
#define CTX_CAM_PF_FUNC GENMASK_ULL(61, 46)
#define CTX_CAM_CPTR GENMASK_ULL(45, 0)
int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc)
{
int nix_blkaddr, blkaddr;
u16 max_ctx_entries, i;
int slot = 0, num_lfs;
u64 reg, cam_data;
int rc;
nix_blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
if (nix_blkaddr < 0)
return -EINVAL;
if (is_rvu_otx2(rvu))
return 0;
blkaddr = (nix_blkaddr == BLKADDR_NIX1) ? BLKADDR_CPT1 : BLKADDR_CPT0;
/* Submit CPT_INST_S to track when all packets have been
* flushed through for the NIX PF FUNC in inline inbound case.
*/
rc = cpt_inline_inb_lf_cmd_send(rvu, blkaddr, nix_blkaddr);
if (rc)
return rc;
/* Wait for rxc entries to be flushed out */
cpt_rxc_teardown(rvu, blkaddr);
reg = rvu_read64(rvu, blkaddr, CPT_AF_CONSTANTS0);
max_ctx_entries = (reg >> 48) & 0xFFF;
mutex_lock(&rvu->rsrc_lock);
num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, pcifunc),
blkaddr);
if (num_lfs == 0) {
dev_warn(rvu->dev, "CPT LF is not configured\n");
goto unlock;
}
/* Enable BAR2 ALIAS for this pcifunc. */
reg = BIT_ULL(16) | pcifunc;
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg);
for (i = 0; i < max_ctx_entries; i++) {
cam_data = rvu_read64(rvu, blkaddr, CPT_AF_CTX_CAM_DATA(i));
if ((FIELD_GET(CTX_CAM_PF_FUNC, cam_data) == pcifunc) &&
FIELD_GET(CTX_CAM_CPTR, cam_data)) {
reg = BIT_ULL(46) | FIELD_GET(CTX_CAM_CPTR, cam_data);
rvu_write64(rvu, blkaddr,
CPT_AF_BAR2_ALIASX(slot, CPT_LF_CTX_FLUSH),
reg);
}
}
rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0);
unlock:
mutex_unlock(&rvu->rsrc_lock);
return 0;
}
......@@ -4512,6 +4512,8 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
return rvu_cgx_start_stop_io(rvu, pcifunc, false);
}
#define RX_SA_BASE GENMASK_ULL(52, 7)
void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
......@@ -4519,6 +4521,7 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
int pf = rvu_get_pf(pcifunc);
struct mac_ops *mac_ops;
u8 cgx_id, lmac_id;
u64 sa_base;
void *cgxd;
int err;
......@@ -4575,6 +4578,14 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
nix_ctx_free(rvu, pfvf);
nix_free_all_bandprof(rvu, pcifunc);
sa_base = rvu_read64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_SA_BASE(nixlf));
if (FIELD_GET(RX_SA_BASE, sa_base)) {
err = rvu_cpt_ctx_flush(rvu, pcifunc);
if (err)
dev_err(rvu->dev,
"CPT ctx flush failed with error: %d\n", err);
}
}
#define NIX_AF_LFX_TX_CFG_PTP_EN BIT_ULL(32)
......
......@@ -527,6 +527,7 @@
#define CPT_AF_CTX_WBACK_LATENCY_PC (0x49448ull)
#define CPT_AF_CTX_PSH_PC (0x49450ull)
#define CPT_AF_CTX_PSH_LATENCY_PC (0x49458ull)
#define CPT_AF_CTX_CAM_DATA(a) (0x49800ull | (u64)(a) << 3)
#define CPT_AF_RXC_TIME (0x50010ull)
#define CPT_AF_RXC_TIME_CFG (0x50018ull)
#define CPT_AF_RXC_DFRG (0x50020ull)
......@@ -544,6 +545,7 @@
#define CPT_LF_CTL 0x10
#define CPT_LF_INPROG 0x40
#define CPT_LF_Q_GRP_PTR 0x120
#define CPT_LF_CTX_FLUSH 0x510
#define NPC_AF_BLK_RST (0x00040)
......
......@@ -62,6 +62,24 @@ enum rvu_af_int_vec_e {
RVU_AF_INT_VEC_CNT = 0x5,
};
/* CPT Admin function Interrupt Vector Enumeration */
enum cpt_af_int_vec_e {
CPT_AF_INT_VEC_FLT0 = 0x0,
CPT_AF_INT_VEC_FLT1 = 0x1,
CPT_AF_INT_VEC_RVU = 0x2,
CPT_AF_INT_VEC_RAS = 0x3,
CPT_AF_INT_VEC_CNT = 0x4,
};
enum cpt_10k_af_int_vec_e {
CPT_10K_AF_INT_VEC_FLT0 = 0x0,
CPT_10K_AF_INT_VEC_FLT1 = 0x1,
CPT_10K_AF_INT_VEC_FLT2 = 0x2,
CPT_10K_AF_INT_VEC_RVU = 0x3,
CPT_10K_AF_INT_VEC_RAS = 0x4,
CPT_10K_AF_INT_VEC_CNT = 0x5,
};
/* NPA Admin function Interrupt Vector Enumeration */
enum npa_af_int_vec_e {
NPA_AF_INT_VEC_RVU = 0x0,
......
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