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) 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 66 return 0; 67 } 68 69 int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 70 u64 reg, u64 val) 71 { 72 struct cpt_rd_wr_reg_msg *reg_msg; 73 74 reg_msg = (struct cpt_rd_wr_reg_msg *) 75 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg), 76 sizeof(*reg_msg)); 77 if (reg_msg == NULL) { 78 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 79 return -EFAULT; 80 } 81 82 reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER; 83 reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG; 84 reg_msg->hdr.pcifunc = 0; 85 86 reg_msg->is_write = 1; 87 reg_msg->reg_offset = reg; 88 reg_msg->val = val; 89 90 return 0; 91 } 92 93 int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 94 u64 reg, u64 *val) 95 { 96 int ret; 97 98 ret = otx2_cpt_add_read_af_reg(mbox, pdev, reg, val); 99 if (ret) 100 return ret; 101 102 return otx2_cpt_send_mbox_msg(mbox, pdev); 103 } 104 105 int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, 106 u64 reg, u64 val) 107 { 108 int ret; 109 110 ret = otx2_cpt_add_write_af_reg(mbox, pdev, reg, val); 111 if (ret) 112 return ret; 113 114 return otx2_cpt_send_mbox_msg(mbox, pdev); 115 } 116 117 int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs) 118 { 119 struct otx2_mbox *mbox = lfs->mbox; 120 struct rsrc_attach *req; 121 int ret; 122 123 req = (struct rsrc_attach *) 124 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 125 sizeof(struct msg_rsp)); 126 if (req == NULL) { 127 dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n"); 128 return -EFAULT; 129 } 130 131 req->hdr.id = MBOX_MSG_ATTACH_RESOURCES; 132 req->hdr.sig = OTX2_MBOX_REQ_SIG; 133 req->hdr.pcifunc = 0; 134 req->cptlfs = lfs->lfs_num; 135 ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev); 136 if (ret) 137 return ret; 138 139 if (!lfs->are_lfs_attached) 140 ret = -EINVAL; 141 142 return ret; 143 } 144 145 int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs) 146 { 147 struct otx2_mbox *mbox = lfs->mbox; 148 struct rsrc_detach *req; 149 int ret; 150 151 req = (struct rsrc_detach *) 152 otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 153 sizeof(struct msg_rsp)); 154 if (req == NULL) { 155 dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n"); 156 return -EFAULT; 157 } 158 159 req->hdr.id = MBOX_MSG_DETACH_RESOURCES; 160 req->hdr.sig = OTX2_MBOX_REQ_SIG; 161 req->hdr.pcifunc = 0; 162 ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev); 163 if (ret) 164 return ret; 165 166 if (lfs->are_lfs_attached) 167 ret = -EINVAL; 168 169 return ret; 170 } 171 172 int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs) 173 { 174 struct otx2_mbox *mbox = lfs->mbox; 175 struct pci_dev *pdev = lfs->pdev; 176 struct mbox_msghdr *req; 177 int ret, i; 178 179 req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), 180 sizeof(struct msix_offset_rsp)); 181 if (req == NULL) { 182 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); 183 return -EFAULT; 184 } 185 186 req->id = MBOX_MSG_MSIX_OFFSET; 187 req->sig = OTX2_MBOX_REQ_SIG; 188 req->pcifunc = 0; 189 ret = otx2_cpt_send_mbox_msg(mbox, pdev); 190 if (ret) 191 return ret; 192 193 for (i = 0; i < lfs->lfs_num; i++) { 194 if (lfs->lf[i].msix_offset == MSIX_VECTOR_INVALID) { 195 dev_err(&pdev->dev, 196 "Invalid msix offset %d for LF %d\n", 197 lfs->lf[i].msix_offset, i); 198 return -EINVAL; 199 } 200 } 201 return ret; 202 } 203