mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
crypto: octeontx2 - add support for AF to CPT PF uplink mbox
This patch adds support for AF -> CPT PF uplink mailbox messages and adds a mailbox handler to submit a CPT instruction from AF as current architecture doesn't allow AF to submit CPT instruction directly to HW. Signed-off-by: Srujana Challa <schalla@marvell.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
dee3590c34
commit
5c553114ce
@ -40,6 +40,9 @@ struct otx2_cptpf_dev {
|
||||
struct work_struct afpf_mbox_work;
|
||||
struct workqueue_struct *afpf_mbox_wq;
|
||||
|
||||
struct otx2_mbox afpf_mbox_up;
|
||||
struct work_struct afpf_mbox_up_work;
|
||||
|
||||
/* VF <=> PF mbox */
|
||||
struct otx2_mbox vfpf_mbox;
|
||||
struct workqueue_struct *vfpf_mbox_wq;
|
||||
@ -61,6 +64,7 @@ struct otx2_cptpf_dev {
|
||||
|
||||
irqreturn_t otx2_cptpf_afpf_mbox_intr(int irq, void *arg);
|
||||
void otx2_cptpf_afpf_mbox_handler(struct work_struct *work);
|
||||
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);
|
||||
|
||||
|
@ -473,10 +473,19 @@ static int cptpf_afpf_mbox_init(struct otx2_cptpf_dev *cptpf)
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = otx2_mbox_init(&cptpf->afpf_mbox_up, cptpf->afpf_mbox_base,
|
||||
pdev, cptpf->reg_base, MBOX_DIR_PFAF_UP, 1);
|
||||
if (err)
|
||||
goto mbox_cleanup;
|
||||
|
||||
INIT_WORK(&cptpf->afpf_mbox_work, otx2_cptpf_afpf_mbox_handler);
|
||||
INIT_WORK(&cptpf->afpf_mbox_up_work, otx2_cptpf_afpf_mbox_up_handler);
|
||||
mutex_init(&cptpf->lock);
|
||||
|
||||
return 0;
|
||||
|
||||
mbox_cleanup:
|
||||
otx2_mbox_destroy(&cptpf->afpf_mbox);
|
||||
error:
|
||||
destroy_workqueue(cptpf->afpf_mbox_wq);
|
||||
return err;
|
||||
@ -486,6 +495,7 @@ static void cptpf_afpf_mbox_destroy(struct otx2_cptpf_dev *cptpf)
|
||||
{
|
||||
destroy_workqueue(cptpf->afpf_mbox_wq);
|
||||
otx2_mbox_destroy(&cptpf->afpf_mbox);
|
||||
otx2_mbox_destroy(&cptpf->afpf_mbox_up);
|
||||
}
|
||||
|
||||
static ssize_t kvf_limits_show(struct device *dev,
|
||||
|
@ -224,14 +224,28 @@ void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
|
||||
irqreturn_t otx2_cptpf_afpf_mbox_intr(int __always_unused irq, void *arg)
|
||||
{
|
||||
struct otx2_cptpf_dev *cptpf = arg;
|
||||
struct otx2_mbox_dev *mdev;
|
||||
struct otx2_mbox *mbox;
|
||||
struct mbox_hdr *hdr;
|
||||
u64 intr;
|
||||
|
||||
/* Read the interrupt bits */
|
||||
intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT);
|
||||
|
||||
if (intr & 0x1ULL) {
|
||||
/* Schedule work queue function to process the MBOX request */
|
||||
queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);
|
||||
mbox = &cptpf->afpf_mbox;
|
||||
mdev = &mbox->dev[0];
|
||||
hdr = mdev->mbase + mbox->rx_start;
|
||||
if (hdr->num_msgs)
|
||||
/* Schedule work queue function to process the MBOX request */
|
||||
queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);
|
||||
|
||||
mbox = &cptpf->afpf_mbox_up;
|
||||
mdev = &mbox->dev[0];
|
||||
hdr = mdev->mbase + mbox->rx_start;
|
||||
if (hdr->num_msgs)
|
||||
/* Schedule work queue function to process the MBOX request */
|
||||
queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_up_work);
|
||||
/* Clear and ack the interrupt */
|
||||
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT,
|
||||
0x1ULL);
|
||||
@ -367,3 +381,71 @@ void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
|
||||
}
|
||||
otx2_mbox_reset(afpf_mbox, 0);
|
||||
}
|
||||
|
||||
static void handle_msg_cpt_inst_lmtst(struct otx2_cptpf_dev *cptpf,
|
||||
struct mbox_msghdr *msg)
|
||||
{
|
||||
struct cpt_inst_lmtst_req *req = (struct cpt_inst_lmtst_req *)msg;
|
||||
struct otx2_cptlfs_info *lfs = &cptpf->lfs;
|
||||
struct msg_rsp *rsp;
|
||||
|
||||
if (cptpf->lfs.lfs_num)
|
||||
lfs->ops->send_cmd((union otx2_cpt_inst_s *)req->inst, 1,
|
||||
&lfs->lf[0]);
|
||||
|
||||
rsp = (struct msg_rsp *)otx2_mbox_alloc_msg(&cptpf->afpf_mbox_up, 0,
|
||||
sizeof(*rsp));
|
||||
if (!rsp)
|
||||
return;
|
||||
|
||||
rsp->hdr.id = msg->id;
|
||||
rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
|
||||
rsp->hdr.pcifunc = 0;
|
||||
rsp->hdr.rc = 0;
|
||||
}
|
||||
|
||||
static void process_afpf_mbox_up_msg(struct otx2_cptpf_dev *cptpf,
|
||||
struct mbox_msghdr *msg)
|
||||
{
|
||||
if (msg->id >= MBOX_MSG_MAX) {
|
||||
dev_err(&cptpf->pdev->dev,
|
||||
"MBOX msg with unknown ID %d\n", msg->id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg->id) {
|
||||
case MBOX_MSG_CPT_INST_LMTST:
|
||||
handle_msg_cpt_inst_lmtst(cptpf, msg);
|
||||
break;
|
||||
default:
|
||||
otx2_reply_invalid_msg(&cptpf->afpf_mbox_up, 0, 0, msg->id);
|
||||
}
|
||||
}
|
||||
|
||||
void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work)
|
||||
{
|
||||
struct otx2_cptpf_dev *cptpf;
|
||||
struct otx2_mbox_dev *mdev;
|
||||
struct mbox_hdr *rsp_hdr;
|
||||
struct mbox_msghdr *msg;
|
||||
struct otx2_mbox *mbox;
|
||||
int offset, i;
|
||||
|
||||
cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_up_work);
|
||||
mbox = &cptpf->afpf_mbox_up;
|
||||
mdev = &mbox->dev[0];
|
||||
/* Sync mbox data into memory */
|
||||
smp_wmb();
|
||||
|
||||
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
for (i = 0; i < rsp_hdr->num_msgs; i++) {
|
||||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
|
||||
process_afpf_mbox_up_msg(cptpf, msg);
|
||||
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
}
|
||||
otx2_mbox_msg_send(mbox, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user