Skip to content

Commit

Permalink
crypto: octeontx2 - register error interrupts for inline cptlf
Browse files Browse the repository at this point in the history
Register errors interrupts for inline cptlf attached to PF driver
so that SMMU faults and other errors can be reported.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Nithin Dabilpuram authored and Herbert Xu committed Dec 29, 2023
1 parent e929711 commit 434c1cb
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 55 deletions.
101 changes: 64 additions & 37 deletions drivers/crypto/marvell/octeontx2/otx2_cptlf.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,26 +151,14 @@ static void cptlf_set_misc_intrs(struct otx2_cptlfs_info *lfs, u8 enable)
irq_misc.u);
}

static void cptlf_enable_intrs(struct otx2_cptlfs_info *lfs)
static void cptlf_set_done_intrs(struct otx2_cptlfs_info *lfs, u8 enable)
{
u64 reg = enable ? OTX2_CPT_LF_DONE_INT_ENA_W1S :
OTX2_CPT_LF_DONE_INT_ENA_W1C;
int slot;

/* Enable done interrupts */
for (slot = 0; slot < lfs->lfs_num; slot++)
otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot,
OTX2_CPT_LF_DONE_INT_ENA_W1S, 0x1);
/* Enable Misc interrupts */
cptlf_set_misc_intrs(lfs, true);
}

static void cptlf_disable_intrs(struct otx2_cptlfs_info *lfs)
{
int slot;

for (slot = 0; slot < lfs->lfs_num; slot++)
otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot,
OTX2_CPT_LF_DONE_INT_ENA_W1C, 0x1);
cptlf_set_misc_intrs(lfs, false);
otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot, reg, 0x1);
}

static inline int cptlf_read_done_cnt(struct otx2_cptlf_info *lf)
Expand Down Expand Up @@ -257,24 +245,44 @@ static irqreturn_t cptlf_done_intr_handler(int irq, void *arg)
return IRQ_HANDLED;
}

void otx2_cptlf_unregister_interrupts(struct otx2_cptlfs_info *lfs)
void otx2_cptlf_unregister_misc_interrupts(struct otx2_cptlfs_info *lfs)
{
int i, offs, vector;
int i, irq_offs, vector;

irq_offs = OTX2_CPT_LF_INT_VEC_E_MISC;
for (i = 0; i < lfs->lfs_num; i++) {
for (offs = 0; offs < OTX2_CPT_LF_MSIX_VECTORS; offs++) {
if (!lfs->lf[i].is_irq_reg[offs])
continue;
if (!lfs->lf[i].is_irq_reg[irq_offs])
continue;

vector = pci_irq_vector(lfs->pdev,
lfs->lf[i].msix_offset + offs);
free_irq(vector, &lfs->lf[i]);
lfs->lf[i].is_irq_reg[offs] = false;
}
vector = pci_irq_vector(lfs->pdev,
lfs->lf[i].msix_offset + irq_offs);
free_irq(vector, &lfs->lf[i]);
lfs->lf[i].is_irq_reg[irq_offs] = false;
}

cptlf_set_misc_intrs(lfs, false);
}
EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_misc_interrupts,
CRYPTO_DEV_OCTEONTX2_CPT);

void otx2_cptlf_unregister_done_interrupts(struct otx2_cptlfs_info *lfs)
{
int i, irq_offs, vector;

irq_offs = OTX2_CPT_LF_INT_VEC_E_DONE;
for (i = 0; i < lfs->lfs_num; i++) {
if (!lfs->lf[i].is_irq_reg[irq_offs])
continue;

vector = pci_irq_vector(lfs->pdev,
lfs->lf[i].msix_offset + irq_offs);
free_irq(vector, &lfs->lf[i]);
lfs->lf[i].is_irq_reg[irq_offs] = false;
}
cptlf_disable_intrs(lfs);

cptlf_set_done_intrs(lfs, false);
}
EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_interrupts,
EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_done_interrupts,
CRYPTO_DEV_OCTEONTX2_CPT);

