Skip to content

Commit

Permalink
octeontx2-af: Enable CPT HW interrupts
Browse files Browse the repository at this point in the history
This patch enables and registers interrupt handler for CPT HW
interrupts.

Signed-off-by: Srujana Challa <schalla@marvell.com>
  • Loading branch information
SruChalla authored and intel-lab-lkp committed Oct 11, 2021
1 parent 0182d07 commit 4678bed
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 0 deletions.
13 changes: 13 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -2724,6 +2730,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);
Expand Down Expand Up @@ -2933,6 +2941,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:
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct rvu_block {
u64 msixcfg_reg;
u64 lfreset_reg;
unsigned char name[NAME_SIZE];
struct rvu *rvu;
};

struct nix_mcast {
Expand Down Expand Up @@ -812,6 +813,8 @@ bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
int index);

/* CPT APIs */
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 lf, int slot);

/* CN10K RVU */
Expand Down
228 changes: 228 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,234 @@
(_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);
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;
Expand Down
18 changes: 18 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 4678bed

Please sign in to comment.