1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2020 Marvell. */ 3 4 #include "otx2_cpt_common.h" 5 #include "otx2_cptvf.h" 6 #include <rvu_reg.h> 7 8 irqreturn_t otx2_cptvf_pfvf_mbox_intr(int __always_unused irq, void *arg) 9 { 10 struct otx2_cptvf_dev *cptvf = arg; 11 u64 intr; 12 13 /* Read the interrupt bits */ 14 intr = otx2_cpt_read64(cptvf->reg_base, BLKADDR_RVUM, 0, 15 OTX2_RVU_VF_INT); 16 17 if (intr & 0x1ULL) { 18 /* Schedule work queue function to process the MBOX request */ 19 queue_work(cptvf->pfvf_mbox_wq, &cptvf->pfvf_mbox_work); 20 /* Clear and ack the interrupt */ 21 otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, 22 OTX2_RVU_VF_INT, 0x1ULL); 23 } 24 return IRQ_HANDLED; 25 } 26 27 static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev *cptvf, 28 struct mbox_msghdr *msg) 29 { 30 struct otx2_cptlfs_info *lfs = &cptvf->lfs; 31 struct otx2_cpt_kvf_limits_rsp *rsp_limits; 32 struct otx2_cpt_egrp_num_rsp *rsp_grp; 33 struct cpt_rd_wr_reg_msg *rsp_reg; 34 struct msix_offset_rsp *rsp_msix; 35 int i; 36 37 if (msg->id >= MBOX_MSG_MAX) { 38 dev_err(&cptvf->pdev->dev, 39 "MBOX msg with unknown ID %d\n", msg->id); 40 return; 41 } 42 if (msg->sig != OTX2_MBOX_RSP_SIG) { 43 dev_err(&cptvf->pdev->dev, 44 "MBOX msg with wrong signature %x, ID %d\n", 45 msg->sig, msg->id); 46 return; 47 } 48 switch (msg->id) { 49 case MBOX_MSG_READY: 50 cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT) 51 & RVU_PFVF_FUNC_MASK) - 1; 52 break; 53 case MBOX_MSG_ATTACH_RESOURCES: 54 /* Check if resources were successfully attached */ 55 if (!msg->rc) 56 lfs->are_lfs_attached = 1; 57 break; 58 case MBOX_MSG_DETACH_RESOURCES: 59 /* Check if resources were successfully detached */ 60 if (!msg->rc) 61 lfs->are_lfs_attached = 0; 62 break; 63 case MBOX_MSG_MSIX_OFFSET: 64 rsp_msix = (struct msix_offset_rsp *) msg; 65 for (i = 0; i < rsp_msix->cptlfs; i++) 66 lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i]; 67 break; 68 case MBOX_MSG_CPT_RD_WR_REGISTER: 69 rsp_reg = (struct cpt_rd_wr_reg_msg *) msg; 70 if (msg->rc) { 71 dev_err(&cptvf->pdev->dev, 72 "Reg %llx rd/wr(%d) failed %d\n", 73 rsp_reg->reg_offset, rsp_reg->is_write, 74 msg->rc); 75 return; 76 } 77 if (!rsp_reg->is_write) 78 *rsp_reg->ret_val = rsp_reg->val; 79 break; 80 case MBOX_MSG_GET_ENG_GRP_NUM: 81 rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg; 82 cptvf->lfs.kcrypto_eng_grp_num = rsp_grp->eng_grp_num; 83 break; 84 case MBOX_MSG_GET_KVF_LIMITS: 85 rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg; 86 cptvf->lfs.kvf_limits = rsp_limits->kvf_limits; 87 break; 88 default: 89 dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n", 90 msg->id); 91 break; 92 } 93 } 94 95 void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work) 96 { 97 struct otx2_cptvf_dev *cptvf; 98 struct otx2_mbox *pfvf_mbox; 99 struct otx2_mbox_dev *mdev; 100 struct mbox_hdr *rsp_hdr; 101 struct mbox_msghdr *msg; 102 int offset, i; 103 104 /* sync with mbox memory region */ 105 smp_rmb(); 106 107 cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work); 108 pfvf_mbox = &cptvf->pfvf_mbox; 109 mdev = &pfvf_mbox->dev[0]; 110 rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start); 111 if (rsp_hdr->num_msgs == 0) 112 return; 113 offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); 114 115 for (i = 0; i < rsp_hdr->num_msgs; i++) { 116 msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start + 117 offset); 118 process_pfvf_mbox_mbox_msg(cptvf, msg); 119 offset = msg->next_msgoff; 120 mdev->msgs_acked++; 121 } 122 otx2_mbox_reset(pfvf_mbox, 0); 123 } 124 125 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type) 126 { 127 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 128 struct pci_dev *pdev = cptvf->pdev; 129 struct otx2_cpt_egrp_num_msg *req; 130 131 req = (struct otx2_cpt_egrp_num_msg *) 132 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 133 sizeof(struct otx2_cpt_egrp_num_rsp)); 134 if (req == NULL) { 135 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 136 return -EFAULT; 137 } 138 req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM; 139 req->hdr.sig = OTX2_MBOX_REQ_SIG; 140 req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 141 req->eng_type = eng_type; 142 143 return otx2_cpt_send_mbox_msg(mbox, pdev); 144 } 145 146 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf) 147 { 148 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 149 struct pci_dev *pdev = cptvf->pdev; 150 struct mbox_msghdr *req; 151 int ret; 152 153 req = (struct mbox_msghdr *) 154 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 155 sizeof(struct otx2_cpt_kvf_limits_rsp)); 156 if (req == NULL) { 157 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 158 return -EFAULT; 159 } 160 req->id = MBOX_MSG_GET_KVF_LIMITS; 161 req->sig = OTX2_MBOX_REQ_SIG; 162 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 163 164 ret = otx2_cpt_send_mbox_msg(mbox, pdev); 165 166 return ret; 167 } 168