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 EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_mbox_msg, CRYPTO_DEV_OCTEONTX2_CPT);
23 
24 int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
25 {
26 	struct mbox_msghdr *req;
27 
28 	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
29 				      sizeof(struct ready_msg_rsp));
30 	if (req == NULL) {
31 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
32 		return -EFAULT;
33 	}
34 	req->id = MBOX_MSG_READY;
35 	req->sig = OTX2_MBOX_REQ_SIG;
36 	req->pcifunc = 0;
37 
38 	return otx2_cpt_send_mbox_msg(mbox, pdev);
39 }
40 EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_ready_msg, CRYPTO_DEV_OCTEONTX2_CPT);
41 
42 int otx2_cpt_send_af_reg_requests(struct otx2_mbox *mbox, struct pci_dev *pdev)
43 {
44 	return otx2_cpt_send_mbox_msg(mbox, pdev);
45 }
46 EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_af_reg_requests, CRYPTO_DEV_OCTEONTX2_CPT);
47 
48 static int otx2_cpt_add_read_af_reg(struct otx2_mbox *mbox,
49 				    struct pci_dev *pdev, u64 reg,
50 				    u64 *val, int blkaddr)
51 {
52 	struct cpt_rd_wr_reg_msg *reg_msg;
53 
54 	reg_msg = (struct cpt_rd_wr_reg_msg *)
55 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg),
56 						sizeof(*reg_msg));
57 	if (reg_msg == NULL) {
58 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
59 		return -EFAULT;
60 	}
61 
62 	reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
63 	reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG;
64 	reg_msg->hdr.pcifunc = 0;
65 
66 	reg_msg->is_write = 0;
67 	reg_msg->reg_offset = reg;
68 	reg_msg->ret_val = val;
69 	reg_msg->blkaddr = blkaddr;
70 
71 	return 0;
72 }
73 
74 int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
75 			      u64 reg, u64 val, int blkaddr)
76 {
77 	struct cpt_rd_wr_reg_msg *reg_msg;
78 
79 	reg_msg = (struct cpt_rd_wr_reg_msg *)
80 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg),
81 						sizeof(*reg_msg));
82 	if (reg_msg == NULL) {
83 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
84 		return -EFAULT;
85 	}
86 
87 	reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
88 	reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG;
89 	reg_msg->hdr.pcifunc = 0;
90 
91 	reg_msg->is_write = 1;
92 	reg_msg->reg_offset = reg;
93 	reg_msg->val = val;
94 	reg_msg->blkaddr = blkaddr;
95 
96 	return 0;
97 }
98 EXPORT_SYMBOL_NS_GPL(otx2_cpt_add_write_af_reg, CRYPTO_DEV_OCTEONTX2_CPT);
99 
100 int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
101 			 u64 reg, u64 *val, int blkaddr)
102 {
103 	int ret;
104 
105 	ret = otx2_cpt_add_read_af_reg(mbox, pdev, reg, val, blkaddr);
106 	if (ret)
107 		return ret;
108 
109 	return otx2_cpt_send_mbox_msg(mbox, pdev);
110 }
111 EXPORT_SYMBOL_NS_GPL(otx2_cpt_read_af_reg, CRYPTO_DEV_OCTEONTX2_CPT);
112 
113 int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
114 			  u64 reg, u64 val, int blkaddr)
115 {
116 	int ret;
117 
118 	ret = otx2_cpt_add_write_af_reg(mbox, pdev, reg, val, blkaddr);
119 	if (ret)
120 		return ret;
121 
122 	return otx2_cpt_send_mbox_msg(mbox, pdev);
123 }
124 EXPORT_SYMBOL_NS_GPL(otx2_cpt_write_af_reg, CRYPTO_DEV_OCTEONTX2_CPT);
125 
126 int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs)
127 {
128 	struct otx2_mbox *mbox = lfs->mbox;
129 	struct rsrc_attach *req;
130 	int ret;
131 
132 	req = (struct rsrc_attach *)
133 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
134 						sizeof(struct msg_rsp));
135 	if (req == NULL) {
136 		dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n");
137 		return -EFAULT;
138 	}
139 
140 	req->hdr.id = MBOX_MSG_ATTACH_RESOURCES;
141 	req->hdr.sig = OTX2_MBOX_REQ_SIG;
142 	req->hdr.pcifunc = 0;
143 	req->cptlfs = lfs->lfs_num;
144 	req->cpt_blkaddr = lfs->blkaddr;
145 	req->modify = 1;
146 	ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev);
147 	if (ret)
148 		return ret;
149 
150 	if (!lfs->are_lfs_attached)
151 		ret = -EINVAL;
152 
153 	return ret;
154 }
155 
156 int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs)
157 {
158 	struct otx2_mbox *mbox = lfs->mbox;
159 	struct rsrc_detach *req;
160 	int ret;
161 
162 	req = (struct rsrc_detach *)
163 				otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
164 							sizeof(struct msg_rsp));
165 	if (req == NULL) {
166 		dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n");
167 		return -EFAULT;
168 	}
169 
170 	req->hdr.id = MBOX_MSG_DETACH_RESOURCES;
171 	req->hdr.sig = OTX2_MBOX_REQ_SIG;
172 	req->hdr.pcifunc = 0;
173 	req->cptlfs = 1;
174 	ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev);
175 	if (ret)
176 		return ret;
177 
178 	if (lfs->are_lfs_attached)
179 		ret = -EINVAL;
180 
181 	return ret;
182 }
183 EXPORT_SYMBOL_NS_GPL(otx2_cpt_detach_rsrcs_msg, CRYPTO_DEV_OCTEONTX2_CPT);
184 
185 int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs)
186 {
187 	struct otx2_mbox *mbox = lfs->mbox;
188 	struct pci_dev *pdev = lfs->pdev;
189 	struct mbox_msghdr *req;
190 	int ret, i;
191 
192 	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
193 				      sizeof(struct msix_offset_rsp));
194 	if (req == NULL) {
195 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
196 		return -EFAULT;
197 	}
198 
199 	req->id = MBOX_MSG_MSIX_OFFSET;
200 	req->sig = OTX2_MBOX_REQ_SIG;
201 	req->pcifunc = 0;
202 	ret = otx2_cpt_send_mbox_msg(mbox, pdev);
203 	if (ret)
204 		return ret;
205 
206 	for (i = 0; i < lfs->lfs_num; i++) {
207 		if (lfs->lf[i].msix_offset == MSIX_VECTOR_INVALID) {
208 			dev_err(&pdev->dev,
209 				"Invalid msix offset %d for LF %d\n",
210 				lfs->lf[i].msix_offset, i);
211 			return -EINVAL;
212 		}
213 	}
214 	return ret;
215 }
216 EXPORT_SYMBOL_NS_GPL(otx2_cpt_msix_offset_msg, CRYPTO_DEV_OCTEONTX2_CPT);
217 
218 int otx2_cpt_sync_mbox_msg(struct otx2_mbox *mbox)
219 {
220 	int err;
221 
222 	if (!otx2_mbox_nonempty(mbox, 0))
223 		return 0;
224 	otx2_mbox_msg_send(mbox, 0);
225 	err = otx2_mbox_wait_for_rsp(mbox, 0);
226 	if (err)
227 		return err;
228 
229 	return otx2_mbox_check_rsp_msgs(mbox, 0);
230 }
231 EXPORT_SYMBOL_NS_GPL(otx2_cpt_sync_mbox_msg, CRYPTO_DEV_OCTEONTX2_CPT);
232