static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs,
Expand All @@ -296,34 +304,53 @@ static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs,
return ret;
}

int otx2_cptlf_register_interrupts(struct otx2_cptlfs_info *lfs)
int otx2_cptlf_register_misc_interrupts(struct otx2_cptlfs_info *lfs)
{
bool is_cpt1 = (lfs->blkaddr == BLKADDR_CPT1);
int irq_offs, ret, i;

irq_offs = OTX2_CPT_LF_INT_VEC_E_MISC;
for (i = 0; i < lfs->lfs_num; i++) {
irq_offs = OTX2_CPT_LF_INT_VEC_E_MISC;
snprintf(lfs->lf[i].irq_name[irq_offs], 32, "CPTLF Misc%d", i);
snprintf(lfs->lf[i].irq_name[irq_offs], 32, "CPT%dLF Misc%d",
is_cpt1, i);
ret = cptlf_do_register_interrrupts(lfs, i, irq_offs,
cptlf_misc_intr_handler);
if (ret)
goto free_irq;
}
cptlf_set_misc_intrs(lfs, true);
return 0;

irq_offs = OTX2_CPT_LF_INT_VEC_E_DONE;
snprintf(lfs->lf[i].irq_name[irq_offs], 32, "OTX2_CPTLF Done%d",
i);
free_irq:
otx2_cptlf_unregister_misc_interrupts(lfs);
return ret;
}
EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_misc_interrupts,
CRYPTO_DEV_OCTEONTX2_CPT);

int otx2_cptlf_register_done_interrupts(struct otx2_cptlfs_info *lfs)
{
bool is_cpt1 = (lfs->blkaddr == BLKADDR_CPT1);
int irq_offs, ret, i;

irq_offs = OTX2_CPT_LF_INT_VEC_E_DONE;
for (i = 0; i < lfs->lfs_num; i++) {
snprintf(lfs->lf[i].irq_name[irq_offs], 32,
"OTX2_CPT%dLF Done%d", is_cpt1, i);
ret = cptlf_do_register_interrrupts(lfs, i, irq_offs,
cptlf_done_intr_handler);
if (ret)
goto free_irq;
}
cptlf_enable_intrs(lfs);
cptlf_set_done_intrs(lfs, true);
return 0;

free_irq:
otx2_cptlf_unregister_interrupts(lfs);
otx2_cptlf_unregister_done_interrupts(lfs);
return ret;
}
EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_interrupts, CRYPTO_DEV_OCTEONTX2_CPT);
EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_done_interrupts,
CRYPTO_DEV_OCTEONTX2_CPT);

void otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs)
{
Expand Down
6 changes: 4 additions & 2 deletions drivers/crypto/marvell/octeontx2/otx2_cptlf.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,10 @@ static inline void otx2_cptlf_set_dev_info(struct otx2_cptlfs_info *lfs,
int otx2_cptlf_init(struct otx2_cptlfs_info *lfs, u8 eng_grp_msk, int pri,
int lfs_num);
void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs);
int otx2_cptlf_register_interrupts(struct otx2_cptlfs_info *lfs);
void otx2_cptlf_unregister_interrupts(struct otx2_cptlfs_info *lfs);
int otx2_cptlf_register_misc_interrupts(struct otx2_cptlfs_info *lfs);
int otx2_cptlf_register_done_interrupts(struct otx2_cptlfs_info *lfs);
void otx2_cptlf_unregister_misc_interrupts(struct otx2_cptlfs_info *lfs);
void otx2_cptlf_unregister_done_interrupts(struct otx2_cptlfs_info *lfs);
void otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs);
int otx2_cptlf_set_irqs_affinity(struct otx2_cptlfs_info *lfs);

Expand Down
4 changes: 4 additions & 0 deletions drivers/crypto/marvell/octeontx2/otx2_cptpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,8 @@ void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work);
irqreturn_t otx2_cptpf_vfpf_mbox_intr(int irq, void *arg);
void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work);

