1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2020 Marvell. */ 3 4 #include "otx2_cpt_common.h" 5 #include "otx2_cptlf.h" 6 7 int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev) 8 { 9 int ret; 10 11 otx2_mbox_msg_send(mbox, 0); 12 ret = otx2_mbox_wait_for_rsp(mbox, 0); 13 if (ret == -EIO) { 14 dev_err(&pdev->dev, "RVU MBOX timeout.\n"); 15 return ret; 16 } else if (ret) { 17 dev_err(&pdev->dev, "RVU MBOX error: %d.\n", ret); 18 return -EFAULT; 19 } 20 return ret; 21 } 22 23 int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev) 24 { 25 struct mbox_msghdr *req; 26 27 req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 28 sizeof(struct ready_msg_rsp)); 29 if (req == NULL) { 30 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 31 return -EFAULT; 32 } 33 req->id = MBOX_MSG_READY; 34 req->sig = OTX2_MBOX_REQ_SIG; 35 req->pcifunc = 0; 36 37 return otx2_cpt_send_mbox_msg(mbox, pdev); 38 } 39 40 int otx2_cpt_send_af_reg_requests(struct otx2_mbox *mbox, struct pci_dev *pdev) 41 { 42 return otx2_cpt_send_mbox_msg(mbox, pdev); 43 } 44 45 int otx2_cpt_add_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 46 u64 reg, u64 *val, int blkaddr) 47 { 48 struct cpt_rd_wr_reg_msg *reg_msg; 49 50 reg_msg = (struct cpt_rd_wr_reg_msg *) 51 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg), 52 sizeof(*reg_msg)); 53 if (reg_msg == NULL) { 54 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 55 return -EFAULT; 56 } 57 58 reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER; 59 reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG; 60 reg_msg->hdr.pcifunc = 0; 61 62 reg_msg->is_write = 0; 63 reg_msg->reg_offset = reg; 64 reg_msg->ret_val = val; 65 reg_msg->blkaddr = blkaddr; 66 67 return 0; 68 } 69 70 int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 71 u64 reg, u64 val, int blkaddr) 72 { 73 struct cpt_rd_wr_reg_msg *reg_msg; 74 75 reg_msg = (struct cpt_rd_wr_reg_msg *) 76 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg), 77 sizeof(*reg_msg)); 78 if (reg_msg == NULL) { 79 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 80 return -EFAULT; 81 } 82 83 reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER; 84 reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG; 85 reg_msg->hdr.pcifunc = 0; 86 87 reg_msg->is_write = 1; 88 reg_msg->reg_offset = reg; 89 reg_msg->val = val; 90 reg_msg->blkaddr = blkaddr; 91 92 return 0; 93 } 94 95 int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 96 u64 reg, u64 *val, int blkaddr) 97 { 98 int ret; 99 100 ret = otx2_cpt_add_read_af_reg(mbox, pdev, reg, val, blkaddr); 101 if (ret) 102 return ret; 103 104 return otx2_cpt_send_mbox_msg(mbox, pdev); 105 } 106 107 int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 108 u64 reg, u64 val, int blkaddr) 109 { 110 int ret; 111 112 ret = otx2_cpt_add_write_af_reg(mbox, pdev, reg, val, blkaddr); 113 if (ret) 114 return ret; 115 116 return otx2_cpt_send_mbox_msg(mbox, pdev); 117 } 118 119 int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs) 120 { 121 struct otx2_mbox *mbox = lfs->mbox; 122 struct rsrc_attach *req; 123 int ret; 124 125 req = (struct rsrc_attach *) 126 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 127 sizeof(struct msg_rsp)); 128 if (req == NULL) { 129 dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n"); 130 return -EFAULT; 131 } 132 133 req->hdr.id = MBOX_MSG_ATTACH_RESOURCES; 134 req->hdr.sig = OTX2_MBOX_REQ_SIG; 135 req->hdr.pcifunc = 0; 136 req->cptlfs = lfs->lfs_num; 137 ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev); 138 if (ret) 139 return ret; 140 141 if (!lfs->are_lfs_attached) 142 ret = -EINVAL; 143 144 return ret; 145 } 146 147 int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs) 148 { 149 struct otx2_mbox *mbox = lfs->mbox; 150 struct rsrc_detach *req; 151 int ret; 152 153 req = (struct rsrc_detach *) 154 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 155 sizeof(struct msg_rsp)); 156 if (req == NULL) { 157 dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n"); 158 return -EFAULT; 159 } 160 161 req->hdr.id = MBOX_MSG_DETACH_RESOURCES; 162 req->hdr.sig = OTX2_MBOX_REQ_SIG; 163 req->hdr.pcifunc = 0; 164 ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev); 165 if (ret) 166 return ret; 167 168 if (lfs->are_lfs_attached) 169 ret = -EINVAL; 170 171 return ret; 172 } 173 174 int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs) 175 { 176 struct otx2_mbox *mbox = lfs->mbox; 177 struct pci_dev *pdev = lfs->pdev; 178 struct mbox_msghdr *req; 179 int ret, i; 180 181 req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 182 sizeof(struct msix_offset_rsp)); 183 if (req == NULL) { 184 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 185 return -EFAULT; 186 } 187 188 req->id = MBOX_MSG_MSIX_OFFSET; 189 req->sig = OTX2_MBOX_REQ_SIG; 190 req->pcifunc = 0; 191 ret = otx2_cpt_send_mbox_msg(mbox, pdev); 192 if (ret) 193 return ret; 194 195 for (i = 0; i < lfs->lfs_num; i++) { 196 if (lfs->lf[i].msix_offset == MSIX_VECTOR_INVALID) { 197 dev_err(&pdev->dev, 198 "Invalid msix offset %d for LF %d\n", 199 lfs->lf[i].msix_offset, i); 200 return -EINVAL; 201 } 202 } 203 return ret; 204 } 205