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 break; 138 default: 139 dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n", 140 msg->id); 141 break; 142 } 143 } 144 145 void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work) 146 { 147 struct otx2_cptvf_dev *cptvf; 148 struct otx2_mbox *pfvf_mbox; 149 struct otx2_mbox_dev *mdev; 150 struct mbox_hdr *rsp_hdr; 151 struct mbox_msghdr *msg; 152 int offset, i; 153 154 /* sync with mbox memory region */ 155 smp_rmb(); 156 157 cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work); 158 pfvf_mbox = &cptvf->pfvf_mbox; 159 otx2_cpt_sync_mbox_bbuf(pfvf_mbox, 0); 160 mdev = &pfvf_mbox->dev[0]; 161 rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start); 162 if (rsp_hdr->num_msgs == 0) 163 return; 164 offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); 165 166 for (i = 0; i < rsp_hdr->num_msgs; i++) { 167 msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start + 168 offset); 169 process_pfvf_mbox_mbox_msg(cptvf, msg); 170 offset = msg->next_msgoff; 171 mdev->msgs_acked++; 172 } 173 otx2_mbox_reset(pfvf_mbox, 0); 174 } 175 176 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type) 177 { 178 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 179 struct pci_dev *pdev = cptvf->pdev; 180 struct otx2_cpt_egrp_num_msg *req; 181 182 req = (struct otx2_cpt_egrp_num_msg *) 183 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 184 sizeof(struct otx2_cpt_egrp_num_rsp)); 185 if (req == NULL) { 186 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 187 return -EFAULT; 188 } 189 req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM; 190 req->hdr.sig = OTX2_MBOX_REQ_SIG; 191 req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 192 req->eng_type = eng_type; 193 194 return otx2_cpt_send_mbox_msg(mbox, pdev); 195 } 196 197 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf) 198 { 199 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 200 struct pci_dev *pdev = cptvf->pdev; 201 struct mbox_msghdr *req; 202 203 req = (struct mbox_msghdr *) 204 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 205 sizeof(struct otx2_cpt_kvf_limits_rsp)); 206 if (req == NULL) { 207 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 208 return -EFAULT; 209 } 210 req->id = MBOX_MSG_GET_KVF_LIMITS; 211 req->sig = OTX2_MBOX_REQ_SIG; 212 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 213 214 return otx2_cpt_send_mbox_msg(mbox, pdev); 215 } 216 217 int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf) 218 { 219 struct otx2_mbox *mbox = &cptvf->pfvf_mbox; 220 struct pci_dev *pdev = cptvf->pdev; 221 struct mbox_msghdr *req; 222 223 req = (struct mbox_msghdr *) 224 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 225 sizeof(struct otx2_cpt_caps_rsp)); 226 if (!req) { 227 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 228 return -EFAULT; 229 } 230 req->id = MBOX_MSG_GET_CAPS; 231 req->sig = OTX2_MBOX_REQ_SIG; 232 req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0); 233 234 return otx2_cpt_send_mbox_msg(mbox, pdev); 235 } 236