int otx2_inline_cptlf_setup(struct otx2_cptpf_dev *cptpf,
struct otx2_cptlfs_info *lfs, u8 egrp, int num_lfs);
void otx2_inline_cptlf_cleanup(struct otx2_cptlfs_info *lfs);

#endif /* __OTX2_CPTPF_H */
19 changes: 16 additions & 3 deletions drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
{
struct device *dev = &pdev->dev;
struct otx2_cptpf_dev *cptpf;
int err;
int err, num_vec;

cptpf = devm_kzalloc(dev, sizeof(*cptpf), GFP_KERNEL);
if (!cptpf)
Expand Down Expand Up @@ -757,8 +757,13 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
if (err)
goto clear_drvdata;

err = pci_alloc_irq_vectors(pdev, RVU_PF_INT_VEC_CNT,
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
num_vec = pci_msix_vec_count(cptpf->pdev);
if (num_vec <= 0) {
err = -EINVAL;
goto clear_drvdata;
}

err = pci_alloc_irq_vectors(pdev, num_vec, num_vec, PCI_IRQ_MSIX);
if (err < 0) {
dev_err(dev, "Request for %d msix vectors failed\n",
RVU_PF_INT_VEC_CNT);
Expand Down Expand Up @@ -823,6 +828,14 @@ static void otx2_cptpf_remove(struct pci_dev *pdev)

cptpf_sriov_disable(pdev);
otx2_cpt_unregister_dl(cptpf);

/* Cleanup Inline CPT LF's if attached */
if (cptpf->lfs.lfs_num)
otx2_inline_cptlf_cleanup(&cptpf->lfs);

if (cptpf->cpt1_lfs.lfs_num)
otx2_inline_cptlf_cleanup(&cptpf->cpt1_lfs);

/* Delete sysfs entry created for kernel VF limits */
sysfs_remove_group(&pdev->dev.kobj, &cptpf_sysfs_group);
/* Cleanup engine groups */
Expand Down
68 changes: 58 additions & 10 deletions drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,47 @@ static int rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, u8 egrp,
return send_inline_ipsec_inbound_msg(cptpf, req->sso_pf_func, 0);
}

int
otx2_inline_cptlf_setup(struct otx2_cptpf_dev *cptpf,
struct otx2_cptlfs_info *lfs, u8 egrp, int num_lfs)
{
int ret;

ret = otx2_cptlf_init(lfs, 1 << egrp, OTX2_CPT_QUEUE_HI_PRIO, 1);
if (ret) {
dev_err(&cptpf->pdev->dev,
"LF configuration failed for RX inline ipsec.\n");
return ret;
}

/* Get msix offsets for attached LFs */
ret = otx2_cpt_msix_offset_msg(lfs);
if (ret)
goto cleanup_lf;

/* Register for CPT LF Misc interrupts */
ret = otx2_cptlf_register_misc_interrupts(lfs);
if (ret)
goto free_irq;

return 0;
free_irq:
otx2_cptlf_unregister_misc_interrupts(lfs);
cleanup_lf:
otx2_cptlf_shutdown(lfs);
return ret;
}

void
otx2_inline_cptlf_cleanup(struct otx2_cptlfs_info *lfs)
{
/* Unregister misc interrupt */
otx2_cptlf_unregister_misc_interrupts(lfs);

/* Cleanup LFs */
otx2_cptlf_shutdown(lfs);
}

static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
struct mbox_msghdr *req)
{
Expand Down Expand Up @@ -226,11 +267,9 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
otx2_cptlf_set_dev_info(&cptpf->lfs, cptpf->pdev, cptpf->reg_base,
&cptpf->afpf_mbox, BLKADDR_CPT0);
cptpf->lfs.global_slot = 0;
ret = otx2_cptlf_init(&cptpf->lfs, 1 << egrp, OTX2_CPT_QUEUE_HI_PRIO,
num_lfs);
ret = otx2_inline_cptlf_setup(cptpf, &cptpf->lfs, egrp, num_lfs);
if (ret) {
dev_err(&cptpf->pdev->dev,
"LF configuration failed for RX inline ipsec.\n");
dev_err(&cptpf->pdev->dev, "Inline-Ipsec CPT0 LF setup failed.\n");
return ret;
}

Expand All @@ -240,11 +279,10 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
cptpf->reg_base, &cptpf->afpf_mbox,
BLKADDR_CPT1);
cptpf->cpt1_lfs.global_slot = num_lfs;
ret = otx2_cptlf_init(&cptpf->cpt1_lfs, 1 << egrp,
OTX2_CPT_QUEUE_HI_PRIO, num_lfs);
ret = otx2_inline_cptlf_setup(cptpf, &cptpf->cpt1_lfs, egrp,
num_lfs);
if (ret) {
dev_err(&cptpf->pdev->dev,
"LF configuration failed for RX inline ipsec.\n");
dev_err(&cptpf->pdev->dev, "Inline CPT1 LF setup failed.\n");
goto lf_cleanup;
}
cptpf->rsrc_req_blkaddr = 0;
Expand All @@ -257,9 +295,9 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
return 0;

lf1_cleanup:
otx2_cptlf_shutdown(&cptpf->cpt1_lfs);
otx2_inline_cptlf_cleanup(&cptpf->cpt1_lfs);
lf_cleanup:
otx2_cptlf_shutdown(&cptpf->lfs);
otx2_inline_cptlf_cleanup(&cptpf->lfs);
return ret;
}

