1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2020 Marvell International Ltd.
3  */
4 
5 #include "otx2_common.h"
6 #include "otx2_dev.h"
7 #include "otx2_regexdev_mbox.h"
8 #include "otx2_regexdev.h"
9 
10 int
otx2_ree_available_queues_get(const struct rte_regexdev * dev,uint16_t * nb_queues)11 otx2_ree_available_queues_get(const struct rte_regexdev *dev,
12 			      uint16_t *nb_queues)
13 {
14 	struct otx2_ree_data *data = dev->data->dev_private;
15 	struct otx2_ree_vf *vf = &data->vf;
16 	struct free_rsrcs_rsp *rsp;
17 	struct otx2_dev *otx2_dev;
18 	int ret;
19 
20 	otx2_dev = &vf->otx2_dev;
21 	otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
22 
23 	ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
24 	if (ret)
25 		return -EIO;
26 
27 	if (vf->block_address == RVU_BLOCK_ADDR_REE0)
28 		*nb_queues = rsp->ree0;
29 	else
30 		*nb_queues = rsp->ree1;
31 	return 0;
32 }
33 
34 int
otx2_ree_queues_attach(const struct rte_regexdev * dev,uint8_t nb_queues)35 otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues)
36 {
37 	struct otx2_ree_data *data = dev->data->dev_private;
38 	struct otx2_ree_vf *vf = &data->vf;
39 	struct rsrc_attach_req *req;
40 	struct otx2_mbox *mbox;
41 
42 	/* Ask AF to attach required LFs */
43 	mbox = vf->otx2_dev.mbox;
44 	req = otx2_mbox_alloc_msg_attach_resources(mbox);
45 
46 	/* 1 LF = 1 queue */
47 	req->reelfs = nb_queues;
48 	req->ree_blkaddr = vf->block_address;
49 
50 	if (otx2_mbox_process(mbox) < 0)
51 		return -EIO;
52 
53 	/* Update number of attached queues */
54 	vf->nb_queues = nb_queues;
55 
56 	return 0;
57 }
58 
59 int
otx2_ree_queues_detach(const struct rte_regexdev * dev)60 otx2_ree_queues_detach(const struct rte_regexdev *dev)
61 {
62 	struct otx2_ree_data *data = dev->data->dev_private;
63 	struct otx2_ree_vf *vf = &data->vf;
64 	struct rsrc_detach_req *req;
65 	struct otx2_mbox *mbox;
66 
67 	mbox = vf->otx2_dev.mbox;
68 	req = otx2_mbox_alloc_msg_detach_resources(mbox);
69 	req->reelfs = true;
70 	req->partial = true;
71 	if (otx2_mbox_process(mbox) < 0)
72 		return -EIO;
73 
74 	/* Queues have been detached */
75 	vf->nb_queues = 0;
76 
77 	return 0;
78 }
79 
80 int
otx2_ree_msix_offsets_get(const struct rte_regexdev * dev)81 otx2_ree_msix_offsets_get(const struct rte_regexdev *dev)
82 {
83 	struct otx2_ree_data *data = dev->data->dev_private;
84 	struct otx2_ree_vf *vf = &data->vf;
85 	struct msix_offset_rsp *rsp;
86 	struct otx2_mbox *mbox;
87 	uint32_t i, ret;
88 
89 	/* Get REE MSI-X vector offsets */
90 	mbox = vf->otx2_dev.mbox;
91 	otx2_mbox_alloc_msg_msix_offset(mbox);
92 
93 	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
94 	if (ret)
95 		return ret;
96 
97 	for (i = 0; i < vf->nb_queues; i++) {
98 		if (vf->block_address == RVU_BLOCK_ADDR_REE0)
99 			vf->lf_msixoff[i] = rsp->ree0_lf_msixoff[i];
100 		else
101 			vf->lf_msixoff[i] = rsp->ree1_lf_msixoff[i];
102 		otx2_ree_dbg("lf_msixoff[%d]  0x%x", i, vf->lf_msixoff[i]);
103 	}
104 
105 	return 0;
106 }
107 
108 static int
ree_send_mbox_msg(struct otx2_ree_vf * vf)109 ree_send_mbox_msg(struct otx2_ree_vf *vf)
110 {
111 	struct otx2_mbox *mbox = vf->otx2_dev.mbox;
112 	int ret;
113 
114 	otx2_mbox_msg_send(mbox, 0);
115 
116 	ret = otx2_mbox_wait_for_rsp(mbox, 0);
117 	if (ret < 0) {
118 		otx2_err("Could not get mailbox response");
119 		return ret;
120 	}
121 
122 	return 0;
123 }
124 
125 int
otx2_ree_config_lf(const struct rte_regexdev * dev,uint8_t lf,uint8_t pri,uint32_t size)126 otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
127 		   uint32_t size)
128 {
129 	struct otx2_ree_data *data = dev->data->dev_private;
130 	struct otx2_ree_vf *vf = &data->vf;
131 	struct ree_lf_req_msg *req;
132 	struct otx2_mbox *mbox;
133 	int ret;
134 
135 	mbox = vf->otx2_dev.mbox;
136 	req = otx2_mbox_alloc_msg_ree_config_lf(mbox);
137 
138 	req->lf = lf;
139 	req->pri =  pri ? 1 : 0;
140 	req->size = size;
141 	req->blkaddr = vf->block_address;
142 
143 	ret = otx2_mbox_process(mbox);
144 	if (ret < 0) {
145 		otx2_err("Could not get mailbox response");
146 		return ret;
147 	}
148 	return 0;
149 }
150 
151 int
otx2_ree_af_reg_read(const struct rte_regexdev * dev,uint64_t reg,uint64_t * val)152 otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
153 		     uint64_t *val)
154 {
155 	struct otx2_ree_data *data = dev->data->dev_private;
156 	struct otx2_ree_vf *vf = &data->vf;
157 	struct ree_rd_wr_reg_msg *msg;
158 	struct otx2_mbox_dev *mdev;
159 	struct otx2_mbox *mbox;
160 	int ret, off;
161 
162 	mbox = vf->otx2_dev.mbox;
163 	mdev = &mbox->dev[0];
164 	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
165 						sizeof(*msg), sizeof(*msg));
166 	if (msg == NULL) {
167 		otx2_err("Could not allocate mailbox message");
168 		return -EFAULT;
169 	}
170 
171 	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
172 	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
173 	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
174 	msg->is_write = 0;
175 	msg->reg_offset = reg;
176 	msg->ret_val = val;
177 	msg->blkaddr = vf->block_address;
178 
179 	ret = ree_send_mbox_msg(vf);
180 	if (ret < 0)
181 		return ret;
182 
183 	off = mbox->rx_start +
184 			RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
185 	msg = (struct ree_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
186 
187 	*val = msg->val;
188 
189 	return 0;
190 }
191 
192 int
otx2_ree_af_reg_write(const struct rte_regexdev * dev,uint64_t reg,uint64_t val)193 otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
194 		      uint64_t val)
195 {
196 	struct otx2_ree_data *data = dev->data->dev_private;
197 	struct otx2_ree_vf *vf = &data->vf;
198 	struct ree_rd_wr_reg_msg *msg;
199 	struct otx2_mbox *mbox;
200 
201 	mbox = vf->otx2_dev.mbox;
202 	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
203 						sizeof(*msg), sizeof(*msg));
204 	if (msg == NULL) {
205 		otx2_err("Could not allocate mailbox message");
206 		return -EFAULT;
207 	}
208 
209 	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
210 	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
211 	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
212 	msg->is_write = 1;
213 	msg->reg_offset = reg;
214 	msg->val = val;
215 	msg->blkaddr = vf->block_address;
216 
217 	return ree_send_mbox_msg(vf);
218 }
219 
220 int
otx2_ree_rule_db_get(const struct rte_regexdev * dev,char * rule_db,uint32_t rule_db_len,char * rule_dbi,uint32_t rule_dbi_len)221 otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
222 		uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len)
223 {
224 	struct otx2_ree_data *data = dev->data->dev_private;
225 	struct ree_rule_db_get_req_msg *req;
226 	struct ree_rule_db_get_rsp_msg *rsp;
227 	char *rule_db_ptr = (char *)rule_db;
228 	struct otx2_ree_vf *vf = &data->vf;
229 	struct otx2_mbox *mbox;
230 	int ret, last = 0;
231 	uint32_t len = 0;
232 
233 	mbox = vf->otx2_dev.mbox;
234 	if (!rule_db) {
235 		otx2_err("Couldn't return rule db due to NULL pointer");
236 		return -EFAULT;
237 	}
238 
239 	while (!last) {
240 		req = (struct ree_rule_db_get_req_msg *)
241 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
242 						sizeof(*rsp));
243 		if (!req) {
244 			otx2_err("Could not allocate mailbox message");
245 			return -EFAULT;
246 		}
247 
248 		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
249 		req->hdr.sig = OTX2_MBOX_REQ_SIG;
250 		req->hdr.pcifunc = vf->otx2_dev.pf_func;
251 		req->blkaddr = vf->block_address;
252 		req->is_dbi = 0;
253 		req->offset = len;
254 		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
255 		if (ret)
256 			return ret;
257 		if (rule_db_len < len + rsp->len) {
258 			otx2_err("Rule db size is too small");
259 			return -EFAULT;
260 		}
261 		otx2_mbox_memcpy(rule_db_ptr, rsp->rule_db, rsp->len);
262 		len += rsp->len;
263 		rule_db_ptr = rule_db_ptr + rsp->len;
264 		last = rsp->is_last;
265 	}
266 
267 	if (rule_dbi) {
268 		req = (struct ree_rule_db_get_req_msg *)
269 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
270 						sizeof(*rsp));
271 		if (!req) {
272 			otx2_err("Could not allocate mailbox message");
273 			return -EFAULT;
274 		}
275 
276 		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
277 		req->hdr.sig = OTX2_MBOX_REQ_SIG;
278 		req->hdr.pcifunc = vf->otx2_dev.pf_func;
279 		req->blkaddr = vf->block_address;
280 		req->is_dbi = 1;
281 		req->offset = 0;
282 
283 		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
284 		if (ret)
285 			return ret;
286 		if (rule_dbi_len < rsp->len) {
287 			otx2_err("Rule dbi size is too small");
288 			return -EFAULT;
289 		}
290 		otx2_mbox_memcpy(rule_dbi, rsp->rule_db, rsp->len);
291 	}
292 	return 0;
293 }
294 
295 int
otx2_ree_rule_db_len_get(const struct rte_regexdev * dev,uint32_t * rule_db_len,uint32_t * rule_dbi_len)296 otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
297 		uint32_t *rule_db_len,
298 		uint32_t *rule_dbi_len)
299 {
300 	struct otx2_ree_data *data = dev->data->dev_private;
301 	struct ree_rule_db_len_rsp_msg *rsp;
302 	struct otx2_ree_vf *vf = &data->vf;
303 	struct ree_req_msg *req;
304 	struct otx2_mbox *mbox;
305 	int ret;
306 
307 	mbox = vf->otx2_dev.mbox;
308 	req = (struct ree_req_msg *)
309 		otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), sizeof(*rsp));
310 	if (!req) {
311 		otx2_err("Could not allocate mailbox message");
312 		return -EFAULT;
313 	}
314 
315 	req->hdr.id = MBOX_MSG_REE_RULE_DB_LEN_GET;
316 	req->hdr.sig = OTX2_MBOX_REQ_SIG;
317 	req->hdr.pcifunc = vf->otx2_dev.pf_func;
318 	req->blkaddr = vf->block_address;
319 	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
320 	if (ret)
321 		return ret;
322 	if (rule_db_len != NULL)
323 		*rule_db_len = rsp->len;
324 	if (rule_dbi_len != NULL)
325 		*rule_dbi_len = rsp->inc_len;
326 
327 	return 0;
328 }
329 
330 static int
ree_db_msg(const struct rte_regexdev * dev,const char * db,uint32_t db_len,int inc,int dbi)331 ree_db_msg(const struct rte_regexdev *dev, const char *db, uint32_t db_len,
332 		int inc, int dbi)
333 {
334 	struct otx2_ree_data *data = dev->data->dev_private;
335 	uint32_t len_left = db_len, offset = 0;
336 	struct ree_rule_db_prog_req_msg *req;
337 	struct otx2_ree_vf *vf = &data->vf;
338 	const char *rule_db_ptr = db;
339 	struct otx2_mbox *mbox;
340 	struct msg_rsp *rsp;
341 	int ret;
342 
343 	mbox = vf->otx2_dev.mbox;
344 	while (len_left) {
345 		req = (struct ree_rule_db_prog_req_msg *)
346 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
347 						sizeof(*rsp));
348 		if (!req) {
349 			otx2_err("Could not allocate mailbox message");
350 			return -EFAULT;
351 		}
352 		req->hdr.id = MBOX_MSG_REE_RULE_DB_PROG;
353 		req->hdr.sig = OTX2_MBOX_REQ_SIG;
354 		req->hdr.pcifunc = vf->otx2_dev.pf_func;
355 		req->offset = offset;
356 		req->total_len = db_len;
357 		req->len = REE_RULE_DB_REQ_BLOCK_SIZE;
358 		req->is_incremental = inc;
359 		req->is_dbi = dbi;
360 		req->blkaddr = vf->block_address;
361 
362 		if (len_left < REE_RULE_DB_REQ_BLOCK_SIZE) {
363 			req->is_last = true;
364 			req->len = len_left;
365 		}
366 		otx2_mbox_memcpy(req->rule_db, rule_db_ptr, req->len);
367 		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
368 		if (ret) {
369 			otx2_err("Programming mailbox processing failed");
370 			return ret;
371 		}
372 		len_left -= req->len;
373 		offset += req->len;
374 		rule_db_ptr = rule_db_ptr + req->len;
375 	}
376 	return 0;
377 }
378 
379 int
otx2_ree_rule_db_prog(const struct rte_regexdev * dev,const char * rule_db,uint32_t rule_db_len,const char * rule_dbi,uint32_t rule_dbi_len)380 otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
381 		uint32_t rule_db_len, const char *rule_dbi,
382 		uint32_t rule_dbi_len)
383 {
384 	int inc, ret;
385 
386 	if (rule_db_len == 0) {
387 		otx2_err("Couldn't program empty rule db");
388 		return -EFAULT;
389 	}
390 	inc = (rule_dbi_len != 0);
391 	if ((rule_db == NULL) || (inc && (rule_dbi == NULL))) {
392 		otx2_err("Couldn't program NULL rule db");
393 		return -EFAULT;
394 	}
395 	if (inc) {
396 		ret = ree_db_msg(dev, rule_dbi, rule_dbi_len, inc, 1);
397 		if (ret)
398 			return ret;
399 	}
400 	return ree_db_msg(dev, rule_db, rule_db_len, inc, 0);
401 }
402