net/mlx5: set Tx queue affinity in round-robin
[dpdk.git] / drivers / regex / octeontx2 / otx2_regexdev_mbox.c
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
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
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
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
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
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
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
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
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
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
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
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
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 }