Path: blob/master/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
26285 views
// SPDX-License-Identifier: GPL-2.0-only1/* Copyright (C) 2020 Marvell. */23#include "otx2_cpt_common.h"4#include "otx2_cptvf.h"5#include <rvu_reg.h>67int otx2_cpt_mbox_bbuf_init(struct otx2_cptvf_dev *cptvf, struct pci_dev *pdev)8{9struct otx2_mbox_dev *mdev;10struct otx2_mbox *otx2_mbox;1112cptvf->bbuf_base = devm_kmalloc(&pdev->dev, MBOX_SIZE, GFP_KERNEL);13if (!cptvf->bbuf_base)14return -ENOMEM;15/*16* Overwrite mbox mbase to point to bounce buffer, so that PF/VF17* prepare all mbox messages in bounce buffer instead of directly18* in hw mbox memory.19*/20otx2_mbox = &cptvf->pfvf_mbox;21mdev = &otx2_mbox->dev[0];22mdev->mbase = cptvf->bbuf_base;2324return 0;25}2627static void otx2_cpt_sync_mbox_bbuf(struct otx2_mbox *mbox, int devid)28{29u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);30void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE);31struct otx2_mbox_dev *mdev = &mbox->dev[devid];32struct mbox_hdr *hdr;33u64 msg_size;3435if (mdev->mbase == hw_mbase)36return;3738hdr = hw_mbase + mbox->rx_start;39msg_size = hdr->msg_size;4041if (msg_size > mbox->rx_size - msgs_offset)42msg_size = mbox->rx_size - msgs_offset;4344/* Copy mbox messages from mbox memory to bounce buffer */45memcpy(mdev->mbase + mbox->rx_start,46hw_mbase + mbox->rx_start, msg_size + msgs_offset);47}4849irqreturn_t otx2_cptvf_pfvf_mbox_intr(int __always_unused irq, void *arg)50{51struct otx2_cptvf_dev *cptvf = arg;52u64 intr;5354/* Read the interrupt bits */55intr = otx2_cpt_read64(cptvf->reg_base, BLKADDR_RVUM, 0,56OTX2_RVU_VF_INT);5758if (intr & 0x1ULL) {59/* Schedule work queue function to process the MBOX request */60queue_work(cptvf->pfvf_mbox_wq, &cptvf->pfvf_mbox_work);61/* Clear and ack the interrupt */62otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0,63OTX2_RVU_VF_INT, 0x1ULL);64}65return IRQ_HANDLED;66}6768static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev *cptvf,69struct mbox_msghdr *msg)70{71struct otx2_cptlfs_info *lfs = &cptvf->lfs;72struct otx2_cpt_kvf_limits_rsp *rsp_limits;73struct otx2_cpt_egrp_num_rsp *rsp_grp;74struct otx2_cpt_caps_rsp *eng_caps;75struct cpt_rd_wr_reg_msg *rsp_reg;76struct msix_offset_rsp *rsp_msix;77u8 grp_num;78int i;7980if (msg->id >= MBOX_MSG_MAX) {81dev_err(&cptvf->pdev->dev,82"MBOX msg with unknown ID %d\n", msg->id);83return;84}85if (msg->sig != OTX2_MBOX_RSP_SIG) {86dev_err(&cptvf->pdev->dev,87"MBOX msg with wrong signature %x, ID %d\n",88msg->sig, msg->id);89return;90}91switch (msg->id) {92case MBOX_MSG_READY:93cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT)94& RVU_PFVF_FUNC_MASK) - 1;95break;96case MBOX_MSG_ATTACH_RESOURCES:97/* Check if resources were successfully attached */98if (!msg->rc)99lfs->are_lfs_attached = 1;100break;101case MBOX_MSG_DETACH_RESOURCES:102/* Check if resources were successfully detached */103if (!msg->rc)104lfs->are_lfs_attached = 0;105break;106case MBOX_MSG_MSIX_OFFSET:107rsp_msix = (struct msix_offset_rsp *) msg;108for (i = 0; i < rsp_msix->cptlfs; i++)109lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i];110break;111case MBOX_MSG_CPT_RD_WR_REGISTER:112rsp_reg = (struct cpt_rd_wr_reg_msg *) msg;113if (msg->rc) {114dev_err(&cptvf->pdev->dev,115"Reg %llx rd/wr(%d) failed %d\n",116rsp_reg->reg_offset, rsp_reg->is_write,117msg->rc);118return;119}120if (!rsp_reg->is_write)121*rsp_reg->ret_val = rsp_reg->val;122break;123case MBOX_MSG_GET_ENG_GRP_NUM:124rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg;125grp_num = rsp_grp->eng_grp_num;126if (rsp_grp->eng_type == OTX2_CPT_SE_TYPES)127cptvf->lfs.kcrypto_se_eng_grp_num = grp_num;128else if (rsp_grp->eng_type == OTX2_CPT_AE_TYPES)129cptvf->lfs.kcrypto_ae_eng_grp_num = grp_num;130break;131case MBOX_MSG_GET_KVF_LIMITS:132rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg;133cptvf->lfs.kvf_limits = rsp_limits->kvf_limits;134break;135case MBOX_MSG_GET_CAPS:136eng_caps = (struct otx2_cpt_caps_rsp *)msg;137memcpy(cptvf->eng_caps, eng_caps->eng_caps,138sizeof(cptvf->eng_caps));139break;140case MBOX_MSG_CPT_LF_RESET:141case MBOX_MSG_LMTST_TBL_SETUP:142break;143default:144dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n",145msg->id);146break;147}148}149150void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work)151{152struct otx2_cptvf_dev *cptvf;153struct otx2_mbox *pfvf_mbox;154struct otx2_mbox_dev *mdev;155struct mbox_hdr *rsp_hdr;156struct mbox_msghdr *msg;157int offset, i;158159/* sync with mbox memory region */160smp_rmb();161162cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work);163pfvf_mbox = &cptvf->pfvf_mbox;164otx2_cpt_sync_mbox_bbuf(pfvf_mbox, 0);165mdev = &pfvf_mbox->dev[0];166rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start);167if (rsp_hdr->num_msgs == 0)168return;169offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);170171for (i = 0; i < rsp_hdr->num_msgs; i++) {172msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start +173offset);174process_pfvf_mbox_mbox_msg(cptvf, msg);175offset = msg->next_msgoff;176mdev->msgs_acked++;177}178otx2_mbox_reset(pfvf_mbox, 0);179}180181int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type)182{183struct otx2_mbox *mbox = &cptvf->pfvf_mbox;184struct pci_dev *pdev = cptvf->pdev;185struct otx2_cpt_egrp_num_msg *req;186187req = (struct otx2_cpt_egrp_num_msg *)188otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),189sizeof(struct otx2_cpt_egrp_num_rsp));190if (req == NULL) {191dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");192return -EFAULT;193}194req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;195req->hdr.sig = OTX2_MBOX_REQ_SIG;196req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);197req->eng_type = eng_type;198199return otx2_cpt_send_mbox_msg(mbox, pdev);200}201202int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf)203{204struct otx2_mbox *mbox = &cptvf->pfvf_mbox;205struct pci_dev *pdev = cptvf->pdev;206struct mbox_msghdr *req;207208req = (struct mbox_msghdr *)209otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),210sizeof(struct otx2_cpt_kvf_limits_rsp));211if (req == NULL) {212dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");213return -EFAULT;214}215req->id = MBOX_MSG_GET_KVF_LIMITS;216req->sig = OTX2_MBOX_REQ_SIG;217req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);218219return otx2_cpt_send_mbox_msg(mbox, pdev);220}221222int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf)223{224struct otx2_mbox *mbox = &cptvf->pfvf_mbox;225struct pci_dev *pdev = cptvf->pdev;226struct mbox_msghdr *req;227228req = (struct mbox_msghdr *)229otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),230sizeof(struct otx2_cpt_caps_rsp));231if (!req) {232dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");233return -EFAULT;234}235req->id = MBOX_MSG_GET_CAPS;236req->sig = OTX2_MBOX_REQ_SIG;237req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);238239return otx2_cpt_send_mbox_msg(mbox, pdev);240}241242243