Commit 434c1cb9 authored by Nithin Dabilpuram's avatar Nithin Dabilpuram Committed by Herbert Xu

crypto: octeontx2 - register error interrupts for inline cptlf

Register errors interrupts for inline cptlf attached to PF driver
so that SMMU faults and other errors can be reported.
Signed-off-by: default avatarNithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent e9297111
...@@ -151,26 +151,14 @@ static void cptlf_set_misc_intrs(struct otx2_cptlfs_info *lfs, u8 enable) ...@@ -151,26 +151,14 @@ static void cptlf_set_misc_intrs(struct otx2_cptlfs_info *lfs, u8 enable)
irq_misc.u); 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; int slot;
/* Enable done interrupts */
for (slot = 0; slot < lfs->lfs_num; slot++) for (slot = 0; slot < lfs->lfs_num; slot++)
otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot, otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot, reg, 0x1);
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);
} }
static inline int cptlf_read_done_cnt(struct otx2_cptlf_info *lf) static inline int cptlf_read_done_cnt(struct otx2_cptlf_info *lf)
...@@ -257,24 +245,44 @@ static irqreturn_t cptlf_done_intr_handler(int irq, void *arg) ...@@ -257,24 +245,44 @@ static irqreturn_t cptlf_done_intr_handler(int irq, void *arg)
return IRQ_HANDLED; 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 (i = 0; i < lfs->lfs_num; i++) {
for (offs = 0; offs < OTX2_CPT_LF_MSIX_VECTORS; offs++) { if (!lfs->lf[i].is_irq_reg[irq_offs])
if (!lfs->lf[i].is_irq_reg[offs])
continue; continue;
vector = pci_irq_vector(lfs->pdev, vector = pci_irq_vector(lfs->pdev,
lfs->lf[i].msix_offset + offs); lfs->lf[i].msix_offset + irq_offs);
free_irq(vector, &lfs->lf[i]); free_irq(vector, &lfs->lf[i]);
lfs->lf[i].is_irq_reg[offs] = false; 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); CRYPTO_DEV_OCTEONTX2_CPT);
static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs, static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs,
...@@ -296,34 +304,53 @@ static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs, ...@@ -296,34 +304,53 @@ static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs,
return ret; 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; int irq_offs, ret, i;
for (i = 0; i < lfs->lfs_num; i++) {
irq_offs = OTX2_CPT_LF_INT_VEC_E_MISC; irq_offs = OTX2_CPT_LF_INT_VEC_E_MISC;
snprintf(lfs->lf[i].irq_name[irq_offs], 32, "CPTLF Misc%d", i); for (i = 0; i < lfs->lfs_num; 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, ret = cptlf_do_register_interrrupts(lfs, i, irq_offs,
cptlf_misc_intr_handler); cptlf_misc_intr_handler);
if (ret) if (ret)
goto free_irq; goto free_irq;
}
cptlf_set_misc_intrs(lfs, true);
return 0;
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; irq_offs = OTX2_CPT_LF_INT_VEC_E_DONE;
snprintf(lfs->lf[i].irq_name[irq_offs], 32, "OTX2_CPTLF Done%d", for (i = 0; i < lfs->lfs_num; i++) {
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, ret = cptlf_do_register_interrrupts(lfs, i, irq_offs,
cptlf_done_intr_handler); cptlf_done_intr_handler);
if (ret) if (ret)
goto free_irq; goto free_irq;
} }
cptlf_enable_intrs(lfs); cptlf_set_done_intrs(lfs, true);
return 0; return 0;
free_irq: free_irq:
otx2_cptlf_unregister_interrupts(lfs); otx2_cptlf_unregister_done_interrupts(lfs);
return ret; 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) void otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs)
{ {
......
...@@ -410,8 +410,10 @@ static inline void otx2_cptlf_set_dev_info(struct otx2_cptlfs_info *lfs, ...@@ -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 otx2_cptlf_init(struct otx2_cptlfs_info *lfs, u8 eng_grp_msk, int pri,
int lfs_num); int lfs_num);
void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs); void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs);
int otx2_cptlf_register_interrupts(struct otx2_cptlfs_info *lfs); int otx2_cptlf_register_misc_interrupts(struct otx2_cptlfs_info *lfs);
void otx2_cptlf_unregister_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); void otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs);
int otx2_cptlf_set_irqs_affinity(struct otx2_cptlfs_info *lfs); int otx2_cptlf_set_irqs_affinity(struct otx2_cptlfs_info *lfs);
......
...@@ -71,4 +71,8 @@ void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work); ...@@ -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); irqreturn_t otx2_cptpf_vfpf_mbox_intr(int irq, void *arg);
void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work); 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 */ #endif /* __OTX2_CPTPF_H */
...@@ -722,7 +722,7 @@ static int otx2_cptpf_probe(struct pci_dev *pdev, ...@@ -722,7 +722,7 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct otx2_cptpf_dev *cptpf; struct otx2_cptpf_dev *cptpf;
int err; int err, num_vec;
cptpf = devm_kzalloc(dev, sizeof(*cptpf), GFP_KERNEL); cptpf = devm_kzalloc(dev, sizeof(*cptpf), GFP_KERNEL);
if (!cptpf) if (!cptpf)
...@@ -757,8 +757,13 @@ static int otx2_cptpf_probe(struct pci_dev *pdev, ...@@ -757,8 +757,13 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
if (err) if (err)
goto clear_drvdata; goto clear_drvdata;
err = pci_alloc_irq_vectors(pdev, RVU_PF_INT_VEC_CNT, num_vec = pci_msix_vec_count(cptpf->pdev);
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX); 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) { if (err < 0) {
dev_err(dev, "Request for %d msix vectors failed\n", dev_err(dev, "Request for %d msix vectors failed\n",
RVU_PF_INT_VEC_CNT); RVU_PF_INT_VEC_CNT);
...@@ -823,6 +828,14 @@ static void otx2_cptpf_remove(struct pci_dev *pdev) ...@@ -823,6 +828,14 @@ static void otx2_cptpf_remove(struct pci_dev *pdev)
cptpf_sriov_disable(pdev); cptpf_sriov_disable(pdev);
otx2_cpt_unregister_dl(cptpf); 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 */ /* Delete sysfs entry created for kernel VF limits */
sysfs_remove_group(&pdev->dev.kobj, &cptpf_sysfs_group); sysfs_remove_group(&pdev->dev.kobj, &cptpf_sysfs_group);
/* Cleanup engine groups */ /* Cleanup engine groups */
......
...@@ -199,6 +199,47 @@ static int rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, u8 egrp, ...@@ -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); 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, static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
struct mbox_msghdr *req) struct mbox_msghdr *req)
{ {
...@@ -226,11 +267,9 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, ...@@ -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, otx2_cptlf_set_dev_info(&cptpf->lfs, cptpf->pdev, cptpf->reg_base,
&cptpf->afpf_mbox, BLKADDR_CPT0); &cptpf->afpf_mbox, BLKADDR_CPT0);
cptpf->lfs.global_slot = 0; cptpf->lfs.global_slot = 0;
ret = otx2_cptlf_init(&cptpf->lfs, 1 << egrp, OTX2_CPT_QUEUE_HI_PRIO, ret = otx2_inline_cptlf_setup(cptpf, &cptpf->lfs, egrp, num_lfs);
num_lfs);
if (ret) { if (ret) {
dev_err(&cptpf->pdev->dev, dev_err(&cptpf->pdev->dev, "Inline-Ipsec CPT0 LF setup failed.\n");
"LF configuration failed for RX inline ipsec.\n");
return ret; return ret;
} }
...@@ -240,11 +279,10 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, ...@@ -240,11 +279,10 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
cptpf->reg_base, &cptpf->afpf_mbox, cptpf->reg_base, &cptpf->afpf_mbox,
BLKADDR_CPT1); BLKADDR_CPT1);
cptpf->cpt1_lfs.global_slot = num_lfs; cptpf->cpt1_lfs.global_slot = num_lfs;
ret = otx2_cptlf_init(&cptpf->cpt1_lfs, 1 << egrp, ret = otx2_inline_cptlf_setup(cptpf, &cptpf->cpt1_lfs, egrp,
OTX2_CPT_QUEUE_HI_PRIO, num_lfs); num_lfs);
if (ret) { if (ret) {
dev_err(&cptpf->pdev->dev, dev_err(&cptpf->pdev->dev, "Inline CPT1 LF setup failed.\n");
"LF configuration failed for RX inline ipsec.\n");
goto lf_cleanup; goto lf_cleanup;
} }
cptpf->rsrc_req_blkaddr = 0; cptpf->rsrc_req_blkaddr = 0;
...@@ -257,9 +295,9 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, ...@@ -257,9 +295,9 @@ static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
return 0; return 0;
lf1_cleanup: lf1_cleanup:
otx2_cptlf_shutdown(&cptpf->cpt1_lfs); otx2_inline_cptlf_cleanup(&cptpf->cpt1_lfs);
lf_cleanup: lf_cleanup:
otx2_cptlf_shutdown(&cptpf->lfs); otx2_inline_cptlf_cleanup(&cptpf->lfs);
return ret; return ret;
} }
...@@ -414,6 +452,8 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf, ...@@ -414,6 +452,8 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
struct otx2_cptlfs_info *lfs = &cptpf->lfs; struct otx2_cptlfs_info *lfs = &cptpf->lfs;
struct device *dev = &cptpf->pdev->dev; struct device *dev = &cptpf->pdev->dev;
struct cpt_rd_wr_reg_msg *rsp_rd_wr; struct cpt_rd_wr_reg_msg *rsp_rd_wr;
struct msix_offset_rsp *rsp_msix;
int i;
if (msg->id >= MBOX_MSG_MAX) { if (msg->id >= MBOX_MSG_MAX) {
dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id); dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id);
...@@ -432,6 +472,14 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf, ...@@ -432,6 +472,14 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) & cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
RVU_PFVF_PF_MASK; RVU_PFVF_PF_MASK;
break; 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: case MBOX_MSG_CPT_RD_WR_REGISTER:
rsp_rd_wr = (struct cpt_rd_wr_reg_msg *)msg; rsp_rd_wr = (struct cpt_rd_wr_reg_msg *)msg;
if (msg->rc) { if (msg->rc) {
......
...@@ -246,7 +246,8 @@ static void cptvf_lf_shutdown(struct otx2_cptlfs_info *lfs) ...@@ -246,7 +246,8 @@ static void cptvf_lf_shutdown(struct otx2_cptlfs_info *lfs)
/* Unregister crypto algorithms */ /* Unregister crypto algorithms */
otx2_cpt_crypto_exit(lfs->pdev, THIS_MODULE); otx2_cpt_crypto_exit(lfs->pdev, THIS_MODULE);
/* Unregister LFs interrupts */ /* Unregister LFs interrupts */
otx2_cptlf_unregister_interrupts(lfs); otx2_cptlf_unregister_misc_interrupts(lfs);
otx2_cptlf_unregister_done_interrupts(lfs);
/* Cleanup LFs software side */ /* Cleanup LFs software side */
lf_sw_cleanup(lfs); lf_sw_cleanup(lfs);
/* Free instruction queues */ /* Free instruction queues */
...@@ -300,7 +301,11 @@ static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf) ...@@ -300,7 +301,11 @@ static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf)
goto cleanup_lf; goto cleanup_lf;
/* Register LFs interrupts */ /* 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) if (ret)
goto cleanup_lf_sw; goto cleanup_lf_sw;
...@@ -321,7 +326,8 @@ static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf) ...@@ -321,7 +326,8 @@ static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf)
disable_irqs: disable_irqs:
otx2_cptlf_free_irqs_affinity(lfs); otx2_cptlf_free_irqs_affinity(lfs);
unregister_intr: unregister_intr:
otx2_cptlf_unregister_interrupts(lfs); otx2_cptlf_unregister_misc_interrupts(lfs);
otx2_cptlf_unregister_done_interrupts(lfs);
cleanup_lf_sw: cleanup_lf_sw:
lf_sw_cleanup(lfs); lf_sw_cleanup(lfs);
cleanup_lf: cleanup_lf:
......
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