Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright (C) 2020 Marvell. */
0003 
0004 #include "otx2_cpt_common.h"
0005 #include "otx2_cptvf.h"
0006 #include <rvu_reg.h>
0007 
0008 int otx2_cpt_mbox_bbuf_init(struct otx2_cptvf_dev *cptvf, struct pci_dev *pdev)
0009 {
0010     struct otx2_mbox_dev *mdev;
0011     struct otx2_mbox *otx2_mbox;
0012 
0013     cptvf->bbuf_base = devm_kmalloc(&pdev->dev, MBOX_SIZE, GFP_KERNEL);
0014     if (!cptvf->bbuf_base)
0015         return -ENOMEM;
0016     /*
0017      * Overwrite mbox mbase to point to bounce buffer, so that PF/VF
0018      * prepare all mbox messages in bounce buffer instead of directly
0019      * in hw mbox memory.
0020      */
0021     otx2_mbox = &cptvf->pfvf_mbox;
0022     mdev = &otx2_mbox->dev[0];
0023     mdev->mbase = cptvf->bbuf_base;
0024 
0025     return 0;
0026 }
0027 
0028 static void otx2_cpt_sync_mbox_bbuf(struct otx2_mbox *mbox, int devid)
0029 {
0030     u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
0031     void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE);
0032     struct otx2_mbox_dev *mdev = &mbox->dev[devid];
0033     struct mbox_hdr *hdr;
0034     u64 msg_size;
0035 
0036     if (mdev->mbase == hw_mbase)
0037         return;
0038 
0039     hdr = hw_mbase + mbox->rx_start;
0040     msg_size = hdr->msg_size;
0041 
0042     if (msg_size > mbox->rx_size - msgs_offset)
0043         msg_size = mbox->rx_size - msgs_offset;
0044 
0045     /* Copy mbox messages from mbox memory to bounce buffer */
0046     memcpy(mdev->mbase + mbox->rx_start,
0047            hw_mbase + mbox->rx_start, msg_size + msgs_offset);
0048 }
0049 
0050 irqreturn_t otx2_cptvf_pfvf_mbox_intr(int __always_unused irq, void *arg)
0051 {
0052     struct otx2_cptvf_dev *cptvf = arg;
0053     u64 intr;
0054 
0055     /* Read the interrupt bits */
0056     intr = otx2_cpt_read64(cptvf->reg_base, BLKADDR_RVUM, 0,
0057                    OTX2_RVU_VF_INT);
0058 
0059     if (intr & 0x1ULL) {
0060         /* Schedule work queue function to process the MBOX request */
0061         queue_work(cptvf->pfvf_mbox_wq, &cptvf->pfvf_mbox_work);
0062         /* Clear and ack the interrupt */
0063         otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0,
0064                  OTX2_RVU_VF_INT, 0x1ULL);
0065     }
0066     return IRQ_HANDLED;
0067 }
0068 
0069 static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev *cptvf,
0070                        struct mbox_msghdr *msg)
0071 {
0072     struct otx2_cptlfs_info *lfs = &cptvf->lfs;
0073     struct otx2_cpt_kvf_limits_rsp *rsp_limits;
0074     struct otx2_cpt_egrp_num_rsp *rsp_grp;
0075     struct cpt_rd_wr_reg_msg *rsp_reg;
0076     struct msix_offset_rsp *rsp_msix;
0077     int i;
0078 
0079     if (msg->id >= MBOX_MSG_MAX) {
0080         dev_err(&cptvf->pdev->dev,
0081             "MBOX msg with unknown ID %d\n", msg->id);
0082         return;
0083     }
0084     if (msg->sig != OTX2_MBOX_RSP_SIG) {
0085         dev_err(&cptvf->pdev->dev,
0086             "MBOX msg with wrong signature %x, ID %d\n",
0087             msg->sig, msg->id);
0088         return;
0089     }
0090     switch (msg->id) {
0091     case MBOX_MSG_READY:
0092         cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT)
0093                 & RVU_PFVF_FUNC_MASK) - 1;
0094         break;
0095     case MBOX_MSG_ATTACH_RESOURCES:
0096         /* Check if resources were successfully attached */
0097         if (!msg->rc)
0098             lfs->are_lfs_attached = 1;
0099         break;
0100     case MBOX_MSG_DETACH_RESOURCES:
0101         /* Check if resources were successfully detached */
0102         if (!msg->rc)
0103             lfs->are_lfs_attached = 0;
0104         break;
0105     case MBOX_MSG_MSIX_OFFSET:
0106         rsp_msix = (struct msix_offset_rsp *) msg;
0107         for (i = 0; i < rsp_msix->cptlfs; i++)
0108             lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i];
0109         break;
0110     case MBOX_MSG_CPT_RD_WR_REGISTER:
0111         rsp_reg = (struct cpt_rd_wr_reg_msg *) msg;
0112         if (msg->rc) {
0113             dev_err(&cptvf->pdev->dev,
0114                 "Reg %llx rd/wr(%d) failed %d\n",
0115                 rsp_reg->reg_offset, rsp_reg->is_write,
0116                 msg->rc);
0117             return;
0118         }
0119         if (!rsp_reg->is_write)
0120             *rsp_reg->ret_val = rsp_reg->val;
0121         break;
0122     case MBOX_MSG_GET_ENG_GRP_NUM:
0123         rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg;
0124         cptvf->lfs.kcrypto_eng_grp_num = rsp_grp->eng_grp_num;
0125         break;
0126     case MBOX_MSG_GET_KVF_LIMITS:
0127         rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg;
0128         cptvf->lfs.kvf_limits = rsp_limits->kvf_limits;
0129         break;
0130     default:
0131         dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n",
0132             msg->id);
0133         break;
0134     }
0135 }
0136 
0137 void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work)
0138 {
0139     struct otx2_cptvf_dev *cptvf;
0140     struct otx2_mbox *pfvf_mbox;
0141     struct otx2_mbox_dev *mdev;
0142     struct mbox_hdr *rsp_hdr;
0143     struct mbox_msghdr *msg;
0144     int offset, i;
0145 
0146     /* sync with mbox memory region */
0147     smp_rmb();
0148 
0149     cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work);
0150     pfvf_mbox = &cptvf->pfvf_mbox;
0151     otx2_cpt_sync_mbox_bbuf(pfvf_mbox, 0);
0152     mdev = &pfvf_mbox->dev[0];
0153     rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start);
0154     if (rsp_hdr->num_msgs == 0)
0155         return;
0156     offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
0157 
0158     for (i = 0; i < rsp_hdr->num_msgs; i++) {
0159         msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start +
0160                          offset);
0161         process_pfvf_mbox_mbox_msg(cptvf, msg);
0162         offset = msg->next_msgoff;
0163         mdev->msgs_acked++;
0164     }
0165     otx2_mbox_reset(pfvf_mbox, 0);
0166 }
0167 
0168 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type)
0169 {
0170     struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
0171     struct pci_dev *pdev = cptvf->pdev;
0172     struct otx2_cpt_egrp_num_msg *req;
0173 
0174     req = (struct otx2_cpt_egrp_num_msg *)
0175           otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
0176                       sizeof(struct otx2_cpt_egrp_num_rsp));
0177     if (req == NULL) {
0178         dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
0179         return -EFAULT;
0180     }
0181     req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
0182     req->hdr.sig = OTX2_MBOX_REQ_SIG;
0183     req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
0184     req->eng_type = eng_type;
0185 
0186     return otx2_cpt_send_mbox_msg(mbox, pdev);
0187 }
0188 
0189 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf)
0190 {
0191     struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
0192     struct pci_dev *pdev = cptvf->pdev;
0193     struct mbox_msghdr *req;
0194     int ret;
0195 
0196     req = (struct mbox_msghdr *)
0197           otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
0198                       sizeof(struct otx2_cpt_kvf_limits_rsp));
0199     if (req == NULL) {
0200         dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
0201         return -EFAULT;
0202     }
0203     req->id = MBOX_MSG_GET_KVF_LIMITS;
0204     req->sig = OTX2_MBOX_REQ_SIG;
0205     req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
0206 
0207     ret = otx2_cpt_send_mbox_msg(mbox, pdev);
0208 
0209     return ret;
0210 }