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 int otx2_cpt_mbox_bbuf_init(struct otx2_cptvf_dev *cptvf, struct pci_dev *pdev) 9 { 10 struct otx2_mbox_dev *mdev; 11 struct otx2_mbox *otx2_mbox; 12 13 cptvf->bbuf_base = devm_kmalloc(&pdev->dev, MBOX_SIZE, GFP_KERNEL); 14 if (!cptvf->bbuf_base) 15 return -ENOMEM; 16 /* 17 * Overwrite mbox mbase to point to bounce buffer, so that PF/VF 18 * prepare all mbox messages in bounce buffer instead of directly 19 * in hw mbox memory. 20 */ 21 otx2_mbox = &cptvf->pfvf_mbox; 22 mdev = &otx2_mbox->dev[0]; 23 mdev->mbase = cptvf->bbuf_base; 24 25 return 0; 26 } 27 28 static void otx2_cpt_sync_mbox_bbuf(struct otx2_mbox *mbox, int devid) 29 { 30 u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); 31 void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE); 32 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; 33 struct mbox_hdr *hdr; 34 u64 msg_size; 35 36 if (mdev->mbase == hw_mbase) 37 return; 38 39 hdr = hw_mbase + mbox->rx_start; 40 msg_size = hdr->msg_size; 41 42 if (msg_size > mbox->rx_size - msgs_offset) 43 msg_size = mbox->rx_size - msgs_offset; 44 45 /* Copy mbox messages from mbox memory to bounce buffer */ 46 memcpy(mdev->mbase + mbox->rx_start, 47 hw_mbase + mbox->rx_start, msg_size + msgs_offset); 48 } 49 50 irqreturn_t otx2_cptvf_pfvf_mbox_intr(int __always_unused irq, void *arg) 51 { 52 struct otx2_cptvf_dev *cptvf = arg; 53 u64 intr; 54 55 /* Read the interrupt bits */ 56 intr = otx2_cpt_read64(cptvf->reg_base, BLKADDR_RVUM, 0, 57 OTX2_RVU_VF_INT); 58 59 if (intr & 0x1ULL) { 60 /* Schedule work queue function to process the MBOX request */ 61 queue_work(cptvf->pfvf_mbox_wq, &cptvf->pfvf_mbox_work); 62 /* Clear and ack the interrupt */ 63 otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, 64 OTX2_RVU_VF_INT, 0x1ULL); 65 } 66 return IRQ_HANDLED; 67 } 68 69 static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev *cptvf, 70 struct mbox_msghdr *msg) 71 { 72 struct otx2_cptlfs_info *lfs = &cptvf->lfs; 73 struct otx2_cpt_kvf_limits_rsp *rsp_limits; 74 struct otx2_cpt_egrp_num_rsp *rsp_grp; 75 struct otx2_cpt_caps_rsp *eng_caps; 76 struct cpt_rd_wr_reg_msg *rsp_reg; 77 struct msix_offset_rsp *rsp_msix; 78 u8 grp_num; 79 int i; 80 81 if (msg->id >= MBOX_MSG_MAX) { 82 dev_err(&cptvf->pdev->dev, 83 "MBOX msg with unknown ID %d\n", msg->id); 84 return; 85 } 86 if (msg->sig != OTX2_MBOX_RSP_SIG) { 87 dev_err(&cptvf->pdev->dev, 88 "MBOX msg with wrong signature %x, ID %d\n", 89 msg->sig, msg->id); 90 return; 91 } 92 switch (msg->id) { 93 case MBOX_MSG_READY: 94 cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT) 95 & RVU_PFVF_FUNC_MASK) - 1; 96 break; 97 case MBOX_MSG_ATTACH_RESOURCES: 98 /* Check if resources were successfully attached */ 99 if (!msg->rc) 100 lfs->are_lfs_attached = 1; 101 break; 102 case MBOX_MSG_DETACH_RESOURCES: 103 /* Check if resources were successfully detached */ 104 if (!msg->rc) 105 lfs->are_lfs_attached = 0; 106 break; 107 case MBOX_MSG_MSIX_OFFSET: 108 rsp_msix = (struct msix_offset_rsp *) msg; 109 for (i = 0; i < rsp_msix->cptlfs; i++) 110 lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i]; 111 break; 112 case MBOX_MSG_CPT_RD_WR_REGISTER: 113 rsp_reg = (struct cpt_rd_wr_reg_msg *) msg; 114 if (msg->rc) { 115 dev_err(&cptvf->pdev->dev, 116 "Reg %llx rd/wr(%d) failed %d\n", 117 rsp_reg->reg_offset, rsp_reg->is_write, 118 msg->rc); 119 return; 120 } 121 if (!rsp_reg->is_write) 122 *rsp_reg->ret_val = rsp_reg->val; 123 break; 124 case MBOX_MSG_GET_ENG_GRP_NUM: 125 rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg; 126 grp_num = rsp_grp->eng_grp_num; 127 if (rsp_grp->eng_type == OTX2_CPT_SE_TYPES) 128 cptvf->lfs.kcrypto_se_eng_grp_num = grp_num; 129 else if (rsp_grp->eng_type == OTX2_CPT_AE_TYPES) 130 cptvf->lfs.kcrypto_ae_eng_grp_num = grp_num; 131 break; 132 case MBOX_MSG_GET_KVF_LIMITS: 133 rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg; 134 cptvf->lfs.kvf_limits = rsp_limits->kvf_limits; 135 break; 136 case MBOX_MSG_GET_CAPS: 137 eng_caps = (struct otx2_cpt_caps_rsp *)msg; 138 memcpy(cptvf->eng_caps, eng_caps->eng_caps, 139 sizeof(cptvf->eng_caps)); 140 break; 141 case MBOX_MSG_CPT_LF_RESET: 142 case MBOX_MSG_LMTST_TBL_SETUP: 143 break; 144 default: 145 dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n", 146 msg->id); 147 break; 148 } 149 } 150 151 void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work) 152 { 153 struct otx2_cptvf_dev *cptvf; 154 struct otx2_mbox *pfvf_mbox; 155 struct otx2_mbox_dev *mdev; 156 struct mbox_hdr *rsp_hdr; 157 struct mbox_msghdr *msg; 158 int offset, i; 159 160 /* sync with mbox memory region */ 161 smp_rmb(); 162 163 cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work); 164 pfvf_mbox = &cptvf->pfvf_mbox; 165 otx2_cpt_sync_mbox_bbuf(pfvf_mbox, 0); 166 mdev = &pfvf_mbox->dev[0]; 167 rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start); 168 if (rsp_hdr->num_msgs == 0) 169 return; 170 offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); 171 172 for (i = 0; i < rsp_hdr->num_msgs; i++) { 173 msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start + 174 offset); 175 process_pfvf_mbox_mbox_msg(cptvf, msg); 176 offset = msg->next_msgoff; 177 mdev->msgs_acked++; 178 } 179 otx2_mbox_reset(pfvf_mbox, 0); 180 } 181 182 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type) 183 { 184 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 185 struct pci_dev *pdev = cptvf->pdev; 186 struct otx2_cpt_egrp_num_msg *req; 187 188 req = (struct otx2_cpt_egrp_num_msg *) 189 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 190 sizeof(struct otx2_cpt_egrp_num_rsp)); 191 if (req == NULL) { 192 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 193 return -EFAULT; 194 } 195 req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM; 196 req->hdr.sig = OTX2_MBOX_REQ_SIG; 197 req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0); 198 req->eng_type = eng_type; 199 200 return otx2_cpt_send_mbox_msg(mbox, pdev); 201 } 202 203 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf) 204 { 205 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 206 struct pci_dev *pdev = cptvf->pdev; 207 struct mbox_msghdr *req; 208 209 req = (struct mbox_msghdr *) 210 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 211 sizeof(struct otx2_cpt_kvf_limits_rsp)); 212 if (req == NULL) { 213 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 214 return -EFAULT; 215 } 216 req->id = MBOX_MSG_GET_KVF_LIMITS; 217 req->sig = OTX2_MBOX_REQ_SIG; 218 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0); 219 220 return otx2_cpt_send_mbox_msg(mbox, pdev); 221 } 222 223 int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf) 224 { 225 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 226 struct pci_dev *pdev = cptvf->pdev; 227 struct mbox_msghdr *req; 228 229 req = (struct mbox_msghdr *) 230 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 231 sizeof(struct otx2_cpt_caps_rsp)); 232 if (!req) { 233 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 234 return -EFAULT; 235 } 236 req->id = MBOX_MSG_GET_CAPS; 237 req->sig = OTX2_MBOX_REQ_SIG; 238 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0); 239 240 return otx2_cpt_send_mbox_msg(mbox, pdev); 241 } 242