Expand Down Expand Up @@ -414,6 +452,8 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
struct otx2_cptlfs_info *lfs = &cptpf->lfs;
struct device *dev = &cptpf->pdev->dev;
struct cpt_rd_wr_reg_msg *rsp_rd_wr;
struct msix_offset_rsp *rsp_msix;
int i;

if (msg->id >= MBOX_MSG_MAX) {
dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id);
Expand All @@ -432,6 +472,14 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
RVU_PFVF_PF_MASK;
break;
case MBOX_MSG_MSIX_OFFSET:
rsp_msix = (struct msix_offset_rsp *) msg;
for (i = 0; i < rsp_msix->cptlfs; i++)
lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i];

for (i = 0; i < rsp_msix->cpt1_lfs; i++)
lfs->lf[i].msix_offset = rsp_msix->cpt1_lf_msixoff[i];
break;
case MBOX_MSG_CPT_RD_WR_REGISTER:
rsp_rd_wr = (struct cpt_rd_wr_reg_msg *)msg;
if (msg->rc) {
Expand Down
12 changes: 9 additions & 3 deletions drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ static void cptvf_lf_shutdown(struct otx2_cptlfs_info *lfs)
/* Unregister crypto algorithms */
otx2_cpt_crypto_exit(lfs->pdev, THIS_MODULE);
/* Unregister LFs interrupts */
otx2_cptlf_unregister_interrupts(lfs);
otx2_cptlf_unregister_misc_interrupts(lfs);
otx2_cptlf_unregister_done_interrupts(lfs);
/* Cleanup LFs software side */
lf_sw_cleanup(lfs);
/* Free instruction queues */
Expand Down Expand Up @@ -300,7 +301,11 @@ static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf)
goto cleanup_lf;

/* Register LFs interrupts */
ret = otx2_cptlf_register_interrupts(lfs);
ret = otx2_cptlf_register_misc_interrupts(lfs);
if (ret)
goto cleanup_lf_sw;

ret = otx2_cptlf_register_done_interrupts(lfs);
if (ret)
goto cleanup_lf_sw;

Expand All @@ -321,7 +326,8 @@ static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf)
disable_irqs:
otx2_cptlf_free_irqs_affinity(lfs);
unregister_intr:
otx2_cptlf_unregister_interrupts(lfs);
otx2_cptlf_unregister_misc_interrupts(lfs);
otx2_cptlf_unregister_done_interrupts(lfs);
cleanup_lf_sw:
lf_sw_cleanup(lfs);
cleanup_lf:
Expand Down

0 comments on commit 434c1cb

Please sign in to comment.