event/octeontx2: fix Rx adapter capabilities
[dpdk.git] / drivers / event / octeontx2 / otx2_evdev_adptr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_evdev.h"
6
7 int
8 otx2_sso_rx_adapter_caps_get(const struct rte_eventdev *event_dev,
9                              const struct rte_eth_dev *eth_dev, uint32_t *caps)
10 {
11         int rc;
12
13         RTE_SET_USED(event_dev);
14         rc = strncmp(eth_dev->device->driver->name, "net_octeontx2", 13);
15         if (rc)
16                 *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP;
17         else
18                 *caps = RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT |
19                         RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ;
20
21         return 0;
22 }
23
24 static inline int
25 sso_rxq_enable(struct otx2_eth_dev *dev, uint16_t qid, uint8_t tt, uint8_t ggrp,
26                uint16_t eth_port_id)
27 {
28         struct otx2_mbox *mbox = dev->mbox;
29         struct nix_aq_enq_req *aq;
30         int rc;
31
32         aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
33         aq->qidx = qid;
34         aq->ctype = NIX_AQ_CTYPE_CQ;
35         aq->op = NIX_AQ_INSTOP_WRITE;
36
37         aq->cq.ena = 0;
38         aq->cq.caching = 0;
39
40         otx2_mbox_memset(&aq->cq_mask, 0, sizeof(struct nix_cq_ctx_s));
41         aq->cq_mask.ena = ~(aq->cq_mask.ena);
42         aq->cq_mask.caching = ~(aq->cq_mask.caching);
43
44         rc = otx2_mbox_process(mbox);
45         if (rc < 0) {
46                 otx2_err("Failed to disable cq context");
47                 goto fail;
48         }
49
50         aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
51         aq->qidx = qid;
52         aq->ctype = NIX_AQ_CTYPE_RQ;
53         aq->op = NIX_AQ_INSTOP_WRITE;
54
55         aq->rq.sso_ena = 1;
56         aq->rq.sso_tt = tt;
57         aq->rq.sso_grp = ggrp;
58         aq->rq.ena_wqwd = 1;
59         /* Mbuf Header generation :
60          * > FIRST_SKIP is a super set of WQE_SKIP, dont modify first skip as
61          * it already has data related to mbuf size, headroom, private area.
62          * > Using WQE_SKIP we can directly assign
63          *              mbuf = wqe - sizeof(struct mbuf);
64          * so that mbuf header will not have unpredicted values while headroom
65          * and private data starts at the beginning of wqe_data.
66          */
67         aq->rq.wqe_skip = 1;
68         aq->rq.wqe_caching = 1;
69         aq->rq.spb_ena = 0;
70         aq->rq.flow_tagw = 20; /* 20-bits */
71
72         /* Flow Tag calculation :
73          *
74          * rq_tag <31:24> = good/bad_tag<8:0>;
75          * rq_tag  <23:0> = [ltag]
76          *
77          * flow_tag_mask<31:0> =  (1 << flow_tagw) - 1; <31:20>
78          * tag<31:0> = (~flow_tag_mask & rq_tag) | (flow_tag_mask & flow_tag);
79          *
80          * Setup :
81          * ltag<23:0> = (eth_port_id & 0xF) << 20;
82          * good/bad_tag<8:0> =
83          *      ((eth_port_id >> 4) & 0xF) | (RTE_EVENT_TYPE_ETHDEV << 4);
84          *
85          * TAG<31:0> on getwork = <31:28>(RTE_EVENT_TYPE_ETHDEV) |
86          *                              <27:20> (eth_port_id) | <20:0> [TAG]
87          */
88
89         aq->rq.ltag = (eth_port_id & 0xF) << 20;
90         aq->rq.good_utag = ((eth_port_id >> 4) & 0xF) |
91                                 (RTE_EVENT_TYPE_ETHDEV << 4);
92         aq->rq.bad_utag = aq->rq.good_utag;
93
94         aq->rq.ena = 0;          /* Don't enable RQ yet */
95         aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
96         aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
97
98         otx2_mbox_memset(&aq->rq_mask, 0, sizeof(struct nix_rq_ctx_s));
99         /* mask the bits to write. */
100         aq->rq_mask.sso_ena      = ~(aq->rq_mask.sso_ena);
101         aq->rq_mask.sso_tt       = ~(aq->rq_mask.sso_tt);
102         aq->rq_mask.sso_grp      = ~(aq->rq_mask.sso_grp);
103         aq->rq_mask.ena_wqwd     = ~(aq->rq_mask.ena_wqwd);
104         aq->rq_mask.wqe_skip     = ~(aq->rq_mask.wqe_skip);
105         aq->rq_mask.wqe_caching  = ~(aq->rq_mask.wqe_caching);
106         aq->rq_mask.spb_ena      = ~(aq->rq_mask.spb_ena);
107         aq->rq_mask.flow_tagw    = ~(aq->rq_mask.flow_tagw);
108         aq->rq_mask.ltag         = ~(aq->rq_mask.ltag);
109         aq->rq_mask.good_utag    = ~(aq->rq_mask.good_utag);
110         aq->rq_mask.bad_utag     = ~(aq->rq_mask.bad_utag);
111         aq->rq_mask.ena          = ~(aq->rq_mask.ena);
112         aq->rq_mask.pb_caching   = ~(aq->rq_mask.pb_caching);
113         aq->rq_mask.xqe_imm_size = ~(aq->rq_mask.xqe_imm_size);
114
115         rc = otx2_mbox_process(mbox);
116         if (rc < 0) {
117                 otx2_err("Failed to init rx adapter context");
118                 goto fail;
119         }
120
121         return 0;
122 fail:
123         return rc;
124 }
125
126 static inline int
127 sso_rxq_disable(struct otx2_eth_dev *dev, uint16_t qid)
128 {
129         struct otx2_mbox *mbox = dev->mbox;
130         struct nix_aq_enq_req *aq;
131         int rc;
132
133         aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
134         aq->qidx = qid;
135         aq->ctype = NIX_AQ_CTYPE_CQ;
136         aq->op = NIX_AQ_INSTOP_INIT;
137
138         aq->cq.ena = 1;
139         aq->cq.caching = 1;
140
141         otx2_mbox_memset(&aq->cq_mask, 0, sizeof(struct nix_cq_ctx_s));
142         aq->cq_mask.ena = ~(aq->cq_mask.ena);
143         aq->cq_mask.caching = ~(aq->cq_mask.caching);
144
145         rc = otx2_mbox_process(mbox);
146         if (rc < 0) {
147                 otx2_err("Failed to init cq context");
148                 goto fail;
149         }
150
151         aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
152         aq->qidx = qid;
153         aq->ctype = NIX_AQ_CTYPE_RQ;
154         aq->op = NIX_AQ_INSTOP_WRITE;
155
156         aq->rq.sso_ena = 0;
157         aq->rq.sso_tt = SSO_TT_UNTAGGED;
158         aq->rq.sso_grp = 0;
159         aq->rq.ena_wqwd = 0;
160         aq->rq.wqe_caching = 0;
161         aq->rq.wqe_skip = 0;
162         aq->rq.spb_ena = 0;
163         aq->rq.flow_tagw = 0x20;
164         aq->rq.ltag = 0;
165         aq->rq.good_utag = 0;
166         aq->rq.bad_utag = 0;
167         aq->rq.ena = 1;
168         aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
169         aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
170
171         otx2_mbox_memset(&aq->rq_mask, 0, sizeof(struct nix_rq_ctx_s));
172         /* mask the bits to write. */
173         aq->rq_mask.sso_ena      = ~(aq->rq_mask.sso_ena);
174         aq->rq_mask.sso_tt       = ~(aq->rq_mask.sso_tt);
175         aq->rq_mask.sso_grp      = ~(aq->rq_mask.sso_grp);
176         aq->rq_mask.ena_wqwd     = ~(aq->rq_mask.ena_wqwd);
177         aq->rq_mask.wqe_caching  = ~(aq->rq_mask.wqe_caching);
178         aq->rq_mask.wqe_skip     = ~(aq->rq_mask.wqe_skip);
179         aq->rq_mask.spb_ena      = ~(aq->rq_mask.spb_ena);
180         aq->rq_mask.flow_tagw    = ~(aq->rq_mask.flow_tagw);
181         aq->rq_mask.ltag         = ~(aq->rq_mask.ltag);
182         aq->rq_mask.good_utag    = ~(aq->rq_mask.good_utag);
183         aq->rq_mask.bad_utag     = ~(aq->rq_mask.bad_utag);
184         aq->rq_mask.ena          = ~(aq->rq_mask.ena);
185         aq->rq_mask.pb_caching   = ~(aq->rq_mask.pb_caching);
186         aq->rq_mask.xqe_imm_size = ~(aq->rq_mask.xqe_imm_size);
187
188         rc = otx2_mbox_process(mbox);
189         if (rc < 0) {
190                 otx2_err("Failed to clear rx adapter context");
191                 goto fail;
192         }
193
194         return 0;
195 fail:
196         return rc;
197 }
198
199 void
200 sso_updt_xae_cnt(struct otx2_sso_evdev *dev, void *data, uint32_t event_type)
201 {
202         switch (event_type) {
203         case RTE_EVENT_TYPE_ETHDEV:
204         {
205                 struct otx2_eth_rxq *rxq = data;
206                 int i, match = false;
207                 uint64_t *old_ptr;
208
209                 for (i = 0; i < dev->rx_adptr_pool_cnt; i++) {
210                         if ((uint64_t)rxq->pool == dev->rx_adptr_pools[i])
211                                 match = true;
212                 }
213
214                 if (!match) {
215                         dev->rx_adptr_pool_cnt++;
216                         old_ptr = dev->rx_adptr_pools;
217                         dev->rx_adptr_pools = rte_realloc(dev->rx_adptr_pools,
218                                                           sizeof(uint64_t) *
219                                                           dev->rx_adptr_pool_cnt
220                                                           , 0);
221                         if (dev->rx_adptr_pools == NULL) {
222                                 dev->adptr_xae_cnt += rxq->pool->size;
223                                 dev->rx_adptr_pools = old_ptr;
224                                 dev->rx_adptr_pool_cnt--;
225                                 return;
226                         }
227                         dev->rx_adptr_pools[dev->rx_adptr_pool_cnt - 1] =
228                                 (uint64_t)rxq->pool;
229
230                         dev->adptr_xae_cnt += rxq->pool->size;
231                 }
232                 break;
233         }
234         case RTE_EVENT_TYPE_TIMER:
235         {
236                 dev->adptr_xae_cnt += (*(uint64_t *)data);
237                 break;
238         }
239         default:
240                 break;
241         }
242 }
243
244 static inline void
245 sso_updt_lookup_mem(const struct rte_eventdev *event_dev, void *lookup_mem)
246 {
247         struct otx2_sso_evdev *dev = sso_pmd_priv(event_dev);
248         int i;
249
250         for (i = 0; i < dev->nb_event_ports; i++) {
251                 if (dev->dual_ws) {
252                         struct otx2_ssogws_dual *ws = event_dev->data->ports[i];
253
254                         ws->lookup_mem = lookup_mem;
255                 } else {
256                         struct otx2_ssogws *ws = event_dev->data->ports[i];
257
258                         ws->lookup_mem = lookup_mem;
259                 }
260         }
261 }
262
263 int
264 otx2_sso_rx_adapter_queue_add(const struct rte_eventdev *event_dev,
265                               const struct rte_eth_dev *eth_dev,
266                               int32_t rx_queue_id,
267                 const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
268 {
269         struct otx2_eth_dev *otx2_eth_dev = eth_dev->data->dev_private;
270         struct otx2_sso_evdev *dev = sso_pmd_priv(event_dev);
271         uint16_t port = eth_dev->data->port_id;
272         struct otx2_eth_rxq *rxq;
273         int i, rc;
274
275         rc = strncmp(eth_dev->device->driver->name, "net_octeontx2", 13);
276         if (rc)
277                 return -EINVAL;
278
279         if (rx_queue_id < 0) {
280                 for (i = 0 ; i < eth_dev->data->nb_rx_queues; i++) {
281                         rxq = eth_dev->data->rx_queues[i];
282                         sso_updt_xae_cnt(dev, rxq, RTE_EVENT_TYPE_ETHDEV);
283                         rc = sso_xae_reconfigure((struct rte_eventdev *)
284                                                  (uintptr_t)event_dev);
285                         rc |= sso_rxq_enable(otx2_eth_dev, i,
286                                              queue_conf->ev.sched_type,
287                                              queue_conf->ev.queue_id, port);
288                 }
289                 rxq = eth_dev->data->rx_queues[0];
290                 sso_updt_lookup_mem(event_dev, rxq->lookup_mem);
291         } else {
292                 rxq = eth_dev->data->rx_queues[rx_queue_id];
293                 sso_updt_xae_cnt(dev, rxq, RTE_EVENT_TYPE_ETHDEV);
294                 rc = sso_xae_reconfigure((struct rte_eventdev *)
295                                          (uintptr_t)event_dev);
296                 rc |= sso_rxq_enable(otx2_eth_dev, (uint16_t)rx_queue_id,
297                                      queue_conf->ev.sched_type,
298                                      queue_conf->ev.queue_id, port);
299                 sso_updt_lookup_mem(event_dev, rxq->lookup_mem);
300         }
301
302         if (rc < 0) {
303                 otx2_err("Failed to configure Rx adapter port=%d, q=%d", port,
304                          queue_conf->ev.queue_id);
305                 return rc;
306         }
307
308         dev->rx_offloads |= otx2_eth_dev->rx_offload_flags;
309         dev->tstamp = &otx2_eth_dev->tstamp;
310         sso_fastpath_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
311
312         return 0;
313 }
314
315 int
316 otx2_sso_rx_adapter_queue_del(const struct rte_eventdev *event_dev,
317                               const struct rte_eth_dev *eth_dev,
318                               int32_t rx_queue_id)
319 {
320         struct otx2_eth_dev *dev = eth_dev->data->dev_private;
321         int i, rc;
322
323         RTE_SET_USED(event_dev);
324         rc = strncmp(eth_dev->device->driver->name, "net_octeontx2", 13);
325         if (rc)
326                 return -EINVAL;
327
328         if (rx_queue_id < 0) {
329                 for (i = 0 ; i < eth_dev->data->nb_rx_queues; i++)
330                         rc = sso_rxq_disable(dev, i);
331         } else {
332                 rc = sso_rxq_disable(dev, (uint16_t)rx_queue_id);
333         }
334
335         if (rc < 0)
336                 otx2_err("Failed to clear Rx adapter config port=%d, q=%d",
337                          eth_dev->data->port_id, rx_queue_id);
338
339         return rc;
340 }
341
342 int
343 otx2_sso_rx_adapter_start(const struct rte_eventdev *event_dev,
344                           const struct rte_eth_dev *eth_dev)
345 {
346         RTE_SET_USED(event_dev);
347         RTE_SET_USED(eth_dev);
348
349         return 0;
350 }
351
352 int
353 otx2_sso_rx_adapter_stop(const struct rte_eventdev *event_dev,
354                          const struct rte_eth_dev *eth_dev)
355 {
356         RTE_SET_USED(event_dev);
357         RTE_SET_USED(eth_dev);
358
359         return 0;
360 }
361
362 int
363 otx2_sso_tx_adapter_caps_get(const struct rte_eventdev *dev,
364                              const struct rte_eth_dev *eth_dev, uint32_t *caps)
365 {
366         int ret;
367
368         RTE_SET_USED(dev);
369         ret = strncmp(eth_dev->device->driver->name, "net_octeontx2,", 13);
370         if (ret)
371                 *caps = 0;
372         else
373                 *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT;
374
375         return 0;
376 }
377
378 static int
379 sso_sqb_aura_limit_edit(struct rte_mempool *mp, uint16_t nb_sqb_bufs)
380 {
381         struct otx2_npa_lf *npa_lf = otx2_intra_dev_get_cfg()->npa_lf;
382         struct npa_aq_enq_req *aura_req;
383
384         aura_req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
385         aura_req->aura_id = npa_lf_aura_handle_to_aura(mp->pool_id);
386         aura_req->ctype = NPA_AQ_CTYPE_AURA;
387         aura_req->op = NPA_AQ_INSTOP_WRITE;
388
389         aura_req->aura.limit = nb_sqb_bufs;
390         aura_req->aura_mask.limit = ~(aura_req->aura_mask.limit);
391
392         return otx2_mbox_process(npa_lf->mbox);
393 }
394
395 int
396 otx2_sso_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *event_dev,
397                               const struct rte_eth_dev *eth_dev,
398                               int32_t tx_queue_id)
399 {
400         struct otx2_eth_dev *otx2_eth_dev = eth_dev->data->dev_private;
401         struct otx2_sso_evdev *dev = sso_pmd_priv(event_dev);
402         struct otx2_eth_txq *txq;
403         int i;
404
405         RTE_SET_USED(id);
406         if (tx_queue_id < 0) {
407                 for (i = 0 ; i < eth_dev->data->nb_tx_queues; i++) {
408                         txq = eth_dev->data->tx_queues[i];
409                         sso_sqb_aura_limit_edit(txq->sqb_pool,
410                                                 OTX2_SSO_SQB_LIMIT);
411                 }
412         } else {
413                 txq = eth_dev->data->tx_queues[tx_queue_id];
414                 sso_sqb_aura_limit_edit(txq->sqb_pool, OTX2_SSO_SQB_LIMIT);
415         }
416
417         dev->tx_offloads |= otx2_eth_dev->tx_offload_flags;
418         sso_fastpath_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
419
420         return 0;
421 }
422
423 int
424 otx2_sso_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *event_dev,
425                               const struct rte_eth_dev *eth_dev,
426                               int32_t tx_queue_id)
427 {
428         struct otx2_eth_txq *txq;
429         int i;
430
431         RTE_SET_USED(id);
432         RTE_SET_USED(eth_dev);
433         RTE_SET_USED(event_dev);
434         if (tx_queue_id < 0) {
435                 for (i = 0 ; i < eth_dev->data->nb_tx_queues; i++) {
436                         txq = eth_dev->data->tx_queues[i];
437                         sso_sqb_aura_limit_edit(txq->sqb_pool,
438                                                 txq->nb_sqb_bufs);
439                 }
440         } else {
441                 txq = eth_dev->data->tx_queues[tx_queue_id];
442                 sso_sqb_aura_limit_edit(txq->sqb_pool, txq->nb_sqb_bufs);
443         }
444
445         return 0;
446 }