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 int i; 79 80 if (msg->id >= MBOX_MSG_MAX) { 81 dev_err(&cptvf->pdev->dev, 82 "MBOX msg with unknown ID %d\n", msg->id); 83 return; 84 } 85 if (msg->sig != OTX2_MBOX_RSP_SIG) { 86 dev_err(&cptvf->pdev->dev, 87 "MBOX msg with wrong signature %x, ID %d\n", 88 msg->sig, msg->id); 89 return; 90 } 91 switch (msg->id) { 92 case MBOX_MSG_READY: 93 cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT) 94 & RVU_PFVF_FUNC_MASK) - 1; 95 break; 96 case MBOX_MSG_ATTACH_RESOURCES: 97 /* Check if resources were successfully attached */ 98 if (!msg->rc) 99 lfs->are_lfs_attached = 1; 100 break; 101 case MBOX_MSG_DETACH_RESOURCES: 102 /* Check if resources were successfully detached */ 103 if (!msg->rc) 104 lfs->are_lfs_attached = 0; 105 break; 106 case MBOX_MSG_MSIX_OFFSET: 107 rsp_msix = (struct msix_offset_rsp *) msg; 108 for (i = 0; i < rsp_msix->cptlfs; i++) 109 lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i]; 110 break; 111 case MBOX_MSG_CPT_RD_WR_REGISTER: 112 rsp_reg = (struct cpt_rd_wr_reg_msg *) msg; 113 if (msg->rc) { 114 dev_err(&cptvf->pdev->dev, 115 "Reg %llx rd/wr(%d) failed %d\n", 116 rsp_reg->reg_offset, rsp_reg->is_write, 117 msg->rc); 118 return; 119 } 120 if (!rsp_reg->is_write) 121 *rsp_reg->ret_val = rsp_reg->val; 122 break; 123 case MBOX_MSG_GET_ENG_GRP_NUM: 124 rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg; 125 cptvf->lfs.kcrypto_eng_grp_num = rsp_grp->eng_grp_num; 126 break; 127 case MBOX_MSG_GET_KVF_LIMITS: 128 rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg; 129 cptvf->lfs.kvf_limits = rsp_limits->kvf_limits; 130 break; 131 case MBOX_MSG_GET_CAPS: 132 eng_caps = (struct otx2_cpt_caps_rsp *)msg; 133 memcpy(cptvf->eng_caps, eng_caps->eng_caps, 134 sizeof(cptvf->eng_caps)); 135 break; 136 case MBOX_MSG_CPT_LF_RESET: 137 case MBOX_MSG_LMTST_TBL_SETUP: 138 break; 139 default: 140 dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n", 141 msg->id); 142 break; 143 } 144 } 145 146 void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work) 147 { 148 struct otx2_cptvf_dev *cptvf; 149 struct otx2_mbox *pfvf_mbox; 150 struct otx2_mbox_dev *mdev; 151 struct mbox_hdr *rsp_hdr; 152 struct mbox_msghdr *msg; 153 int offset, i; 154 155 /* sync with mbox memory region */ 156 smp_rmb(); 157 158 cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work); 159 pfvf_mbox = &cptvf->pfvf_mbox; 160 otx2_cpt_sync_mbox_bbuf(pfvf_mbox, 0); 161 mdev = &pfvf_mbox->dev[0]; 162 rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start); 163 if (rsp_hdr->num_msgs == 0) 164 return; 165 offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); 166 167 for (i = 0; i < rsp_hdr->num_msgs; i++) { 168 msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start + 169 offset); 170 process_pfvf_mbox_mbox_msg(cptvf, msg); 171 offset = msg->next_msgoff; 172 mdev->msgs_acked++; 173 } 174 otx2_mbox_reset(pfvf_mbox, 0); 175 } 176 177 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type) 178 { 179 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 180 struct pci_dev *pdev = cptvf->pdev; 181 struct otx2_cpt_egrp_num_msg *req; 182 183 req = (struct otx2_cpt_egrp_num_msg *) 184 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 185 sizeof(struct otx2_cpt_egrp_num_rsp)); 186 if (req == NULL) { 187 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 188 return -EFAULT; 189 } 190 req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM; 191 req->hdr.sig = OTX2_MBOX_REQ_SIG; 192 req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 193 req->eng_type = eng_type; 194 195 return otx2_cpt_send_mbox_msg(mbox, pdev); 196 } 197 198 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf) 199 { 200 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 201 struct pci_dev *pdev = cptvf->pdev; 202 struct mbox_msghdr *req; 203 204 req = (struct mbox_msghdr *) 205 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 206 sizeof(struct otx2_cpt_kvf_limits_rsp)); 207 if (req == NULL) { 208 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 209 return -EFAULT; 210 } 211 req->id = MBOX_MSG_GET_KVF_LIMITS; 212 req->sig = OTX2_MBOX_REQ_SIG; 213 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 214 215 return otx2_cpt_send_mbox_msg(mbox, pdev); 216 } 217 218 int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf) 219 { 220 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 221 struct pci_dev *pdev = cptvf->pdev; 222 struct mbox_msghdr *req; 223 224 req = (struct mbox_msghdr *) 225 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 226 sizeof(struct otx2_cpt_caps_rsp)); 227 if (!req) { 228 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 229 return -EFAULT; 230 } 231 req->id = MBOX_MSG_GET_CAPS; 232 req->sig = OTX2_MBOX_REQ_SIG; 233 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 234 235 return otx2_cpt_send_mbox_msg(mbox, pdev); 236 } 237