net/atlantic: add Rx/Tx descriptors information
[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 void
655 atl_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
656                  struct rte_eth_rxq_info *qinfo)
657 {
658         struct atl_rx_queue *rxq;
659
660         PMD_INIT_FUNC_TRACE();
661
662         rxq = dev->data->rx_queues[queue_id];
663
664         qinfo->mp = rxq->mb_pool;
665         qinfo->scattered_rx = dev->data->scattered_rx;
666         qinfo->nb_desc = rxq->nb_rx_desc;
667 }
668
669 void
670 atl_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
671                  struct rte_eth_txq_info *qinfo)
672 {
673         struct atl_tx_queue *txq;
674
675         PMD_INIT_FUNC_TRACE();
676
677         txq = dev->data->tx_queues[queue_id];
678
679         qinfo->nb_desc = txq->nb_tx_desc;
680 }
681
682 /* Return Rx queue avail count */
683
684 uint32_t
685 atl_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
686 {
687         struct atl_rx_queue *rxq;
688
689         PMD_INIT_FUNC_TRACE();
690
691         if (rx_queue_id >= dev->data->nb_rx_queues) {
692                 PMD_DRV_LOG(ERR, "Invalid RX queue id=%d", rx_queue_id);
693                 return 0;
694         }
695
696         rxq = dev->data->rx_queues[rx_queue_id];
697
698         if (rxq == NULL)
699                 return 0;
700
701         return rxq->nb_rx_desc - rxq->nb_rx_hold;
702 }
703
704 int
705 atl_dev_rx_descriptor_status(void *rx_queue, uint16_t offset)
706 {
707         struct atl_rx_queue *rxq = rx_queue;
708         struct hw_atl_rxd_wb_s *rxd;
709         uint32_t idx;
710
711         PMD_INIT_FUNC_TRACE();
712
713         if (unlikely(offset >= rxq->nb_rx_desc))
714                 return -EINVAL;
715
716         if (offset >= rxq->nb_rx_desc - rxq->nb_rx_hold)
717                 return RTE_ETH_RX_DESC_UNAVAIL;
718
719         idx = rxq->rx_tail + offset;
720
721         if (idx >= rxq->nb_rx_desc)
722                 idx -= rxq->nb_rx_desc;
723
724         rxd = (struct hw_atl_rxd_wb_s *)&rxq->hw_ring[idx];
725
726         if (rxd->dd)
727                 return RTE_ETH_RX_DESC_DONE;
728
729         return RTE_ETH_RX_DESC_AVAIL;
730 }
731
732 int
733 atl_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
734 {
735         struct atl_tx_queue *txq = tx_queue;
736         struct hw_atl_txd_s *txd;
737         uint32_t idx;
738
739         PMD_INIT_FUNC_TRACE();
740
741         if (unlikely(offset >= txq->nb_tx_desc))
742                 return -EINVAL;
743
744         idx = txq->tx_tail + offset;
745
746         if (idx >= txq->nb_tx_desc)
747                 idx -= txq->nb_tx_desc;
748
749         txd = &txq->hw_ring[idx];
750
751         if (txd->dd)
752                 return RTE_ETH_TX_DESC_DONE;
753
754         return RTE_ETH_TX_DESC_FULL;
755 }
756
757 static int
758 atl_rx_enable_intr(struct rte_eth_dev *dev, uint16_t queue_id, bool enable)
759 {
760         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
761         struct atl_rx_queue *rxq;
762
763         PMD_INIT_FUNC_TRACE();
764
765         if (queue_id >= dev->data->nb_rx_queues) {
766                 PMD_DRV_LOG(ERR, "Invalid RX queue id=%d", queue_id);
767                 return -EINVAL;
768         }
769
770         rxq = dev->data->rx_queues[queue_id];
771
772         if (rxq == NULL)
773                 return 0;
774
775         /* Mapping interrupt vector */
776         hw_atl_itr_irq_map_en_rx_set(hw, enable, queue_id);
777
778         return 0;
779 }
780
781 int
782 atl_dev_rx_queue_intr_enable(struct rte_eth_dev *eth_dev, uint16_t queue_id)
783 {
784         return atl_rx_enable_intr(eth_dev, queue_id, true);
785 }
786
787 int
788 atl_dev_rx_queue_intr_disable(struct rte_eth_dev *eth_dev, uint16_t queue_id)
789 {
790         return atl_rx_enable_intr(eth_dev, queue_id, false);
791 }
792
793 uint16_t
794 atl_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
795               uint16_t nb_pkts)
796 {
797         int i, ret;
798         uint64_t ol_flags;
799         struct rte_mbuf *m;
800
801         PMD_INIT_FUNC_TRACE();
802
803         for (i = 0; i < nb_pkts; i++) {
804                 m = tx_pkts[i];
805                 ol_flags = m->ol_flags;
806
807                 if (m->nb_segs > AQ_HW_MAX_SEGS_SIZE) {
808                         rte_errno = -EINVAL;
809                         return i;
810                 }
811
812                 if (ol_flags & ATL_TX_OFFLOAD_NOTSUP_MASK) {
813                         rte_errno = -ENOTSUP;
814                         return i;
815                 }
816
817 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
818                 ret = rte_validate_tx_offload(m);
819                 if (ret != 0) {
820                         rte_errno = ret;
821                         return i;
822                 }
823 #endif
824                 ret = rte_net_intel_cksum_prepare(m);
825                 if (ret != 0) {
826                         rte_errno = ret;
827                         return i;
828                 }
829         }
830
831         return i;
832 }
833
834 static uint64_t
835 atl_desc_to_offload_flags(struct atl_rx_queue *rxq,
836                           struct hw_atl_rxd_wb_s *rxd_wb)
837 {
838         uint64_t mbuf_flags = 0;
839
840         PMD_INIT_FUNC_TRACE();
841
842         /* IPv4 ? */
843         if (rxq->l3_csum_enabled && ((rxd_wb->pkt_type & 0x3) == 0)) {
844                 /* IPv4 csum error ? */
845                 if (rxd_wb->rx_stat & BIT(1))
846                         mbuf_flags |= PKT_RX_IP_CKSUM_BAD;
847                 else
848                         mbuf_flags |= PKT_RX_IP_CKSUM_GOOD;
849         } else {
850                 mbuf_flags |= PKT_RX_IP_CKSUM_UNKNOWN;
851         }
852
853         /* CSUM calculated ? */
854         if (rxq->l4_csum_enabled && (rxd_wb->rx_stat & BIT(3))) {
855                 if (rxd_wb->rx_stat & BIT(2))
856                         mbuf_flags |= PKT_RX_L4_CKSUM_BAD;
857                 else
858                         mbuf_flags |= PKT_RX_L4_CKSUM_GOOD;
859         } else {
860                 mbuf_flags |= PKT_RX_L4_CKSUM_UNKNOWN;
861         }
862
863         return mbuf_flags;
864 }
865
866 static uint32_t
867 atl_desc_to_pkt_type(struct hw_atl_rxd_wb_s *rxd_wb)
868 {
869         uint32_t type = RTE_PTYPE_UNKNOWN;
870         uint16_t l2_l3_type = rxd_wb->pkt_type & 0x3;
871         uint16_t l4_type = (rxd_wb->pkt_type & 0x1C) >> 2;
872
873         switch (l2_l3_type) {
874         case 0:
875                 type = RTE_PTYPE_L3_IPV4;
876                 break;
877         case 1:
878                 type = RTE_PTYPE_L3_IPV6;
879                 break;
880         case 2:
881                 type = RTE_PTYPE_L2_ETHER;
882                 break;
883         case 3:
884                 type = RTE_PTYPE_L2_ETHER_ARP;
885                 break;
886         }
887
888         switch (l4_type) {
889         case 0:
890                 type |= RTE_PTYPE_L4_TCP;
891                 break;
892         case 1:
893                 type |= RTE_PTYPE_L4_UDP;
894                 break;
895         case 2:
896                 type |= RTE_PTYPE_L4_SCTP;
897                 break;
898         case 3:
899                 type |= RTE_PTYPE_L4_ICMP;
900                 break;
901         }
902
903         if (rxd_wb->pkt_type & BIT(5))
904                 type |= RTE_PTYPE_L2_ETHER_VLAN;
905
906         return type;
907 }
908
909 uint16_t
910 atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
911 {
912         struct atl_rx_queue *rxq = (struct atl_rx_queue *)rx_queue;
913         struct rte_eth_dev *dev = &rte_eth_devices[rxq->port_id];
914         struct atl_adapter *adapter =
915                 ATL_DEV_TO_ADAPTER(&rte_eth_devices[rxq->port_id]);
916         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(adapter);
917         struct atl_rx_entry *sw_ring = rxq->sw_ring;
918
919         struct rte_mbuf *new_mbuf;
920         struct rte_mbuf *rx_mbuf, *rx_mbuf_prev, *rx_mbuf_first;
921         struct atl_rx_entry *rx_entry;
922         uint16_t nb_rx = 0;
923         uint16_t nb_hold = 0;
924         struct hw_atl_rxd_wb_s rxd_wb;
925         struct hw_atl_rxd_s *rxd = NULL;
926         uint16_t tail = rxq->rx_tail;
927         uint64_t dma_addr;
928         uint16_t pkt_len = 0;
929
930         while (nb_rx < nb_pkts) {
931                 uint16_t eop_tail = tail;
932
933                 rxd = (struct hw_atl_rxd_s *)&rxq->hw_ring[tail];
934                 rxd_wb = *(struct hw_atl_rxd_wb_s *)rxd;
935
936                 if (!rxd_wb.dd) { /* RxD is not done */
937                         break;
938                 }
939
940                 PMD_RX_LOG(ERR, "port_id=%u queue_id=%u tail=%u "
941                            "eop=0x%x pkt_len=%u hash=0x%x hash_type=0x%x",
942                            (unsigned int)rxq->port_id,
943                            (unsigned int)rxq->queue_id,
944                            (unsigned int)tail, (unsigned int)rxd_wb.eop,
945                            (unsigned int)rte_le_to_cpu_16(rxd_wb.pkt_len),
946                         rxd_wb.rss_hash, rxd_wb.rss_type);
947
948                 /* RxD is not done */
949                 if (!rxd_wb.eop) {
950                         while (true) {
951                                 struct hw_atl_rxd_wb_s *eop_rxwbd;
952
953                                 eop_tail = (eop_tail + 1) % rxq->nb_rx_desc;
954                                 eop_rxwbd = (struct hw_atl_rxd_wb_s *)
955                                         &rxq->hw_ring[eop_tail];
956                                 if (!eop_rxwbd->dd) {
957                                         /* no EOP received yet */
958                                         eop_tail = tail;
959                                         break;
960                                 }
961                                 if (eop_rxwbd->dd && eop_rxwbd->eop)
962                                         break;
963                         }
964                         /* No EOP in ring */
965                         if (eop_tail == tail)
966                                 break;
967                 }
968                 rx_mbuf_prev = NULL;
969                 rx_mbuf_first = NULL;
970
971                 /* Run through packet segments */
972                 while (true) {
973                         new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
974                         if (new_mbuf == NULL) {
975                                 PMD_RX_LOG(ERR,
976                                    "RX mbuf alloc failed port_id=%u "
977                                    "queue_id=%u", (unsigned int)rxq->port_id,
978                                    (unsigned int)rxq->queue_id);
979                                 dev->data->rx_mbuf_alloc_failed++;
980                                 adapter->sw_stats.rx_nombuf++;
981                                 goto err_stop;
982                         }
983
984                         nb_hold++;
985                         rx_entry = &sw_ring[tail];
986
987                         rx_mbuf = rx_entry->mbuf;
988                         rx_entry->mbuf = new_mbuf;
989                         dma_addr = rte_cpu_to_le_64(
990                                 rte_mbuf_data_iova_default(new_mbuf));
991
992                         /* setup RX descriptor */
993                         rxd->hdr_addr = 0;
994                         rxd->buf_addr = dma_addr;
995
996                         /*
997                          * Initialize the returned mbuf.
998                          * 1) setup generic mbuf fields:
999                          *        - number of segments,
1000                          *        - next segment,
1001                          *        - packet length,
1002                          *        - RX port identifier.
1003                          * 2) integrate hardware offload data, if any:
1004                          *      <  - RSS flag & hash,
1005                          *        - IP checksum flag,
1006                          *        - VLAN TCI, if any,
1007                          *        - error flags.
1008                          */
1009                         pkt_len = (uint16_t)rte_le_to_cpu_16(rxd_wb.pkt_len);
1010                         rx_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
1011                         rte_prefetch1((char *)rx_mbuf->buf_addr +
1012                                 rx_mbuf->data_off);
1013                         rx_mbuf->nb_segs = 0;
1014                         rx_mbuf->next = NULL;
1015                         rx_mbuf->pkt_len = pkt_len;
1016                         rx_mbuf->data_len = pkt_len;
1017                         if (rxd_wb.eop) {
1018                                 u16 remainder_len = pkt_len % rxq->buff_size;
1019                                 if (!remainder_len)
1020                                         remainder_len = rxq->buff_size;
1021                                 rx_mbuf->data_len = remainder_len;
1022                         } else {
1023                                 rx_mbuf->data_len = pkt_len > rxq->buff_size ?
1024                                                 rxq->buff_size : pkt_len;
1025                         }
1026                         rx_mbuf->port = rxq->port_id;
1027
1028                         rx_mbuf->hash.rss = rxd_wb.rss_hash;
1029
1030                         rx_mbuf->vlan_tci = rxd_wb.vlan;
1031
1032                         rx_mbuf->ol_flags =
1033                                 atl_desc_to_offload_flags(rxq, &rxd_wb);
1034                         rx_mbuf->packet_type = atl_desc_to_pkt_type(&rxd_wb);
1035
1036                         if (!rx_mbuf_first)
1037                                 rx_mbuf_first = rx_mbuf;
1038                         rx_mbuf_first->nb_segs++;
1039
1040                         if (rx_mbuf_prev)
1041                                 rx_mbuf_prev->next = rx_mbuf;
1042                         rx_mbuf_prev = rx_mbuf;
1043
1044                         tail = (tail + 1) % rxq->nb_rx_desc;
1045                         /* Prefetch next mbufs */
1046                         rte_prefetch0(sw_ring[tail].mbuf);
1047                         if ((tail & 0x3) == 0) {
1048                                 rte_prefetch0(&sw_ring[tail]);
1049                                 rte_prefetch0(&sw_ring[tail]);
1050                         }
1051
1052                         /* filled mbuf_first */
1053                         if (rxd_wb.eop)
1054                                 break;
1055                         rxd = (struct hw_atl_rxd_s *)&rxq->hw_ring[tail];
1056                         rxd_wb = *(struct hw_atl_rxd_wb_s *)rxd;
1057                 };
1058
1059                 /*
1060                  * Store the mbuf address into the next entry of the array
1061                  * of returned packets.
1062                  */
1063                 rx_pkts[nb_rx++] = rx_mbuf_first;
1064                 adapter->sw_stats.q_ipackets[rxq->queue_id]++;
1065                 adapter->sw_stats.q_ibytes[rxq->queue_id] +=
1066                         rx_mbuf_first->pkt_len;
1067
1068                 PMD_RX_LOG(ERR, "add mbuf segs=%d pkt_len=%d",
1069                         rx_mbuf_first->nb_segs,
1070                         rx_mbuf_first->pkt_len);
1071         }
1072
1073 err_stop:
1074
1075         rxq->rx_tail = tail;
1076
1077         /*
1078          * If the number of free RX descriptors is greater than the RX free
1079          * threshold of the queue, advance the Receive Descriptor Tail (RDT)
1080          * register.
1081          * Update the RDT with the value of the last processed RX descriptor
1082          * minus 1, to guarantee that the RDT register is never equal to the
1083          * RDH register, which creates a "full" ring situtation from the
1084          * hardware point of view...
1085          */
1086         nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold);
1087         if (nb_hold > rxq->rx_free_thresh) {
1088                 PMD_RX_LOG(ERR, "port_id=%u queue_id=%u rx_tail=%u "
1089                         "nb_hold=%u nb_rx=%u",
1090                         (unsigned int)rxq->port_id, (unsigned int)rxq->queue_id,
1091                         (unsigned int)tail, (unsigned int)nb_hold,
1092                         (unsigned int)nb_rx);
1093                 tail = (uint16_t)((tail == 0) ?
1094                         (rxq->nb_rx_desc - 1) : (tail - 1));
1095
1096                 hw_atl_reg_rx_dma_desc_tail_ptr_set(hw, tail, rxq->queue_id);
1097
1098                 nb_hold = 0;
1099         }
1100
1101         rxq->nb_rx_hold = nb_hold;
1102
1103         return nb_rx;
1104 }
1105
1106 static void
1107 atl_xmit_cleanup(struct atl_tx_queue *txq)
1108 {
1109         struct atl_tx_entry *sw_ring;
1110         struct hw_atl_txd_s *txd;
1111         int to_clean = 0;
1112
1113         PMD_INIT_FUNC_TRACE();
1114
1115         if (txq != NULL) {
1116                 sw_ring = txq->sw_ring;
1117                 int head = txq->tx_head;
1118                 int cnt;
1119                 int i;
1120
1121                 for (i = 0, cnt = head; ; i++) {
1122                         txd = &txq->hw_ring[cnt];
1123
1124                         if (txd->dd)
1125                                 to_clean++;
1126
1127                         cnt = (cnt + 1) % txq->nb_tx_desc;
1128                         if (cnt == txq->tx_tail)
1129                                 break;
1130                 }
1131
1132                 if (to_clean == 0)
1133                         return;
1134
1135                 while (to_clean) {
1136                         txd = &txq->hw_ring[head];
1137
1138                         struct atl_tx_entry *rx_entry = &sw_ring[head];
1139
1140                         if (rx_entry->mbuf) {
1141                                 rte_pktmbuf_free_seg(rx_entry->mbuf);
1142                                 rx_entry->mbuf = NULL;
1143                         }
1144
1145                         if (txd->dd)
1146                                 to_clean--;
1147
1148                         txd->buf_addr = 0;
1149                         txd->flags = 0;
1150
1151                         head = (head + 1) % txq->nb_tx_desc;
1152                         txq->tx_free++;
1153                 }
1154
1155                 txq->tx_head = head;
1156         }
1157 }
1158
1159 static int
1160 atl_tso_setup(struct rte_mbuf *tx_pkt, union hw_atl_txc_s *txc)
1161 {
1162         uint32_t tx_cmd = 0;
1163         uint64_t ol_flags = tx_pkt->ol_flags;
1164
1165         PMD_INIT_FUNC_TRACE();
1166
1167         if (ol_flags & PKT_TX_TCP_SEG) {
1168                 PMD_DRV_LOG(DEBUG, "xmit TSO pkt");
1169
1170                 tx_cmd |= tx_desc_cmd_lso | tx_desc_cmd_l4cs;
1171
1172                 txc->cmd = 0x4;
1173
1174                 if (ol_flags & PKT_TX_IPV6)
1175                         txc->cmd |= 0x2;
1176
1177                 txc->l2_len = tx_pkt->l2_len;
1178                 txc->l3_len = tx_pkt->l3_len;
1179                 txc->l4_len = tx_pkt->l4_len;
1180
1181                 txc->mss_len = tx_pkt->tso_segsz;
1182         }
1183
1184         if (ol_flags & PKT_TX_VLAN) {
1185                 tx_cmd |= tx_desc_cmd_vlan;
1186                 txc->vlan_tag = tx_pkt->vlan_tci;
1187         }
1188
1189         if (tx_cmd) {
1190                 txc->type = tx_desc_type_ctx;
1191                 txc->idx = 0;
1192         }
1193
1194         return tx_cmd;
1195 }
1196
1197 static inline void
1198 atl_setup_csum_offload(struct rte_mbuf *mbuf, struct hw_atl_txd_s *txd,
1199                        uint32_t tx_cmd)
1200 {
1201         txd->cmd |= tx_desc_cmd_fcs;
1202         txd->cmd |= (mbuf->ol_flags & PKT_TX_IP_CKSUM) ? tx_desc_cmd_ipv4 : 0;
1203         /* L4 csum requested */
1204         txd->cmd |= (mbuf->ol_flags & PKT_TX_L4_MASK) ? tx_desc_cmd_l4cs : 0;
1205         txd->cmd |= tx_cmd;
1206 }
1207
1208 static inline void
1209 atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
1210              struct rte_mbuf *tx_pkt)
1211 {
1212         struct atl_adapter *adapter =
1213                 ATL_DEV_TO_ADAPTER(&rte_eth_devices[txq->port_id]);
1214         uint32_t pay_len = 0;
1215         int tail = 0;
1216         struct atl_tx_entry *tx_entry;
1217         uint64_t buf_dma_addr;
1218         struct rte_mbuf *m_seg;
1219         union hw_atl_txc_s *txc = NULL;
1220         struct hw_atl_txd_s *txd = NULL;
1221         u32 tx_cmd = 0U;
1222         int desc_count = 0;
1223
1224         PMD_INIT_FUNC_TRACE();
1225
1226         tail = txq->tx_tail;
1227
1228         txc = (union hw_atl_txc_s *)&txq->hw_ring[tail];
1229
1230         txc->flags1 = 0U;
1231         txc->flags2 = 0U;
1232
1233         tx_cmd = atl_tso_setup(tx_pkt, txc);
1234
1235         if (tx_cmd) {
1236                 /* We've consumed the first desc, adjust counters */
1237                 tail = (tail + 1) % txq->nb_tx_desc;
1238                 txq->tx_tail = tail;
1239                 txq->tx_free -= 1;
1240
1241                 txd = &txq->hw_ring[tail];
1242                 txd->flags = 0U;
1243         } else {
1244                 txd = (struct hw_atl_txd_s *)txc;
1245         }
1246
1247         txd->ct_en = !!tx_cmd;
1248
1249         txd->type = tx_desc_type_desc;
1250
1251         atl_setup_csum_offload(tx_pkt, txd, tx_cmd);
1252
1253         if (tx_cmd)
1254                 txd->ct_idx = 0;
1255
1256         pay_len = tx_pkt->pkt_len;
1257
1258         txd->pay_len = pay_len;
1259
1260         for (m_seg = tx_pkt; m_seg; m_seg = m_seg->next) {
1261                 if (desc_count > 0) {
1262                         txd = &txq->hw_ring[tail];
1263                         txd->flags = 0U;
1264                 }
1265
1266                 buf_dma_addr = rte_mbuf_data_iova(m_seg);
1267                 txd->buf_addr = rte_cpu_to_le_64(buf_dma_addr);
1268
1269                 txd->type = tx_desc_type_desc;
1270                 txd->len = m_seg->data_len;
1271                 txd->pay_len = pay_len;
1272
1273                 /* Store mbuf for freeing later */
1274                 tx_entry = &txq->sw_ring[tail];
1275
1276                 if (tx_entry->mbuf)
1277                         rte_pktmbuf_free_seg(tx_entry->mbuf);
1278                 tx_entry->mbuf = m_seg;
1279
1280                 tail = (tail + 1) % txq->nb_tx_desc;
1281
1282                 desc_count++;
1283         }
1284
1285         // Last descriptor requires EOP and WB
1286         txd->eop = 1U;
1287         txd->cmd |= tx_desc_cmd_wb;
1288
1289         hw_atl_b0_hw_tx_ring_tail_update(hw, tail, txq->queue_id);
1290
1291         txq->tx_tail = tail;
1292
1293         txq->tx_free -= desc_count;
1294
1295         adapter->sw_stats.q_opackets[txq->queue_id]++;
1296         adapter->sw_stats.q_obytes[txq->queue_id] += pay_len;
1297 }
1298
1299 uint16_t
1300 atl_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1301 {
1302         struct rte_eth_dev *dev = NULL;
1303         struct aq_hw_s *hw = NULL;
1304         struct atl_tx_queue *txq = tx_queue;
1305         struct rte_mbuf *tx_pkt;
1306         uint16_t nb_tx;
1307
1308         dev = &rte_eth_devices[txq->port_id];
1309         hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1310
1311         PMD_TX_LOG(DEBUG,
1312                 "port %d txq %d pkts: %d tx_free=%d tx_tail=%d tx_head=%d",
1313                 txq->port_id, txq->queue_id, nb_pkts, txq->tx_free,
1314                 txq->tx_tail, txq->tx_head);
1315
1316         for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
1317                 tx_pkt = *tx_pkts++;
1318
1319                 /* Clean Tx queue if needed */
1320                 if (txq->tx_free < txq->tx_free_thresh)
1321                         atl_xmit_cleanup(txq);
1322
1323                 /* Check if we have enough free descriptors */
1324                 if (txq->tx_free < tx_pkt->nb_segs)
1325                         break;
1326
1327                 /* check mbuf is valid */
1328                 if ((tx_pkt->nb_segs == 0) ||
1329                         ((tx_pkt->nb_segs > 1) && (tx_pkt->next == NULL)))
1330                         break;
1331
1332                 /* Send the packet */
1333                 atl_xmit_pkt(hw, txq, tx_pkt);
1334         }
1335
1336         PMD_TX_LOG(DEBUG, "atl_xmit_pkts %d transmitted", nb_tx);
1337
1338         return nb_tx;
1339 }
1340