build: remove library name from version map file name
[dpdk.git] / drivers / regex / octeontx2 / otx2_regexdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2020 Marvell International Ltd.
3  */
4
5 #include <stdio.h>
6 #include <unistd.h>
7
8 #include <rte_malloc.h>
9 #include <rte_memzone.h>
10 #include <rte_regexdev.h>
11 #include <rte_regexdev_core.h>
12 #include <rte_regexdev_driver.h>
13
14
15 /* REE common headers */
16 #include "otx2_common.h"
17 #include "otx2_dev.h"
18 #include "otx2_regexdev.h"
19 #include "otx2_regexdev_compiler.h"
20 #include "otx2_regexdev_hw_access.h"
21 #include "otx2_regexdev_mbox.h"
22
23
24 /* HW matches are at offset 0x80 from RES_PTR_ADDR
25  * In op structure matches starts at W5 (0x28)
26  * There is a need to copy to 0x28 to 0x80 The matches that are at the tail
27  * Which are 88 B. Each match holds 8 B, so up to 11 matches can be copied
28  */
29 #define REE_NUM_MATCHES_ALIGN   11
30 /* The REE co-processor will write up to 254 job match structures
31  * (REE_MATCH_S) starting at address [RES_PTR_ADDR] + 0x80.
32  */
33 #define REE_MATCH_OFFSET        0x80
34
35 #define REE_MAX_RULES_PER_GROUP 0xFFFF
36 #define REE_MAX_GROUPS 0xFFFF
37
38 /* This is temporarily here */
39 #define REE0_PF 19
40 #define REE1_PF 20
41
42 #define REE_RULE_DB_VERSION     2
43 #define REE_RULE_DB_REVISION    0
44
45 struct ree_rule_db_entry {
46         uint8_t         type;
47         uint32_t        addr;
48         uint64_t        value;
49 };
50
51 struct ree_rule_db {
52         uint32_t version;
53         uint32_t revision;
54         uint32_t number_of_entries;
55         struct ree_rule_db_entry entries[];
56 } __rte_packed;
57
58 static void
59 qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
60 {
61         snprintf(name, size, "otx2_ree_lf_mem_%u:%u", dev_id, qp_id);
62 }
63
64 static struct otx2_ree_qp *
65 ree_qp_create(const struct rte_regexdev *dev, uint16_t qp_id)
66 {
67         struct otx2_ree_data *data = dev->data->dev_private;
68         uint64_t pg_sz = sysconf(_SC_PAGESIZE);
69         struct otx2_ree_vf *vf = &data->vf;
70         const struct rte_memzone *lf_mem;
71         uint32_t len, iq_len, size_div2;
72         char name[RTE_MEMZONE_NAMESIZE];
73         uint64_t used_len, iova;
74         struct otx2_ree_qp *qp;
75         uint8_t *va;
76         int ret;
77
78         /* Allocate queue pair */
79         qp = rte_zmalloc("OCTEON TX2 Regex PMD Queue Pair", sizeof(*qp),
80                                 OTX2_ALIGN);
81         if (qp == NULL) {
82                 otx2_err("Could not allocate queue pair");
83                 return NULL;
84         }
85
86         iq_len = OTX2_REE_IQ_LEN;
87
88         /*
89          * Queue size must be in units of 128B 2 * REE_INST_S (which is 64B),
90          * and a power of 2.
91          * effective queue size to software is (size - 1) * 128
92          */
93         size_div2 = iq_len >> 1;
94
95         /* For pending queue */
96         len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
97
98         /* So that instruction queues start as pg size aligned */
99         len = RTE_ALIGN(len, pg_sz);
100
101         /* For instruction queues */
102         len += OTX2_REE_IQ_LEN * sizeof(union otx2_ree_inst);
103
104         /* Waste after instruction queues */
105         len = RTE_ALIGN(len, pg_sz);
106
107         qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
108                             qp_id);
109
110         lf_mem = rte_memzone_reserve_aligned(name, len, vf->otx2_dev.node,
111                         RTE_MEMZONE_SIZE_HINT_ONLY | RTE_MEMZONE_256MB,
112                         RTE_CACHE_LINE_SIZE);
113         if (lf_mem == NULL) {
114                 otx2_err("Could not allocate reserved memzone");
115                 goto qp_free;
116         }
117
118         va = lf_mem->addr;
119         iova = lf_mem->iova;
120
121         memset(va, 0, len);
122
123         /* Initialize pending queue */
124         qp->pend_q.rid_queue = (struct otx2_ree_rid *)va;
125         qp->pend_q.enq_tail = 0;
126         qp->pend_q.deq_head = 0;
127         qp->pend_q.pending_count = 0;
128
129         used_len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
130         used_len = RTE_ALIGN(used_len, pg_sz);
131         iova += used_len;
132
133         qp->iq_dma_addr = iova;
134         qp->id = qp_id;
135         qp->base = OTX2_REE_LF_BAR2(vf, qp_id);
136         qp->otx2_regexdev_jobid = 0;
137         qp->write_offset = 0;
138
139         ret = otx2_ree_iq_enable(dev, qp, OTX2_REE_QUEUE_HI_PRIO, size_div2);
140         if (ret) {
141                 otx2_err("Could not enable instruction queue");
142                 goto qp_free;
143         }
144
145         return qp;
146
147 qp_free:
148         rte_free(qp);
149         return NULL;
150 }
151
152 static int
153 ree_qp_destroy(const struct rte_regexdev *dev, struct otx2_ree_qp *qp)
154 {
155         const struct rte_memzone *lf_mem;
156         char name[RTE_MEMZONE_NAMESIZE];
157         int ret;
158
159         otx2_ree_iq_disable(qp);
160
161         qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
162                             qp->id);
163
164         lf_mem = rte_memzone_lookup(name);
165
166         ret = rte_memzone_free(lf_mem);
167         if (ret)
168                 return ret;
169
170         rte_free(qp);
171
172         return 0;
173 }
174
175 static int
176 ree_queue_pair_release(struct rte_regexdev *dev, uint16_t qp_id)
177 {
178         struct otx2_ree_data *data = dev->data->dev_private;
179         struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
180         int ret;
181
182         ree_func_trace("Queue=%d", qp_id);
183
184         if (qp == NULL)
185                 return -EINVAL;
186
187         ret = ree_qp_destroy(dev, qp);
188         if (ret) {
189                 otx2_err("Could not destroy queue pair %d", qp_id);
190                 return ret;
191         }
192
193         data->queue_pairs[qp_id] = NULL;
194
195         return 0;
196 }
197
198 static struct rte_regexdev *
199 ree_dev_register(const char *name)
200 {
201         struct rte_regexdev *dev;
202
203         otx2_ree_dbg("Creating regexdev %s\n", name);
204
205         /* allocate device structure */
206         dev = rte_regexdev_register(name);
207         if (dev == NULL) {
208                 otx2_err("Failed to allocate regex device for %s", name);
209                 return NULL;
210         }
211
212         /* allocate private device structure */
213         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
214                 dev->data->dev_private =
215                                 rte_zmalloc_socket("regexdev device private",
216                                                 sizeof(struct otx2_ree_data),
217                                                 RTE_CACHE_LINE_SIZE,
218                                                 rte_socket_id());
219
220                 if (dev->data->dev_private == NULL) {
221                         otx2_err("Cannot allocate memory for dev %s private data",
222                                         name);
223
224                         rte_regexdev_unregister(dev);
225                         return NULL;
226                 }
227         }
228
229         return dev;
230 }
231
232 static int
233 ree_dev_unregister(struct rte_regexdev *dev)
234 {
235         otx2_ree_dbg("Closing regex device %s", dev->device->name);
236
237         /* free regex device */
238         rte_regexdev_unregister(dev);
239
240         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
241                 rte_free(dev->data->dev_private);
242
243         return 0;
244 }
245
246 static int
247 ree_dev_fini(struct rte_regexdev *dev)
248 {
249         struct otx2_ree_data *data = dev->data->dev_private;
250         struct rte_pci_device *pci_dev;
251         int i, ret;
252
253         ree_func_trace();
254
255         for (i = 0; i < data->nb_queue_pairs; i++) {
256                 ret = ree_queue_pair_release(dev, i);
257                 if (ret)
258                         return ret;
259         }
260
261         ret = otx2_ree_queues_detach(dev);
262         if (ret)
263                 otx2_err("Could not detach queues");
264
265         /* TEMP : should be in lib */
266         if (data->queue_pairs)
267                 rte_free(data->queue_pairs);
268         if (data->rules)
269                 rte_free(data->rules);
270
271         pci_dev = container_of(dev->device, struct rte_pci_device, device);
272         otx2_dev_fini(pci_dev, &(data->vf.otx2_dev));
273
274         ret = ree_dev_unregister(dev);
275         if (ret)
276                 otx2_err("Could not destroy PMD");
277
278         return ret;
279 }
280
281 static inline int
282 ree_enqueue(struct otx2_ree_qp *qp, struct rte_regex_ops *op,
283                  struct otx2_ree_pending_queue *pend_q)
284 {
285         union otx2_ree_inst inst;
286         union otx2_ree_res *res;
287         uint32_t offset;
288
289         if (unlikely(pend_q->pending_count >= OTX2_REE_DEFAULT_CMD_QLEN)) {
290                 otx2_err("Pending count %" PRIu64 " is greater than Q size %d",
291                 pend_q->pending_count, OTX2_REE_DEFAULT_CMD_QLEN);
292                 return -EAGAIN;
293         }
294         if (unlikely(op->mbuf->data_len > OTX2_REE_MAX_PAYLOAD_SIZE ||
295                         op->mbuf->data_len == 0)) {
296                 otx2_err("Packet length %d is greater than MAX payload %d",
297                                 op->mbuf->data_len, OTX2_REE_MAX_PAYLOAD_SIZE);
298                 return -EAGAIN;
299         }
300
301         /* W 0 */
302         inst.cn98xx.ooj = 1;
303         inst.cn98xx.dg = 0;
304         inst.cn98xx.doneint = 0;
305         /* W 1 */
306         inst.cn98xx.inp_ptr_addr = rte_pktmbuf_mtod(op->mbuf, uint64_t);
307         /* W 2 */
308         inst.cn98xx.inp_ptr_ctl = op->mbuf->data_len & 0x7FFF;
309         inst.cn98xx.inp_ptr_ctl = inst.cn98xx.inp_ptr_ctl << 32;
310
311         /* W 3 */
312         inst.cn98xx.res_ptr_addr = (uint64_t)op;
313         /* W 4 */
314         inst.cn98xx.wq_ptr = 0;
315         /* W 5 */
316         inst.cn98xx.ggrp = 0;
317         inst.cn98xx.tt = 0;
318         inst.cn98xx.tag = 0;
319         /* W 6 */
320         inst.cn98xx.ree_job_length = op->mbuf->data_len & 0x7FFF;
321         if (op->req_flags & RTE_REGEX_OPS_REQ_STOP_ON_MATCH_F)
322                 inst.cn98xx.ree_job_ctrl = (0x2 << 8);
323         else if (op->req_flags & RTE_REGEX_OPS_REQ_MATCH_HIGH_PRIORITY_F)
324                 inst.cn98xx.ree_job_ctrl = (0x1 << 8);
325         else
326                 inst.cn98xx.ree_job_ctrl = 0;
327         inst.cn98xx.ree_job_id = qp->otx2_regexdev_jobid;
328         /* W 7 */
329         inst.cn98xx.ree_job_subset_id_0 = op->group_id0;
330         if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID1_VALID_F)
331                 inst.cn98xx.ree_job_subset_id_1 = op->group_id1;
332         else
333                 inst.cn98xx.ree_job_subset_id_1 = op->group_id0;
334         if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID2_VALID_F)
335                 inst.cn98xx.ree_job_subset_id_2 = op->group_id2;
336         else
337                 inst.cn98xx.ree_job_subset_id_2 = op->group_id0;
338         if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID3_VALID_F)
339                 inst.cn98xx.ree_job_subset_id_3 = op->group_id3;
340         else
341                 inst.cn98xx.ree_job_subset_id_3 = op->group_id0;
342
343         /* Copy REE command to Q */
344         offset = qp->write_offset * sizeof(inst);
345         memcpy((void *)(qp->iq_dma_addr + offset), &inst, sizeof(inst));
346
347         pend_q->rid_queue[pend_q->enq_tail].rid = (uintptr_t)op;
348         pend_q->rid_queue[pend_q->enq_tail].user_id = op->user_id;
349
350         /* Mark result as not done */
351         res = (union otx2_ree_res *)(op);
352         res->s.done = 0;
353         res->s.ree_err = 0;
354
355         /* We will use soft queue length here to limit requests */
356         REE_MOD_INC(pend_q->enq_tail, OTX2_REE_DEFAULT_CMD_QLEN);
357         pend_q->pending_count += 1;
358         REE_MOD_INC(qp->otx2_regexdev_jobid, 0xFFFFFF);
359         REE_MOD_INC(qp->write_offset, OTX2_REE_IQ_LEN);
360
361         return 0;
362 }
363
364 static uint16_t
365 otx2_ree_enqueue_burst(struct rte_regexdev *dev, uint16_t qp_id,
366                        struct rte_regex_ops **ops, uint16_t nb_ops)
367 {
368         struct otx2_ree_data *data = dev->data->dev_private;
369         struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
370         struct otx2_ree_pending_queue *pend_q;
371         uint16_t nb_allowed, count = 0;
372         struct rte_regex_ops *op;
373         int ret;
374
375         pend_q = &qp->pend_q;
376
377         nb_allowed = OTX2_REE_DEFAULT_CMD_QLEN - pend_q->pending_count;
378         if (nb_ops > nb_allowed)
379                 nb_ops = nb_allowed;
380
381         for (count = 0; count < nb_ops; count++) {
382                 op = ops[count];
383                 ret = ree_enqueue(qp, op, pend_q);
384
385                 if (unlikely(ret))
386                         break;
387         }
388
389         /*
390          * Make sure all instructions are written before DOORBELL is activated
391          */
392         rte_io_wmb();
393
394         /* Update Doorbell */
395         otx2_write64(count, qp->base + OTX2_REE_LF_DOORBELL);
396
397         return count;
398 }
399
400 static inline void
401 ree_dequeue_post_process(struct rte_regex_ops *ops)
402 {
403         uint8_t ree_res_mcnt, ree_res_dmcnt;
404         int off = REE_MATCH_OFFSET;
405         struct ree_res_s_98 *res;
406         uint16_t ree_res_status;
407         uint64_t match;
408
409         res = (struct ree_res_s_98 *)ops;
410         /* store res values on stack since ops and res
411          * are using the same memory
412          */
413         ree_res_status = res->ree_res_status;
414         ree_res_mcnt = res->ree_res_mcnt;
415         ree_res_dmcnt = res->ree_res_dmcnt;
416         ops->rsp_flags = 0;
417         ops->nb_actual_matches = ree_res_dmcnt;
418         ops->nb_matches = ree_res_mcnt;
419         if (unlikely(res->ree_err)) {
420                 ops->nb_actual_matches = 0;
421                 ops->nb_matches = 0;
422         }
423
424         if (unlikely(ree_res_status != REE_TYPE_RESULT_DESC)) {
425                 if (ree_res_status & OTX2_REE_STATUS_PMI_SOJ_BIT)
426                         ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_SOJ_F;
427                 if (ree_res_status & OTX2_REE_STATUS_PMI_EOJ_BIT)
428                         ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_EOJ_F;
429                 if (ree_res_status & OTX2_REE_STATUS_ML_CNT_DET_BIT)
430                         ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_SCAN_TIMEOUT_F;
431                 if (ree_res_status & OTX2_REE_STATUS_MM_CNT_DET_BIT)
432                         ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_MATCH_F;
433                 if (ree_res_status & OTX2_REE_STATUS_MP_CNT_DET_BIT)
434                         ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_PREFIX_F;
435         }
436         if (ops->nb_matches > 0) {
437                 /* Move the matches to the correct offset */
438                 off = ((ops->nb_matches < REE_NUM_MATCHES_ALIGN) ?
439                         ops->nb_matches : REE_NUM_MATCHES_ALIGN);
440                 match = (uint64_t)ops + REE_MATCH_OFFSET;
441                 match += (ops->nb_matches - off) *
442                         sizeof(union otx2_ree_match);
443                 memcpy((void *)ops->matches, (void *)match,
444                         off * sizeof(union otx2_ree_match));
445         }
446 }
447
448 static uint16_t
449 otx2_ree_dequeue_burst(struct rte_regexdev *dev, uint16_t qp_id,
450                        struct rte_regex_ops **ops, uint16_t nb_ops)
451 {
452         struct otx2_ree_data *data = dev->data->dev_private;
453         struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
454         struct otx2_ree_pending_queue *pend_q;
455         int i, nb_pending, nb_completed = 0;
456         volatile struct ree_res_s_98 *res;
457         struct otx2_ree_rid *rid;
458
459         pend_q = &qp->pend_q;
460
461         nb_pending = pend_q->pending_count;
462
463         if (nb_ops > nb_pending)
464                 nb_ops = nb_pending;
465
466         for (i = 0; i < nb_ops; i++) {
467                 rid = &pend_q->rid_queue[pend_q->deq_head];
468                 res = (volatile struct ree_res_s_98 *)(rid->rid);
469
470                 /* Check response header done bit if completed */
471                 if (unlikely(!res->done))
472                         break;
473
474                 ops[i] = (struct rte_regex_ops *)(rid->rid);
475                 ops[i]->user_id = rid->user_id;
476
477                 REE_MOD_INC(pend_q->deq_head, OTX2_REE_DEFAULT_CMD_QLEN);
478                 pend_q->pending_count -= 1;
479         }
480
481         nb_completed = i;
482
483         for (i = 0; i < nb_completed; i++)
484                 ree_dequeue_post_process(ops[i]);
485
486         return nb_completed;
487 }
488
489 static int
490 otx2_ree_dev_info_get(struct rte_regexdev *dev, struct rte_regexdev_info *info)
491 {
492         struct otx2_ree_data *data = dev->data->dev_private;
493         struct otx2_ree_vf *vf = &data->vf;
494
495         ree_func_trace();
496
497         if (info == NULL)
498                 return -EINVAL;
499
500         info->driver_name = dev->device->driver->name;
501         info->dev = dev->device;
502
503         info->max_queue_pairs = vf->max_queues;
504         info->max_matches = vf->max_matches;
505         info->max_payload_size = OTX2_REE_MAX_PAYLOAD_SIZE;
506         info->max_rules_per_group = data->max_rules_per_group;
507         info->max_groups = data->max_groups;
508         info->regexdev_capa = data->regexdev_capa;
509         info->rule_flags = data->rule_flags;
510
511         return 0;
512 }
513
514 static int
515 otx2_ree_dev_config(struct rte_regexdev *dev,
516                     const struct rte_regexdev_config *cfg)
517 {
518         struct otx2_ree_data *data = dev->data->dev_private;
519         struct otx2_ree_vf *vf = &data->vf;
520         const struct ree_rule_db *rule_db;
521         uint32_t rule_db_len;
522         int ret;
523
524         ree_func_trace();
525
526         if (cfg->nb_queue_pairs > vf->max_queues) {
527                 otx2_err("Invalid number of queue pairs requested");
528                 return -EINVAL;
529         }
530
531         if (cfg->nb_max_matches != vf->max_matches) {
532                 otx2_err("Invalid number of max matches requested");
533                 return -EINVAL;
534         }
535
536         if (cfg->dev_cfg_flags != 0) {
537                 otx2_err("Invalid device configuration flags requested");
538                 return -EINVAL;
539         }
540
541         /* Unregister error interrupts */
542         if (vf->err_intr_registered)
543                 otx2_ree_err_intr_unregister(dev);
544
545         /* Detach queues */
546         if (vf->nb_queues) {
547                 ret = otx2_ree_queues_detach(dev);
548                 if (ret) {
549                         otx2_err("Could not detach REE queues");
550                         return ret;
551                 }
552         }
553
554         /* TEMP : should be in lib */
555         if (data->queue_pairs == NULL) { /* first time configuration */
556                 data->queue_pairs = rte_zmalloc("regexdev->queue_pairs",
557                                 sizeof(data->queue_pairs[0]) *
558                                 cfg->nb_queue_pairs, RTE_CACHE_LINE_SIZE);
559
560                 if (data->queue_pairs == NULL) {
561                         data->nb_queue_pairs = 0;
562                         otx2_err("Failed to get memory for qp meta data, nb_queues %u",
563                                         cfg->nb_queue_pairs);
564                         return -ENOMEM;
565                 }
566         } else { /* re-configure */
567                 uint16_t old_nb_queues = data->nb_queue_pairs;
568                 void **qp;
569                 unsigned int i;
570
571                 qp = data->queue_pairs;
572
573                 for (i = cfg->nb_queue_pairs; i < old_nb_queues; i++) {
574                         ret = ree_queue_pair_release(dev, i);
575                         if (ret < 0)
576                                 return ret;
577                 }
578
579                 qp = rte_realloc(qp, sizeof(qp[0]) * cfg->nb_queue_pairs,
580                                 RTE_CACHE_LINE_SIZE);
581                 if (qp == NULL) {
582                         otx2_err("Failed to realloc qp meta data, nb_queues %u",
583                                         cfg->nb_queue_pairs);
584                         return -ENOMEM;
585                 }
586
587                 if (cfg->nb_queue_pairs > old_nb_queues) {
588                         uint16_t new_qs = cfg->nb_queue_pairs - old_nb_queues;
589                         memset(qp + old_nb_queues, 0, sizeof(qp[0]) * new_qs);
590                 }
591
592                 data->queue_pairs = qp;
593         }
594         data->nb_queue_pairs = cfg->nb_queue_pairs;
595
596         /* Attach queues */
597         otx2_ree_dbg("Attach %d queues", cfg->nb_queue_pairs);
598         ret = otx2_ree_queues_attach(dev, cfg->nb_queue_pairs);
599         if (ret) {
600                 otx2_err("Could not attach queues");
601                 return -ENODEV;
602         }
603
604         ret = otx2_ree_msix_offsets_get(dev);
605         if (ret) {
606                 otx2_err("Could not get MSI-X offsets");
607                 goto queues_detach;
608         }
609
610         if (cfg->rule_db && cfg->rule_db_len) {
611                 otx2_ree_dbg("rule_db length %d", cfg->rule_db_len);
612                 rule_db = (const struct ree_rule_db *)cfg->rule_db;
613                 rule_db_len = rule_db->number_of_entries *
614                                 sizeof(struct ree_rule_db_entry);
615                 otx2_ree_dbg("rule_db number of entries %d",
616                                 rule_db->number_of_entries);
617                 if (rule_db_len > cfg->rule_db_len) {
618                         otx2_err("Could not program rule db");
619                         ret = -EINVAL;
620                         goto queues_detach;
621                 }
622                 ret = otx2_ree_rule_db_prog(dev, (const char *)rule_db->entries,
623                                 rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
624                 if (ret) {
625                         otx2_err("Could not program rule db");
626                         goto queues_detach;
627                 }
628         }
629
630         dev->enqueue = otx2_ree_enqueue_burst;
631         dev->dequeue = otx2_ree_dequeue_burst;
632
633         rte_mb();
634         return 0;
635
636 queues_detach:
637         otx2_ree_queues_detach(dev);
638         return ret;
639 }
640
641 static int
642 otx2_ree_stop(struct rte_regexdev *dev)
643 {
644         RTE_SET_USED(dev);
645
646         ree_func_trace();
647         return 0;
648 }
649
650 static int
651 otx2_ree_start(struct rte_regexdev *dev)
652 {
653         uint32_t rule_db_len = 0;
654         int ret;
655
656         ree_func_trace();
657
658         ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, NULL);
659         if (ret)
660                 return ret;
661         if (rule_db_len == 0) {
662                 otx2_err("Rule db not programmed");
663                 return -EFAULT;
664         }
665
666         return 0;
667 }
668
669 static int
670 otx2_ree_close(struct rte_regexdev *dev)
671 {
672         return ree_dev_fini(dev);
673 }
674
675 static int
676 otx2_ree_queue_pair_setup(struct rte_regexdev *dev, uint16_t qp_id,
677                 const struct rte_regexdev_qp_conf *qp_conf)
678 {
679         struct otx2_ree_data *data = dev->data->dev_private;
680         struct otx2_ree_qp *qp;
681
682         ree_func_trace("Queue=%d", qp_id);
683
684         if (data->queue_pairs[qp_id] != NULL)
685                 ree_queue_pair_release(dev, qp_id);
686
687         if (qp_conf->nb_desc > OTX2_REE_DEFAULT_CMD_QLEN) {
688                 otx2_err("Could not setup queue pair for %u descriptors",
689                                 qp_conf->nb_desc);
690                 return -EINVAL;
691         }
692         if (qp_conf->qp_conf_flags != 0) {
693                 otx2_err("Could not setup queue pair with configuration flags 0x%x",
694                                 qp_conf->qp_conf_flags);
695                 return -EINVAL;
696         }
697
698         qp = ree_qp_create(dev, qp_id);
699         if (qp == NULL) {
700                 otx2_err("Could not create queue pair %d", qp_id);
701                 return -ENOMEM;
702         }
703         qp->cb = qp_conf->cb;
704         data->queue_pairs[qp_id] = qp;
705
706         return 0;
707 }
708
709 static int
710 otx2_ree_rule_db_compile_activate(struct rte_regexdev *dev)
711 {
712         return otx2_ree_rule_db_compile_prog(dev);
713 }
714
715 static int
716 otx2_ree_rule_db_update(struct rte_regexdev *dev,
717                 const struct rte_regexdev_rule *rules, uint16_t nb_rules)
718 {
719         struct otx2_ree_data *data = dev->data->dev_private;
720         struct rte_regexdev_rule *old_ptr;
721         uint32_t i, sum_nb_rules;
722
723         ree_func_trace("nb_rules=%d", nb_rules);
724
725         for (i = 0; i < nb_rules; i++) {
726                 if (rules[i].op == RTE_REGEX_RULE_OP_REMOVE)
727                         break;
728                 if (rules[i].group_id >= data->max_groups)
729                         break;
730                 if (rules[i].rule_id >= data->max_rules_per_group)
731                         break;
732                 /* logical implication
733                  * p    q    p -> q
734                  * 0    0      1
735                  * 0    1      1
736                  * 1    0      0
737                  * 1    1      1
738                  */
739                 if ((~(rules[i].rule_flags) | data->rule_flags) == 0)
740                         break;
741         }
742         nb_rules = i;
743
744         if (data->nb_rules == 0) {
745
746                 data->rules = rte_malloc("rte_regexdev_rules",
747                                 nb_rules*sizeof(struct rte_regexdev_rule), 0);
748                 if (data->rules == NULL)
749                         return -ENOMEM;
750
751                 memcpy(data->rules, rules,
752                                 nb_rules*sizeof(struct rte_regexdev_rule));
753                 data->nb_rules = nb_rules;
754         } else {
755
756                 old_ptr = data->rules;
757                 sum_nb_rules = data->nb_rules + nb_rules;
758                 data->rules = rte_realloc(data->rules,
759                                 sum_nb_rules * sizeof(struct rte_regexdev_rule),
760                                                         0);
761                 if (data->rules == NULL) {
762                         data->rules = old_ptr;
763                         return -ENOMEM;
764                 }
765                 memcpy(&data->rules[data->nb_rules], rules,
766                                 nb_rules*sizeof(struct rte_regexdev_rule));
767                 data->nb_rules = sum_nb_rules;
768         }
769         return nb_rules;
770 }
771
772 static int
773 otx2_ree_rule_db_import(struct rte_regexdev *dev, const char *rule_db,
774                 uint32_t rule_db_len)
775 {
776
777         const struct ree_rule_db *ree_rule_db;
778         uint32_t ree_rule_db_len;
779         int ret;
780
781         ree_func_trace("rule_db_len=%d", rule_db_len);
782
783         ree_rule_db = (const struct ree_rule_db *)rule_db;
784         ree_rule_db_len = ree_rule_db->number_of_entries *
785                         sizeof(struct ree_rule_db_entry);
786         if (ree_rule_db_len > rule_db_len) {
787                 otx2_err("Could not program rule db");
788                 return -EINVAL;
789         }
790         ret = otx2_ree_rule_db_prog(dev, (const char *)ree_rule_db->entries,
791                         ree_rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
792         if (ret) {
793                 otx2_err("Could not program rule db");
794                 return -ENOSPC;
795         }
796         return 0;
797 }
798
799 static int
800 otx2_ree_rule_db_export(struct rte_regexdev *dev, char *rule_db)
801 {
802         struct ree_rule_db *ree_rule_db;
803         uint32_t rule_dbi_len;
804         uint32_t rule_db_len;
805         int ret;
806
807         ree_func_trace();
808
809         ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
810         if (ret)
811                 return ret;
812
813         if (rule_db == NULL) {
814                 rule_db_len += sizeof(struct ree_rule_db);
815                 return rule_db_len;
816         }
817
818         ree_rule_db = (struct ree_rule_db *)rule_db;
819         ret = otx2_ree_rule_db_get(dev, (char *)ree_rule_db->entries,
820                         rule_db_len, NULL, 0);
821         if (ret) {
822                 otx2_err("Could not export rule db");
823                 return -EFAULT;
824         }
825         ree_rule_db->number_of_entries =
826                         rule_db_len/sizeof(struct ree_rule_db_entry);
827         ree_rule_db->revision = REE_RULE_DB_REVISION;
828         ree_rule_db->version = REE_RULE_DB_VERSION;
829
830         return 0;
831 }
832
833 static int
834 ree_get_blkaddr(struct otx2_dev *dev)
835 {
836         int pf;
837
838         pf = otx2_get_pf(dev->pf_func);
839         if (pf == REE0_PF)
840                 return RVU_BLOCK_ADDR_REE0;
841         else if (pf == REE1_PF)
842                 return RVU_BLOCK_ADDR_REE1;
843         else
844                 return 0;
845 }
846
847 static struct rte_regexdev_ops otx2_ree_ops = {
848                 .dev_info_get = otx2_ree_dev_info_get,
849                 .dev_configure = otx2_ree_dev_config,
850                 .dev_qp_setup = otx2_ree_queue_pair_setup,
851                 .dev_start = otx2_ree_start,
852                 .dev_stop = otx2_ree_stop,
853                 .dev_close = otx2_ree_close,
854                 .dev_attr_get = NULL,
855                 .dev_attr_set = NULL,
856                 .dev_rule_db_update = otx2_ree_rule_db_update,
857                 .dev_rule_db_compile_activate =
858                                 otx2_ree_rule_db_compile_activate,
859                 .dev_db_import = otx2_ree_rule_db_import,
860                 .dev_db_export = otx2_ree_rule_db_export,
861                 .dev_xstats_names_get = NULL,
862                 .dev_xstats_get = NULL,
863                 .dev_xstats_by_name_get = NULL,
864                 .dev_xstats_reset = NULL,
865                 .dev_selftest = NULL,
866                 .dev_dump = NULL,
867 };
868
869 static int
870 otx2_ree_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
871                    struct rte_pci_device *pci_dev)
872 {
873         char name[RTE_REGEXDEV_NAME_MAX_LEN];
874         struct otx2_ree_data *data;
875         struct otx2_dev *otx2_dev;
876         struct rte_regexdev *dev;
877         uint8_t max_matches = 0;
878         struct otx2_ree_vf *vf;
879         uint16_t nb_queues = 0;
880         int ret;
881
882         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
883
884         dev = ree_dev_register(name);
885         if (dev == NULL) {
886                 ret = -ENODEV;
887                 goto exit;
888         }
889
890         dev->dev_ops = &otx2_ree_ops;
891         dev->device = &pci_dev->device;
892
893         /* Get private data space allocated */
894         data = dev->data->dev_private;
895         vf = &data->vf;
896
897         otx2_dev = &vf->otx2_dev;
898
899         /* Initialize the base otx2_dev object */
900         ret = otx2_dev_init(pci_dev, otx2_dev);
901         if (ret) {
902                 otx2_err("Could not initialize otx2_dev");
903                 goto dev_unregister;
904         }
905         /* Get REE block address */
906         vf->block_address = ree_get_blkaddr(otx2_dev);
907         if (!vf->block_address) {
908                 otx2_err("Could not determine block PF number");
909                 goto otx2_dev_fini;
910         }
911
912         /* Get number of queues available on the device */
913         ret = otx2_ree_available_queues_get(dev, &nb_queues);
914         if (ret) {
915                 otx2_err("Could not determine the number of queues available");
916                 goto otx2_dev_fini;
917         }
918
919         /* Don't exceed the limits set per VF */
920         nb_queues = RTE_MIN(nb_queues, OTX2_REE_MAX_QUEUES_PER_VF);
921
922         if (nb_queues == 0) {
923                 otx2_err("No free queues available on the device");
924                 goto otx2_dev_fini;
925         }
926
927         vf->max_queues = nb_queues;
928
929         otx2_ree_dbg("Max queues supported by device: %d", vf->max_queues);
930
931         /* Get number of maximum matches supported on the device */
932         ret = otx2_ree_max_matches_get(dev, &max_matches);
933         if (ret) {
934                 otx2_err("Could not determine the maximum matches supported");
935                 goto otx2_dev_fini;
936         }
937         /* Don't exceed the limits set per VF */
938         max_matches = RTE_MIN(max_matches, OTX2_REE_MAX_MATCHES_PER_VF);
939         if (max_matches == 0) {
940                 otx2_err("Could not determine the maximum matches supported");
941                 goto otx2_dev_fini;
942         }
943
944         vf->max_matches = max_matches;
945
946         otx2_ree_dbg("Max matches supported by device: %d", vf->max_matches);
947         data->rule_flags = RTE_REGEX_PCRE_RULE_ALLOW_EMPTY_F |
948                         RTE_REGEX_PCRE_RULE_ANCHORED_F;
949         data->regexdev_capa = 0;
950         data->max_groups = REE_MAX_GROUPS;
951         data->max_rules_per_group = REE_MAX_RULES_PER_GROUP;
952         data->nb_rules = 0;
953
954         dev->state = RTE_REGEXDEV_READY;
955         return 0;
956
957 otx2_dev_fini:
958         otx2_dev_fini(pci_dev, otx2_dev);
959 dev_unregister:
960         ree_dev_unregister(dev);
961 exit:
962         otx2_err("Could not create device (vendor_id: 0x%x device_id: 0x%x)",
963                     pci_dev->id.vendor_id, pci_dev->id.device_id);
964         return ret;
965 }
966
967 static int
968 otx2_ree_pci_remove(struct rte_pci_device *pci_dev)
969 {
970         char name[RTE_REGEXDEV_NAME_MAX_LEN];
971         struct rte_regexdev *dev = NULL;
972
973         if (pci_dev == NULL)
974                 return -EINVAL;
975
976         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
977
978         dev = rte_regexdev_get_device_by_name(name);
979
980         if (dev == NULL)
981                 return -ENODEV;
982
983         return ree_dev_fini(dev);
984 }
985
986 static struct rte_pci_id pci_id_ree_table[] = {
987         {
988                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
989                                 PCI_DEVID_OCTEONTX2_RVU_REE_PF)
990         },
991 };
992
993 static struct rte_pci_driver otx2_regexdev_pmd = {
994         .id_table = pci_id_ree_table,
995         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
996         .probe = otx2_ree_pci_probe,
997         .remove = otx2_ree_pci_remove,
998 };
999
1000
1001 RTE_PMD_REGISTER_PCI(REGEXDEV_NAME_OCTEONTX2_PMD, otx2_regexdev_pmd);
1002 RTE_PMD_REGISTER_PCI_TABLE(REGEXDEV_NAME_OCTEONTX2_PMD, pci_id_ree_table);