net/atlantic: add link status and interrupt management
[dpdk.git] / drivers / net / atlantic / atl_rxtx.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Aquantia Corporation
3  */
4
5 #include <rte_malloc.h>
6 #include <rte_ethdev_driver.h>
7 #include <rte_net.h>
8
9 #include "atl_ethdev.h"
10 #include "atl_hw_regs.h"
11
12 #include "atl_logs.h"
13 #include "hw_atl/hw_atl_llh.h"
14 #include "hw_atl/hw_atl_b0.h"
15 #include "hw_atl/hw_atl_b0_internal.h"
16
17 #define ATL_TX_CKSUM_OFFLOAD_MASK (                      \
18         PKT_TX_IP_CKSUM |                                \
19         PKT_TX_L4_MASK |                                 \
20         PKT_TX_TCP_SEG)
21
22 #define ATL_TX_OFFLOAD_MASK (                            \
23         PKT_TX_VLAN |                                    \
24         PKT_TX_IP_CKSUM |                                \
25         PKT_TX_L4_MASK |                                 \
26         PKT_TX_TCP_SEG)
27
28 #define ATL_TX_OFFLOAD_NOTSUP_MASK \
29         (PKT_TX_OFFLOAD_MASK ^ ATL_TX_OFFLOAD_MASK)
30
31 /**
32  * Structure associated with each descriptor of the RX ring of a RX queue.
33  */
34 struct atl_rx_entry {
35         struct rte_mbuf *mbuf;
36 };
37
38 /**
39  * Structure associated with each descriptor of the TX ring of a TX queue.
40  */
41 struct atl_tx_entry {
42         struct rte_mbuf *mbuf;
43         uint16_t next_id;
44         uint16_t last_id;
45 };
46
47 /**
48  * Structure associated with each RX queue.
49  */
50 struct atl_rx_queue {
51         struct rte_mempool      *mb_pool;
52         struct hw_atl_rxd_s     *hw_ring;
53         uint64_t                hw_ring_phys_addr;
54         struct atl_rx_entry     *sw_ring;
55         uint16_t                nb_rx_desc;
56         uint16_t                rx_tail;
57         uint16_t                nb_rx_hold;
58         uint16_t                rx_free_thresh;
59         uint16_t                queue_id;
60         uint16_t                port_id;
61         uint16_t                buff_size;
62         bool                    l3_csum_enabled;
63         bool                    l4_csum_enabled;
64 };
65
66 /**
67  * Structure associated with each TX queue.
68  */
69 struct atl_tx_queue {
70         struct hw_atl_txd_s     *hw_ring;
71         uint64_t                hw_ring_phys_addr;
72         struct atl_tx_entry     *sw_ring;
73         uint16_t                nb_tx_desc;
74         uint16_t                tx_tail;
75         uint16_t                tx_head;
76         uint16_t                queue_id;
77         uint16_t                port_id;
78         uint16_t                tx_free_thresh;
79         uint16_t                tx_free;
80 };
81
82 static inline void
83 atl_reset_rx_queue(struct atl_rx_queue *rxq)
84 {
85         struct hw_atl_rxd_s *rxd = NULL;
86         int i;
87
88         PMD_INIT_FUNC_TRACE();
89
90         for (i = 0; i < rxq->nb_rx_desc; i++) {
91                 rxd = (struct hw_atl_rxd_s *)&rxq->hw_ring[i];
92                 rxd->buf_addr = 0;
93                 rxd->hdr_addr = 0;
94         }
95
96         rxq->rx_tail = 0;
97 }
98
99 int
100 atl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
101                    uint16_t nb_rx_desc, unsigned int socket_id,
102                    const struct rte_eth_rxconf *rx_conf,
103                    struct rte_mempool *mb_pool)
104 {
105         struct atl_rx_queue *rxq;
106         const struct rte_memzone *mz;
107
108         PMD_INIT_FUNC_TRACE();
109
110         /* make sure a valid number of descriptors have been requested */
111         if (nb_rx_desc < AQ_HW_MIN_RX_RING_SIZE ||
112                         nb_rx_desc > AQ_HW_MAX_RX_RING_SIZE) {
113                 PMD_INIT_LOG(ERR, "Number of Rx descriptors must be "
114                 "less than or equal to %d, "
115                 "greater than or equal to %d", AQ_HW_MAX_RX_RING_SIZE,
116                 AQ_HW_MIN_RX_RING_SIZE);
117                 return -EINVAL;
118         }
119
120         /*
121          * if this queue existed already, free the associated memory. The
122          * queue cannot be reused in case we need to allocate memory on
123          * different socket than was previously used.
124          */
125         if (dev->data->rx_queues[rx_queue_id] != NULL) {
126                 atl_rx_queue_release(dev->data->rx_queues[rx_queue_id]);
127                 dev->data->rx_queues[rx_queue_id] = NULL;
128         }
129
130         /* allocate memory for the queue structure */
131         rxq = rte_zmalloc_socket("atlantic Rx queue", sizeof(*rxq),
132                                  RTE_CACHE_LINE_SIZE, socket_id);
133         if (rxq == NULL) {
134                 PMD_INIT_LOG(ERR, "Cannot allocate queue structure");
135                 return -ENOMEM;
136         }
137
138         /* setup queue */
139         rxq->mb_pool = mb_pool;
140         rxq->nb_rx_desc = nb_rx_desc;
141         rxq->port_id = dev->data->port_id;
142         rxq->queue_id = rx_queue_id;
143         rxq->rx_free_thresh = rx_conf->rx_free_thresh;
144
145         rxq->l3_csum_enabled = dev->data->dev_conf.rxmode.offloads &
146                 DEV_RX_OFFLOAD_IPV4_CKSUM;
147         rxq->l4_csum_enabled = dev->data->dev_conf.rxmode.offloads &
148                 (DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM);
149         if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC)
150                 PMD_DRV_LOG(ERR, "PMD does not support KEEP_CRC offload");
151
152         /* allocate memory for the software ring */
153         rxq->sw_ring = rte_zmalloc_socket("atlantic sw rx ring",
154                                 nb_rx_desc * sizeof(struct atl_rx_entry),
155                                 RTE_CACHE_LINE_SIZE, socket_id);
156         if (rxq->sw_ring == NULL) {
157                 PMD_INIT_LOG(ERR,
158                         "Port %d: Cannot allocate software ring for queue %d",
159                         rxq->port_id, rxq->queue_id);
160                 rte_free(rxq);
161                 return -ENOMEM;
162         }
163
164         /*
165          * allocate memory for the hardware descriptor ring. A memzone large
166          * enough to hold the maximum ring size is requested to allow for
167          * resizing in later calls to the queue setup function.
168          */
169         mz = rte_eth_dma_zone_reserve(dev, "rx hw_ring", rx_queue_id,
170                                       HW_ATL_B0_MAX_RXD *
171                                         sizeof(struct hw_atl_rxd_s),
172                                       128, socket_id);
173         if (mz == NULL) {
174                 PMD_INIT_LOG(ERR,
175                         "Port %d: Cannot allocate hardware ring for queue %d",
176                         rxq->port_id, rxq->queue_id);
177                 rte_free(rxq->sw_ring);
178                 rte_free(rxq);
179                 return -ENOMEM;
180         }
181         rxq->hw_ring = mz->addr;
182         rxq->hw_ring_phys_addr = mz->iova;
183
184         atl_reset_rx_queue(rxq);
185
186         dev->data->rx_queues[rx_queue_id] = rxq;
187         return 0;
188 }
189
190 static inline void
191 atl_reset_tx_queue(struct atl_tx_queue *txq)
192 {
193         struct atl_tx_entry *tx_entry;
194         union hw_atl_txc_s *txc;
195         uint16_t i;
196
197         PMD_INIT_FUNC_TRACE();
198
199         if (!txq) {
200                 PMD_DRV_LOG(ERR, "Pointer to txq is NULL");
201                 return;
202         }
203
204         tx_entry = txq->sw_ring;
205
206         for (i = 0; i < txq->nb_tx_desc; i++) {
207                 txc = (union hw_atl_txc_s *)&txq->hw_ring[i];
208                 txc->flags1 = 0;
209                 txc->flags2 = 2;
210         }
211
212         for (i = 0; i < txq->nb_tx_desc; i++) {
213                 txq->hw_ring[i].dd = 1;
214                 tx_entry[i].mbuf = NULL;
215         }
216
217         txq->tx_tail = 0;
218         txq->tx_head = 0;
219         txq->tx_free = txq->nb_tx_desc - 1;
220 }
221
222 int
223 atl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
224                    uint16_t nb_tx_desc, unsigned int socket_id,
225                    const struct rte_eth_txconf *tx_conf)
226 {
227         struct atl_tx_queue *txq;
228         const struct rte_memzone *mz;
229
230         PMD_INIT_FUNC_TRACE();
231
232         /* make sure a valid number of descriptors have been requested */
233         if (nb_tx_desc < AQ_HW_MIN_TX_RING_SIZE ||
234                 nb_tx_desc > AQ_HW_MAX_TX_RING_SIZE) {
235                 PMD_INIT_LOG(ERR, "Number of Tx descriptors must be "
236                         "less than or equal to %d, "
237                         "greater than or equal to %d", AQ_HW_MAX_TX_RING_SIZE,
238                         AQ_HW_MIN_TX_RING_SIZE);
239                 return -EINVAL;
240         }
241
242         /*
243          * if this queue existed already, free the associated memory. The
244          * queue cannot be reused in case we need to allocate memory on
245          * different socket than was previously used.
246          */
247         if (dev->data->tx_queues[tx_queue_id] != NULL) {
248                 atl_tx_queue_release(dev->data->tx_queues[tx_queue_id]);
249                 dev->data->tx_queues[tx_queue_id] = NULL;
250         }
251
252         /* allocate memory for the queue structure */
253         txq = rte_zmalloc_socket("atlantic Tx queue", sizeof(*txq),
254                                  RTE_CACHE_LINE_SIZE, socket_id);
255         if (txq == NULL) {
256                 PMD_INIT_LOG(ERR, "Cannot allocate queue structure");
257                 return -ENOMEM;
258         }
259
260         /* setup queue */
261         txq->nb_tx_desc = nb_tx_desc;
262         txq->port_id = dev->data->port_id;
263         txq->queue_id = tx_queue_id;
264         txq->tx_free_thresh = tx_conf->tx_free_thresh;
265
266
267         /* allocate memory for the software ring */
268         txq->sw_ring = rte_zmalloc_socket("atlantic sw tx ring",
269                                 nb_tx_desc * sizeof(struct atl_tx_entry),
270                                 RTE_CACHE_LINE_SIZE, socket_id);
271         if (txq->sw_ring == NULL) {
272                 PMD_INIT_LOG(ERR,
273                         "Port %d: Cannot allocate software ring for queue %d",
274                         txq->port_id, txq->queue_id);
275                 rte_free(txq);
276                 return -ENOMEM;
277         }
278
279         /*
280          * allocate memory for the hardware descriptor ring. A memzone large
281          * enough to hold the maximum ring size is requested to allow for
282          * resizing in later calls to the queue setup function.
283          */
284         mz = rte_eth_dma_zone_reserve(dev, "tx hw_ring", tx_queue_id,
285                                 HW_ATL_B0_MAX_TXD * sizeof(struct hw_atl_txd_s),
286                                 128, socket_id);
287         if (mz == NULL) {
288                 PMD_INIT_LOG(ERR,
289                         "Port %d: Cannot allocate hardware ring for queue %d",
290                         txq->port_id, txq->queue_id);
291                 rte_free(txq->sw_ring);
292                 rte_free(txq);
293                 return -ENOMEM;
294         }
295         txq->hw_ring = mz->addr;
296         txq->hw_ring_phys_addr = mz->iova;
297
298         atl_reset_tx_queue(txq);
299
300         dev->data->tx_queues[tx_queue_id] = txq;
301         return 0;
302 }
303
304 int
305 atl_tx_init(struct rte_eth_dev *eth_dev)
306 {
307         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
308         struct atl_tx_queue *txq;
309         uint64_t base_addr = 0;
310         int i = 0;
311         int err = 0;
312
313         PMD_INIT_FUNC_TRACE();
314
315         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
316                 txq = eth_dev->data->tx_queues[i];
317                 base_addr = txq->hw_ring_phys_addr;
318
319                 err = hw_atl_b0_hw_ring_tx_init(hw, base_addr,
320                                                 txq->queue_id,
321                                                 txq->nb_tx_desc, 0,
322                                                 txq->port_id);
323
324                 if (err) {
325                         PMD_INIT_LOG(ERR,
326                                 "Port %d: Cannot init TX queue %d",
327                                 txq->port_id, txq->queue_id);
328                         break;
329                 }
330         }
331
332         return err;
333 }
334
335 int
336 atl_rx_init(struct rte_eth_dev *eth_dev)
337 {
338         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
339         struct atl_rx_queue *rxq;
340         uint64_t base_addr = 0;
341         int i = 0;
342         int err = 0;
343
344         PMD_INIT_FUNC_TRACE();
345
346         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
347                 rxq = eth_dev->data->rx_queues[i];
348                 base_addr = rxq->hw_ring_phys_addr;
349
350                 /* Take requested pool mbuf size and adapt
351                  * descriptor buffer to best fit
352                  */
353                 int buff_size = rte_pktmbuf_data_room_size(rxq->mb_pool) -
354                                 RTE_PKTMBUF_HEADROOM;
355
356                 buff_size = RTE_ALIGN_FLOOR(buff_size, 1024);
357                 if (buff_size > HW_ATL_B0_RXD_BUF_SIZE_MAX) {
358                         PMD_INIT_LOG(WARNING,
359                                 "Port %d queue %d: mem pool buff size is too big\n",
360                                 rxq->port_id, rxq->queue_id);
361                         buff_size = HW_ATL_B0_RXD_BUF_SIZE_MAX;
362                 }
363                 if (buff_size < 1024) {
364                         PMD_INIT_LOG(ERR,
365                                 "Port %d queue %d: mem pool buff size is too small\n",
366                                 rxq->port_id, rxq->queue_id);
367                         return -EINVAL;
368                 }
369                 rxq->buff_size = buff_size;
370
371                 err = hw_atl_b0_hw_ring_rx_init(hw, base_addr, rxq->queue_id,
372                                                 rxq->nb_rx_desc, buff_size, 0,
373                                                 rxq->port_id);
374
375                 if (err) {
376                         PMD_INIT_LOG(ERR, "Port %d: Cannot init RX queue %d",
377                                      rxq->port_id, rxq->queue_id);
378                         break;
379                 }
380         }
381
382         return err;
383 }
384
385 static int
386 atl_alloc_rx_queue_mbufs(struct atl_rx_queue *rxq)
387 {
388         struct atl_rx_entry *rx_entry = rxq->sw_ring;
389         struct hw_atl_rxd_s *rxd;
390         uint64_t dma_addr = 0;
391         uint32_t i = 0;
392
393         PMD_INIT_FUNC_TRACE();
394
395         /* fill Rx ring */
396         for (i = 0; i < rxq->nb_rx_desc; i++) {
397                 struct rte_mbuf *mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
398
399                 if (mbuf == NULL) {
400                         PMD_INIT_LOG(ERR,
401                                 "Port %d: mbuf alloc failed for rx queue %d",
402                                 rxq->port_id, rxq->queue_id);
403                         return -ENOMEM;
404                 }
405
406                 mbuf->data_off = RTE_PKTMBUF_HEADROOM;
407                 mbuf->port = rxq->port_id;
408
409                 dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
410                 rxd = (struct hw_atl_rxd_s *)&rxq->hw_ring[i];
411                 rxd->buf_addr = dma_addr;
412                 rxd->hdr_addr = 0;
413                 rx_entry[i].mbuf = mbuf;
414         }
415
416         return 0;
417 }
418
419 static void
420 atl_rx_queue_release_mbufs(struct atl_rx_queue *rxq)
421 {
422         int i;
423
424         PMD_INIT_FUNC_TRACE();
425
426         if (rxq->sw_ring != NULL) {
427                 for (i = 0; i < rxq->nb_rx_desc; i++) {
428                         if (rxq->sw_ring[i].mbuf != NULL) {
429                                 rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
430                                 rxq->sw_ring[i].mbuf = NULL;
431                         }
432                 }
433         }
434 }
435
436 int
437 atl_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
438 {
439         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
440         struct atl_rx_queue *rxq = NULL;
441
442         PMD_INIT_FUNC_TRACE();
443
444         if (rx_queue_id < dev->data->nb_rx_queues) {
445                 rxq = dev->data->rx_queues[rx_queue_id];
446
447                 if (atl_alloc_rx_queue_mbufs(rxq) != 0) {
448                         PMD_INIT_LOG(ERR,
449                                 "Port %d: Allocate mbufs for queue %d failed",
450                                 rxq->port_id, rxq->queue_id);
451                         return -1;
452                 }
453
454                 hw_atl_b0_hw_ring_rx_start(hw, rx_queue_id);
455
456                 rte_wmb();
457                 hw_atl_reg_rx_dma_desc_tail_ptr_set(hw, rxq->nb_rx_desc - 1,
458                                                     rx_queue_id);
459                 dev->data->rx_queue_state[rx_queue_id] =
460                         RTE_ETH_QUEUE_STATE_STARTED;
461         } else {
462                 return -1;
463         }
464
465         return 0;
466 }
467
468 int
469 atl_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
470 {
471         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
472         struct atl_rx_queue *rxq = NULL;
473
474         PMD_INIT_FUNC_TRACE();
475
476         if (rx_queue_id < dev->data->nb_rx_queues) {
477                 rxq = dev->data->rx_queues[rx_queue_id];
478
479                 hw_atl_b0_hw_ring_rx_stop(hw, rx_queue_id);
480
481                 atl_rx_queue_release_mbufs(rxq);
482                 atl_reset_rx_queue(rxq);
483
484                 dev->data->rx_queue_state[rx_queue_id] =
485                         RTE_ETH_QUEUE_STATE_STOPPED;
486         } else {
487                 return -1;
488         }
489
490         return 0;
491 }
492
493 void
494 atl_rx_queue_release(void *rx_queue)
495 {
496         PMD_INIT_FUNC_TRACE();
497
498         if (rx_queue != NULL) {
499                 struct atl_rx_queue *rxq = (struct atl_rx_queue *)rx_queue;
500
501                 atl_rx_queue_release_mbufs(rxq);
502                 rte_free(rxq->sw_ring);
503                 rte_free(rxq);
504         }
505 }
506
507 static void
508 atl_tx_queue_release_mbufs(struct atl_tx_queue *txq)
509 {
510         int i;
511
512         PMD_INIT_FUNC_TRACE();
513
514         if (txq->sw_ring != NULL) {
515                 for (i = 0; i < txq->nb_tx_desc; i++) {
516                         if (txq->sw_ring[i].mbuf != NULL) {
517                                 rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
518                                 txq->sw_ring[i].mbuf = NULL;
519                         }
520                 }
521         }
522 }
523
524 int
525 atl_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
526 {
527         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
528
529         PMD_INIT_FUNC_TRACE();
530
531         if (tx_queue_id < dev->data->nb_tx_queues) {
532                 hw_atl_b0_hw_ring_tx_start(hw, tx_queue_id);
533
534                 rte_wmb();
535                 hw_atl_b0_hw_tx_ring_tail_update(hw, 0, tx_queue_id);
536                 dev->data->tx_queue_state[tx_queue_id] =
537                         RTE_ETH_QUEUE_STATE_STARTED;
538         } else {
539                 return -1;
540         }
541
542         return 0;
543 }
544
545 int
546 atl_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
547 {
548         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
549         struct atl_tx_queue *txq;
550
551         PMD_INIT_FUNC_TRACE();
552
553         txq = dev->data->tx_queues[tx_queue_id];
554
555         hw_atl_b0_hw_ring_tx_stop(hw, tx_queue_id);
556
557         atl_tx_queue_release_mbufs(txq);
558         atl_reset_tx_queue(txq);
559         dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
560
561         return 0;
562 }
563
564 void
565 atl_tx_queue_release(void *tx_queue)
566 {
567         PMD_INIT_FUNC_TRACE();
568
569         if (tx_queue != NULL) {
570                 struct atl_tx_queue *txq = (struct atl_tx_queue *)tx_queue;
571
572                 atl_tx_queue_release_mbufs(txq);
573                 rte_free(txq->sw_ring);
574                 rte_free(txq);
575         }
576 }
577
578 void
579 atl_free_queues(struct rte_eth_dev *dev)
580 {
581         unsigned int i;
582
583         PMD_INIT_FUNC_TRACE();
584
585         for (i = 0; i < dev->data->nb_rx_queues; i++) {
586                 atl_rx_queue_release(dev->data->rx_queues[i]);
587                 dev->data->rx_queues[i] = 0;
588         }
589         dev->data->nb_rx_queues = 0;
590
591         for (i = 0; i < dev->data->nb_tx_queues; i++) {
592                 atl_tx_queue_release(dev->data->tx_queues[i]);
593                 dev->data->tx_queues[i] = 0;
594         }
595         dev->data->nb_tx_queues = 0;
596 }
597
598 int
599 atl_start_queues(struct rte_eth_dev *dev)
600 {
601         int i;
602
603         PMD_INIT_FUNC_TRACE();
604
605         for (i = 0; i < dev->data->nb_tx_queues; i++) {
606                 if (atl_tx_queue_start(dev, i) != 0) {
607                         PMD_DRV_LOG(ERR,
608                                 "Port %d: Start Tx queue %d failed",
609                                 dev->data->port_id, i);
610                         return -1;
611                 }
612         }
613
614         for (i = 0; i < dev->data->nb_rx_queues; i++) {
615                 if (atl_rx_queue_start(dev, i) != 0) {
616                         PMD_DRV_LOG(ERR,
617                                 "Port %d: Start Rx queue %d failed",
618                                 dev->data->port_id, i);
619                         return -1;
620                 }
621         }
622
623         return 0;
624 }
625
626 int
627 atl_stop_queues(struct rte_eth_dev *dev)
628 {
629         int i;
630
631         PMD_INIT_FUNC_TRACE();
632
633         for (i = 0; i < dev->data->nb_tx_queues; i++) {
634                 if (atl_tx_queue_stop(dev, i) != 0) {
635                         PMD_DRV_LOG(ERR,
636                                 "Port %d: Stop Tx queue %d failed",
637                                 dev->data->port_id, i);
638                         return -1;
639                 }
640         }
641
642         for (i = 0; i < dev->data->nb_rx_queues; i++) {
643                 if (atl_rx_queue_stop(dev, i) != 0) {
644                         PMD_DRV_LOG(ERR,
645                                 "Port %d: Stop Rx queue %d failed",
646                                 dev->data->port_id, i);
647                         return -1;
648                 }
649         }
650
651         return 0;
652 }
653
654 static int
655 atl_rx_enable_intr(struct rte_eth_dev *dev, uint16_t queue_id, bool enable)
656 {
657         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
658         struct atl_rx_queue *rxq;
659
660         PMD_INIT_FUNC_TRACE();
661
662         if (queue_id >= dev->data->nb_rx_queues) {
663                 PMD_DRV_LOG(ERR, "Invalid RX queue id=%d", queue_id);
664                 return -EINVAL;
665         }
666
667         rxq = dev->data->rx_queues[queue_id];
668
669         if (rxq == NULL)
670                 return 0;
671
672         /* Mapping interrupt vector */
673         hw_atl_itr_irq_map_en_rx_set(hw, enable, queue_id);
674
675         return 0;
676 }
677
678 int
679 atl_dev_rx_queue_intr_enable(struct rte_eth_dev *eth_dev, uint16_t queue_id)
680 {
681         return atl_rx_enable_intr(eth_dev, queue_id, true);
682 }
683
684 int
685 atl_dev_rx_queue_intr_disable(struct rte_eth_dev *eth_dev, uint16_t queue_id)
686 {
687         return atl_rx_enable_intr(eth_dev, queue_id, false);
688 }
689
690 uint16_t
691 atl_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
692               uint16_t nb_pkts)
693 {
694         int i, ret;
695         uint64_t ol_flags;
696         struct rte_mbuf *m;
697
698         PMD_INIT_FUNC_TRACE();
699
700         for (i = 0; i < nb_pkts; i++) {
701                 m = tx_pkts[i];
702                 ol_flags = m->ol_flags;
703
704                 if (m->nb_segs > AQ_HW_MAX_SEGS_SIZE) {
705                         rte_errno = -EINVAL;
706                         return i;
707                 }
708
709                 if (ol_flags & ATL_TX_OFFLOAD_NOTSUP_MASK) {
710                         rte_errno = -ENOTSUP;
711                         return i;
712                 }
713
714 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
715                 ret = rte_validate_tx_offload(m);
716                 if (ret != 0) {
717                         rte_errno = ret;
718                         return i;
719                 }
720 #endif
721                 ret = rte_net_intel_cksum_prepare(m);
722                 if (ret != 0) {
723                         rte_errno = ret;
724                         return i;
725                 }
726         }
727
728         return i;
729 }
730
731 static uint64_t
732 atl_desc_to_offload_flags(struct atl_rx_queue *rxq,
733                           struct hw_atl_rxd_wb_s *rxd_wb)
734 {
735         uint64_t mbuf_flags = 0;
736
737         PMD_INIT_FUNC_TRACE();
738
739         /* IPv4 ? */
740         if (rxq->l3_csum_enabled && ((rxd_wb->pkt_type & 0x3) == 0)) {
741                 /* IPv4 csum error ? */
742                 if (rxd_wb->rx_stat & BIT(1))
743                         mbuf_flags |= PKT_RX_IP_CKSUM_BAD;
744                 else
745                         mbuf_flags |= PKT_RX_IP_CKSUM_GOOD;
746         } else {
747                 mbuf_flags |= PKT_RX_IP_CKSUM_UNKNOWN;
748         }
749
750         /* CSUM calculated ? */
751         if (rxq->l4_csum_enabled && (rxd_wb->rx_stat & BIT(3))) {
752                 if (rxd_wb->rx_stat & BIT(2))
753                         mbuf_flags |= PKT_RX_L4_CKSUM_BAD;
754                 else
755                         mbuf_flags |= PKT_RX_L4_CKSUM_GOOD;
756         } else {
757                 mbuf_flags |= PKT_RX_L4_CKSUM_UNKNOWN;
758         }
759
760         return mbuf_flags;
761 }
762
763 static uint32_t
764 atl_desc_to_pkt_type(struct hw_atl_rxd_wb_s *rxd_wb)
765 {
766         uint32_t type = RTE_PTYPE_UNKNOWN;
767         uint16_t l2_l3_type = rxd_wb->pkt_type & 0x3;
768         uint16_t l4_type = (rxd_wb->pkt_type & 0x1C) >> 2;
769
770         switch (l2_l3_type) {
771         case 0:
772                 type = RTE_PTYPE_L3_IPV4;
773                 break;
774         case 1:
775                 type = RTE_PTYPE_L3_IPV6;
776                 break;
777         case 2:
778                 type = RTE_PTYPE_L2_ETHER;
779                 break;
780         case 3:
781                 type = RTE_PTYPE_L2_ETHER_ARP;
782                 break;
783         }
784
785         switch (l4_type) {
786         case 0:
787                 type |= RTE_PTYPE_L4_TCP;
788                 break;
789         case 1:
790                 type |= RTE_PTYPE_L4_UDP;
791                 break;
792         case 2:
793                 type |= RTE_PTYPE_L4_SCTP;
794                 break;
795         case 3:
796                 type |= RTE_PTYPE_L4_ICMP;
797                 break;
798         }
799
800         if (rxd_wb->pkt_type & BIT(5))
801                 type |= RTE_PTYPE_L2_ETHER_VLAN;
802
803         return type;
804 }
805
806 uint16_t
807 atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
808 {
809         struct atl_rx_queue *rxq = (struct atl_rx_queue *)rx_queue;
810         struct rte_eth_dev *dev = &rte_eth_devices[rxq->port_id];
811         struct atl_adapter *adapter =
812                 ATL_DEV_TO_ADAPTER(&rte_eth_devices[rxq->port_id]);
813         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(adapter);
814         struct atl_rx_entry *sw_ring = rxq->sw_ring;
815
816         struct rte_mbuf *new_mbuf;
817         struct rte_mbuf *rx_mbuf, *rx_mbuf_prev, *rx_mbuf_first;
818         struct atl_rx_entry *rx_entry;
819         uint16_t nb_rx = 0;
820         uint16_t nb_hold = 0;
821         struct hw_atl_rxd_wb_s rxd_wb;
822         struct hw_atl_rxd_s *rxd = NULL;
823         uint16_t tail = rxq->rx_tail;
824         uint64_t dma_addr;
825         uint16_t pkt_len = 0;
826
827         while (nb_rx < nb_pkts) {
828                 uint16_t eop_tail = tail;
829
830                 rxd = (struct hw_atl_rxd_s *)&rxq->hw_ring[tail];
831                 rxd_wb = *(struct hw_atl_rxd_wb_s *)rxd;
832
833                 if (!rxd_wb.dd) { /* RxD is not done */
834                         break;
835                 }
836
837                 PMD_RX_LOG(ERR, "port_id=%u queue_id=%u tail=%u "
838                            "eop=0x%x pkt_len=%u hash=0x%x hash_type=0x%x",
839                            (unsigned int)rxq->port_id,
840                            (unsigned int)rxq->queue_id,
841                            (unsigned int)tail, (unsigned int)rxd_wb.eop,
842                            (unsigned int)rte_le_to_cpu_16(rxd_wb.pkt_len),
843                         rxd_wb.rss_hash, rxd_wb.rss_type);
844
845                 /* RxD is not done */
846                 if (!rxd_wb.eop) {
847                         while (true) {
848                                 struct hw_atl_rxd_wb_s *eop_rxwbd;
849
850                                 eop_tail = (eop_tail + 1) % rxq->nb_rx_desc;
851                                 eop_rxwbd = (struct hw_atl_rxd_wb_s *)
852                                         &rxq->hw_ring[eop_tail];
853                                 if (!eop_rxwbd->dd) {
854                                         /* no EOP received yet */
855                                         eop_tail = tail;
856                                         break;
857                                 }
858                                 if (eop_rxwbd->dd && eop_rxwbd->eop)
859                                         break;
860                         }
861                         /* No EOP in ring */
862                         if (eop_tail == tail)
863                                 break;
864                 }
865                 rx_mbuf_prev = NULL;
866                 rx_mbuf_first = NULL;
867
868                 /* Run through packet segments */
869                 while (true) {
870                         new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
871                         if (new_mbuf == NULL) {
872                                 PMD_RX_LOG(ERR,
873                                    "RX mbuf alloc failed port_id=%u "
874                                    "queue_id=%u", (unsigned int)rxq->port_id,
875                                    (unsigned int)rxq->queue_id);
876                                 dev->data->rx_mbuf_alloc_failed++;
877                                                 goto err_stop;
878                         }
879
880                         nb_hold++;
881                         rx_entry = &sw_ring[tail];
882
883                         rx_mbuf = rx_entry->mbuf;
884                         rx_entry->mbuf = new_mbuf;
885                         dma_addr = rte_cpu_to_le_64(
886                                 rte_mbuf_data_iova_default(new_mbuf));
887
888                         /* setup RX descriptor */
889                         rxd->hdr_addr = 0;
890                         rxd->buf_addr = dma_addr;
891
892                         /*
893                          * Initialize the returned mbuf.
894                          * 1) setup generic mbuf fields:
895                          *        - number of segments,
896                          *        - next segment,
897                          *        - packet length,
898                          *        - RX port identifier.
899                          * 2) integrate hardware offload data, if any:
900                          *      <  - RSS flag & hash,
901                          *        - IP checksum flag,
902                          *        - VLAN TCI, if any,
903                          *        - error flags.
904                          */
905                         pkt_len = (uint16_t)rte_le_to_cpu_16(rxd_wb.pkt_len);
906                         rx_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
907                         rte_prefetch1((char *)rx_mbuf->buf_addr +
908                                 rx_mbuf->data_off);
909                         rx_mbuf->nb_segs = 0;
910                         rx_mbuf->next = NULL;
911                         rx_mbuf->pkt_len = pkt_len;
912                         rx_mbuf->data_len = pkt_len;
913                         if (rxd_wb.eop) {
914                                 u16 remainder_len = pkt_len % rxq->buff_size;
915                                 if (!remainder_len)
916                                         remainder_len = rxq->buff_size;
917                                 rx_mbuf->data_len = remainder_len;
918                         } else {
919                                 rx_mbuf->data_len = pkt_len > rxq->buff_size ?
920                                                 rxq->buff_size : pkt_len;
921                         }
922                         rx_mbuf->port = rxq->port_id;
923
924                         rx_mbuf->hash.rss = rxd_wb.rss_hash;
925
926                         rx_mbuf->vlan_tci = rxd_wb.vlan;
927
928                         rx_mbuf->ol_flags =
929                                 atl_desc_to_offload_flags(rxq, &rxd_wb);
930                         rx_mbuf->packet_type = atl_desc_to_pkt_type(&rxd_wb);
931
932                         if (!rx_mbuf_first)
933                                 rx_mbuf_first = rx_mbuf;
934                         rx_mbuf_first->nb_segs++;
935
936                         if (rx_mbuf_prev)
937                                 rx_mbuf_prev->next = rx_mbuf;
938                         rx_mbuf_prev = rx_mbuf;
939
940                         tail = (tail + 1) % rxq->nb_rx_desc;
941                         /* Prefetch next mbufs */
942                         rte_prefetch0(sw_ring[tail].mbuf);
943                         if ((tail & 0x3) == 0) {
944                                 rte_prefetch0(&sw_ring[tail]);
945                                 rte_prefetch0(&sw_ring[tail]);
946                         }
947
948                         /* filled mbuf_first */
949                         if (rxd_wb.eop)
950                                 break;
951                         rxd = (struct hw_atl_rxd_s *)&rxq->hw_ring[tail];
952                         rxd_wb = *(struct hw_atl_rxd_wb_s *)rxd;
953                 };
954
955                 /*
956                  * Store the mbuf address into the next entry of the array
957                  * of returned packets.
958                  */
959                 rx_pkts[nb_rx++] = rx_mbuf_first;
960
961                 PMD_RX_LOG(ERR, "add mbuf segs=%d pkt_len=%d",
962                         rx_mbuf_first->nb_segs,
963                         rx_mbuf_first->pkt_len);
964         }
965
966 err_stop:
967
968         rxq->rx_tail = tail;
969
970         /*
971          * If the number of free RX descriptors is greater than the RX free
972          * threshold of the queue, advance the Receive Descriptor Tail (RDT)
973          * register.
974          * Update the RDT with the value of the last processed RX descriptor
975          * minus 1, to guarantee that the RDT register is never equal to the
976          * RDH register, which creates a "full" ring situtation from the
977          * hardware point of view...
978          */
979         nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold);
980         if (nb_hold > rxq->rx_free_thresh) {
981                 PMD_RX_LOG(ERR, "port_id=%u queue_id=%u rx_tail=%u "
982                         "nb_hold=%u nb_rx=%u",
983                         (unsigned int)rxq->port_id, (unsigned int)rxq->queue_id,
984                         (unsigned int)tail, (unsigned int)nb_hold,
985                         (unsigned int)nb_rx);
986                 tail = (uint16_t)((tail == 0) ?
987                         (rxq->nb_rx_desc - 1) : (tail - 1));
988
989                 hw_atl_reg_rx_dma_desc_tail_ptr_set(hw, tail, rxq->queue_id);
990
991                 nb_hold = 0;
992         }
993
994         rxq->nb_rx_hold = nb_hold;
995
996         return nb_rx;
997 }
998
999 static void
1000 atl_xmit_cleanup(struct atl_tx_queue *txq)
1001 {
1002         struct atl_tx_entry *sw_ring;
1003         struct hw_atl_txd_s *txd;
1004         int to_clean = 0;
1005
1006         PMD_INIT_FUNC_TRACE();
1007
1008         if (txq != NULL) {
1009                 sw_ring = txq->sw_ring;
1010                 int head = txq->tx_head;
1011                 int cnt;
1012                 int i;
1013
1014                 for (i = 0, cnt = head; ; i++) {
1015                         txd = &txq->hw_ring[cnt];
1016
1017                         if (txd->dd)
1018                                 to_clean++;
1019
1020                         cnt = (cnt + 1) % txq->nb_tx_desc;
1021                         if (cnt == txq->tx_tail)
1022                                 break;
1023                 }
1024
1025                 if (to_clean == 0)
1026                         return;
1027
1028                 while (to_clean) {
1029                         txd = &txq->hw_ring[head];
1030
1031                         struct atl_tx_entry *rx_entry = &sw_ring[head];
1032
1033                         if (rx_entry->mbuf) {
1034                                 rte_pktmbuf_free_seg(rx_entry->mbuf);
1035                                 rx_entry->mbuf = NULL;
1036                         }
1037
1038                         if (txd->dd)
1039                                 to_clean--;
1040
1041                         txd->buf_addr = 0;
1042                         txd->flags = 0;
1043
1044                         head = (head + 1) % txq->nb_tx_desc;
1045                         txq->tx_free++;
1046                 }
1047
1048                 txq->tx_head = head;
1049         }
1050 }
1051
1052 static int
1053 atl_tso_setup(struct rte_mbuf *tx_pkt, union hw_atl_txc_s *txc)
1054 {
1055         uint32_t tx_cmd = 0;
1056         uint64_t ol_flags = tx_pkt->ol_flags;
1057
1058         PMD_INIT_FUNC_TRACE();
1059
1060         if (ol_flags & PKT_TX_TCP_SEG) {
1061                 PMD_DRV_LOG(DEBUG, "xmit TSO pkt");
1062
1063                 tx_cmd |= tx_desc_cmd_lso | tx_desc_cmd_l4cs;
1064
1065                 txc->cmd = 0x4;
1066
1067                 if (ol_flags & PKT_TX_IPV6)
1068                         txc->cmd |= 0x2;
1069
1070                 txc->l2_len = tx_pkt->l2_len;
1071                 txc->l3_len = tx_pkt->l3_len;
1072                 txc->l4_len = tx_pkt->l4_len;
1073
1074                 txc->mss_len = tx_pkt->tso_segsz;
1075         }
1076
1077         if (ol_flags & PKT_TX_VLAN) {
1078                 tx_cmd |= tx_desc_cmd_vlan;
1079                 txc->vlan_tag = tx_pkt->vlan_tci;
1080         }
1081
1082         if (tx_cmd) {
1083                 txc->type = tx_desc_type_ctx;
1084                 txc->idx = 0;
1085         }
1086
1087         return tx_cmd;
1088 }
1089
1090 static inline void
1091 atl_setup_csum_offload(struct rte_mbuf *mbuf, struct hw_atl_txd_s *txd,
1092                        uint32_t tx_cmd)
1093 {
1094         txd->cmd |= tx_desc_cmd_fcs;
1095         txd->cmd |= (mbuf->ol_flags & PKT_TX_IP_CKSUM) ? tx_desc_cmd_ipv4 : 0;
1096         /* L4 csum requested */
1097         txd->cmd |= (mbuf->ol_flags & PKT_TX_L4_MASK) ? tx_desc_cmd_l4cs : 0;
1098         txd->cmd |= tx_cmd;
1099 }
1100
1101 static inline void
1102 atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
1103              struct rte_mbuf *tx_pkt)
1104 {
1105         uint32_t pay_len = 0;
1106         int tail = 0;
1107         struct atl_tx_entry *tx_entry;
1108         uint64_t buf_dma_addr;
1109         struct rte_mbuf *m_seg;
1110         union hw_atl_txc_s *txc = NULL;
1111         struct hw_atl_txd_s *txd = NULL;
1112         u32 tx_cmd = 0U;
1113         int desc_count = 0;
1114
1115         PMD_INIT_FUNC_TRACE();
1116
1117         tail = txq->tx_tail;
1118
1119         txc = (union hw_atl_txc_s *)&txq->hw_ring[tail];
1120
1121         txc->flags1 = 0U;
1122         txc->flags2 = 0U;
1123
1124         tx_cmd = atl_tso_setup(tx_pkt, txc);
1125
1126         if (tx_cmd) {
1127                 /* We've consumed the first desc, adjust counters */
1128                 tail = (tail + 1) % txq->nb_tx_desc;
1129                 txq->tx_tail = tail;
1130                 txq->tx_free -= 1;
1131
1132                 txd = &txq->hw_ring[tail];
1133                 txd->flags = 0U;
1134         } else {
1135                 txd = (struct hw_atl_txd_s *)txc;
1136         }
1137
1138         txd->ct_en = !!tx_cmd;
1139
1140         txd->type = tx_desc_type_desc;
1141
1142         atl_setup_csum_offload(tx_pkt, txd, tx_cmd);
1143
1144         if (tx_cmd)
1145                 txd->ct_idx = 0;
1146
1147         pay_len = tx_pkt->pkt_len;
1148
1149         txd->pay_len = pay_len;
1150
1151         for (m_seg = tx_pkt; m_seg; m_seg = m_seg->next) {
1152                 if (desc_count > 0) {
1153                         txd = &txq->hw_ring[tail];
1154                         txd->flags = 0U;
1155                 }
1156
1157                 buf_dma_addr = rte_mbuf_data_iova(m_seg);
1158                 txd->buf_addr = rte_cpu_to_le_64(buf_dma_addr);
1159
1160                 txd->type = tx_desc_type_desc;
1161                 txd->len = m_seg->data_len;
1162                 txd->pay_len = pay_len;
1163
1164                 /* Store mbuf for freeing later */
1165                 tx_entry = &txq->sw_ring[tail];
1166
1167                 if (tx_entry->mbuf)
1168                         rte_pktmbuf_free_seg(tx_entry->mbuf);
1169                 tx_entry->mbuf = m_seg;
1170
1171                 tail = (tail + 1) % txq->nb_tx_desc;
1172
1173                 desc_count++;
1174         }
1175
1176         // Last descriptor requires EOP and WB
1177         txd->eop = 1U;
1178         txd->cmd |= tx_desc_cmd_wb;
1179
1180         hw_atl_b0_hw_tx_ring_tail_update(hw, tail, txq->queue_id);
1181
1182         txq->tx_tail = tail;
1183
1184         txq->tx_free -= desc_count;
1185 }
1186
1187 uint16_t
1188 atl_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1189 {
1190         struct rte_eth_dev *dev = NULL;
1191         struct aq_hw_s *hw = NULL;
1192         struct atl_tx_queue *txq = tx_queue;
1193         struct rte_mbuf *tx_pkt;
1194         uint16_t nb_tx;
1195
1196         dev = &rte_eth_devices[txq->port_id];
1197         hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1198
1199         PMD_TX_LOG(DEBUG,
1200                 "port %d txq %d pkts: %d tx_free=%d tx_tail=%d tx_head=%d",
1201                 txq->port_id, txq->queue_id, nb_pkts, txq->tx_free,
1202                 txq->tx_tail, txq->tx_head);
1203
1204         for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
1205                 tx_pkt = *tx_pkts++;
1206
1207                 /* Clean Tx queue if needed */
1208                 if (txq->tx_free < txq->tx_free_thresh)
1209                         atl_xmit_cleanup(txq);
1210
1211                 /* Check if we have enough free descriptors */
1212                 if (txq->tx_free < tx_pkt->nb_segs)
1213                         break;
1214
1215                 /* check mbuf is valid */
1216                 if ((tx_pkt->nb_segs == 0) ||
1217                         ((tx_pkt->nb_segs > 1) && (tx_pkt->next == NULL)))
1218                         break;
1219
1220                 /* Send the packet */
1221                 atl_xmit_pkt(hw, txq, tx_pkt);
1222         }
1223
1224         PMD_TX_LOG(DEBUG, "atl_xmit_pkts %d transmitted", nb_tx);
1225
1226         return nb_tx;
1227 }
1228