LCOV - code coverage report
Current view: top level - drivers/net/axgbe - axgbe_rxtx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 528 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 25 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 266 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
       3                 :            :  *   Copyright(c) 2018 Synopsys, Inc. All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "axgbe_ethdev.h"
       7                 :            : #include "axgbe_rxtx.h"
       8                 :            : #include "axgbe_phy.h"
       9                 :            : 
      10                 :            : #include <rte_time.h>
      11                 :            : #include <rte_mempool.h>
      12                 :            : #include <rte_mbuf.h>
      13                 :            : #include <rte_vect.h>
      14                 :            : 
      15                 :            : static void
      16                 :          0 : axgbe_rx_queue_release(struct axgbe_rx_queue *rx_queue)
      17                 :            : {
      18                 :            :         uint16_t i;
      19                 :            :         struct rte_mbuf **sw_ring;
      20                 :            : 
      21         [ #  # ]:          0 :         if (rx_queue) {
      22                 :          0 :                 sw_ring = rx_queue->sw_ring;
      23         [ #  # ]:          0 :                 if (sw_ring) {
      24         [ #  # ]:          0 :                         for (i = 0; i < rx_queue->nb_desc; i++) {
      25                 :          0 :                                 rte_pktmbuf_free(sw_ring[i]);
      26                 :            :                         }
      27                 :          0 :                         rte_free(sw_ring);
      28                 :            :                 }
      29                 :          0 :                 rte_free(rx_queue);
      30                 :            :         }
      31                 :          0 : }
      32                 :            : 
      33                 :          0 : void axgbe_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t queue_idx)
      34                 :            : {
      35                 :          0 :         axgbe_rx_queue_release(dev->data->rx_queues[queue_idx]);
      36                 :          0 : }
      37                 :            : 
      38                 :          0 : int axgbe_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
      39                 :            :                              uint16_t nb_desc, unsigned int socket_id,
      40                 :            :                              const struct rte_eth_rxconf *rx_conf,
      41                 :            :                              struct rte_mempool *mp)
      42                 :            : {
      43                 :            :         PMD_INIT_FUNC_TRACE();
      44                 :            :         uint32_t size;
      45                 :            :         const struct rte_memzone *dma;
      46                 :            :         struct axgbe_rx_queue *rxq;
      47                 :          0 :         uint32_t rx_desc = nb_desc;
      48         [ #  # ]:          0 :         struct axgbe_port *pdata =  dev->data->dev_private;
      49                 :            : 
      50                 :            :         /*
      51                 :            :          * validate Rx descriptors count
      52                 :            :          * should be power of 2 and less than h/w supported
      53                 :            :          */
      54                 :          0 :         if ((!rte_is_power_of_2(rx_desc)) ||
      55         [ #  # ]:          0 :             rx_desc > pdata->rx_desc_count)
      56                 :            :                 return -EINVAL;
      57                 :            :         /* First allocate the rx queue data structure */
      58                 :          0 :         rxq = rte_zmalloc_socket("ethdev RX queue",
      59                 :            :                                  sizeof(struct axgbe_rx_queue),
      60                 :            :                                  RTE_CACHE_LINE_SIZE, socket_id);
      61         [ #  # ]:          0 :         if (!rxq) {
      62                 :          0 :                 PMD_INIT_LOG(ERR, "rte_zmalloc for rxq failed!");
      63                 :          0 :                 return -ENOMEM;
      64                 :            :         }
      65                 :            : 
      66                 :          0 :         rxq->cur = 0;
      67                 :          0 :         rxq->dirty = 0;
      68                 :          0 :         rxq->pdata = pdata;
      69                 :          0 :         rxq->mb_pool = mp;
      70                 :          0 :         rxq->queue_id = queue_idx;
      71                 :          0 :         rxq->port_id = dev->data->port_id;
      72                 :          0 :         rxq->nb_desc = rx_desc;
      73                 :          0 :         rxq->dma_regs = (void *)((uint8_t *)pdata->xgmac_regs + DMA_CH_BASE +
      74                 :          0 :                 (DMA_CH_INC * rxq->queue_id));
      75                 :          0 :         rxq->dma_tail_reg = (volatile uint32_t *)((uint8_t *)rxq->dma_regs +
      76                 :            :                                                   DMA_CH_RDTR_LO);
      77         [ #  # ]:          0 :         if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
      78                 :          0 :                 rxq->crc_len = RTE_ETHER_CRC_LEN;
      79                 :            :         else
      80                 :          0 :                 rxq->crc_len = 0;
      81                 :            : 
      82                 :            :         /* CRC strip in AXGBE supports per port not per queue */
      83                 :          0 :         pdata->crc_strip_enable = (rxq->crc_len == 0) ? 1 : 0;
      84         [ #  # ]:          0 :         rxq->free_thresh = rx_conf->rx_free_thresh ?
      85                 :            :                 rx_conf->rx_free_thresh : AXGBE_RX_FREE_THRESH;
      86         [ #  # ]:          0 :         if (rxq->free_thresh >  rxq->nb_desc)
      87                 :          0 :                 rxq->free_thresh = rxq->nb_desc >> 3;
      88                 :            : 
      89                 :          0 :         rxq->offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
      90                 :            :         /* Allocate RX ring hardware descriptors */
      91                 :          0 :         size = rxq->nb_desc * sizeof(union axgbe_rx_desc);
      92                 :          0 :         dma = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size, 128,
      93                 :            :                                        socket_id);
      94         [ #  # ]:          0 :         if (!dma) {
      95                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "ring_dma_zone_reserve for rx_ring failed");
      96                 :          0 :                 axgbe_rx_queue_release(rxq);
      97                 :          0 :                 return -ENOMEM;
      98                 :            :         }
      99                 :          0 :         rxq->ring_phys_addr = (uint64_t)dma->iova;
     100                 :          0 :         rxq->desc = (volatile union axgbe_rx_desc *)dma->addr;
     101                 :            :         memset((void *)rxq->desc, 0, size);
     102                 :            :         /* Allocate software ring */
     103                 :          0 :         size = rxq->nb_desc * sizeof(struct rte_mbuf *);
     104                 :          0 :         rxq->sw_ring = rte_zmalloc_socket("sw_ring", size,
     105                 :            :                                           RTE_CACHE_LINE_SIZE,
     106                 :            :                                           socket_id);
     107         [ #  # ]:          0 :         if (!rxq->sw_ring) {
     108                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "rte_zmalloc for sw_ring failed");
     109                 :          0 :                 axgbe_rx_queue_release(rxq);
     110                 :          0 :                 return -ENOMEM;
     111                 :            :         }
     112                 :          0 :         dev->data->rx_queues[queue_idx] = rxq;
     113         [ #  # ]:          0 :         if (!pdata->rx_queues)
     114                 :          0 :                 pdata->rx_queues = dev->data->rx_queues;
     115                 :            : 
     116                 :            :         return 0;
     117                 :            : }
     118                 :            : 
     119                 :          0 : static void axgbe_prepare_rx_stop(struct axgbe_port *pdata,
     120                 :            :                                   unsigned int queue)
     121                 :            : {
     122                 :            :         unsigned int rx_status;
     123                 :            :         unsigned long rx_timeout;
     124                 :            : 
     125                 :            :         /* The Rx engine cannot be stopped if it is actively processing
     126                 :            :          * packets. Wait for the Rx queue to empty the Rx fifo.  Don't
     127                 :            :          * wait forever though...
     128                 :            :          */
     129                 :          0 :         rx_timeout = rte_get_timer_cycles() + (AXGBE_DMA_STOP_TIMEOUT *
     130                 :            :                                                rte_get_timer_hz());
     131                 :            : 
     132         [ #  # ]:          0 :         while (time_before(rte_get_timer_cycles(), rx_timeout)) {
     133                 :          0 :                 rx_status = AXGMAC_MTL_IOREAD(pdata, queue, MTL_Q_RQDR);
     134         [ #  # ]:          0 :                 if ((AXGMAC_GET_BITS(rx_status, MTL_Q_RQDR, PRXQ) == 0) &&
     135         [ #  # ]:          0 :                     (AXGMAC_GET_BITS(rx_status, MTL_Q_RQDR, RXQSTS) == 0))
     136                 :            :                         break;
     137                 :            : 
     138                 :          0 :                 rte_delay_us(900);
     139                 :            :         }
     140                 :            : 
     141         [ #  # ]:          0 :         if (!time_before(rte_get_timer_cycles(), rx_timeout))
     142                 :          0 :                 PMD_DRV_LOG_LINE(ERR,
     143                 :            :                             "timed out waiting for Rx queue %u to empty",
     144                 :            :                             queue);
     145                 :          0 : }
     146                 :            : 
     147                 :          0 : void axgbe_dev_disable_rx(struct rte_eth_dev *dev)
     148                 :            : {
     149                 :            :         struct axgbe_rx_queue *rxq;
     150                 :          0 :         struct axgbe_port *pdata = dev->data->dev_private;
     151                 :            :         unsigned int i;
     152                 :            : 
     153                 :            :         /* Disable MAC Rx */
     154                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 0);
     155                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 0);
     156                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0);
     157                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0);
     158                 :            : 
     159                 :            :         /* Prepare for Rx DMA channel stop */
     160         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     161                 :            :                 rxq = dev->data->rx_queues[i];
     162                 :          0 :                 axgbe_prepare_rx_stop(pdata, i);
     163                 :            :         }
     164                 :            :         /* Disable each Rx queue */
     165                 :          0 :         AXGMAC_IOWRITE(pdata, MAC_RQC0R, 0);
     166         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     167                 :          0 :                 rxq = dev->data->rx_queues[i];
     168                 :            :                 /* Disable Rx DMA channel */
     169                 :          0 :                 AXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, SR, 0);
     170                 :            :         }
     171                 :          0 : }
     172                 :            : 
     173                 :          0 : void axgbe_dev_enable_rx(struct rte_eth_dev *dev)
     174                 :            : {
     175                 :            :         struct axgbe_rx_queue *rxq;
     176                 :          0 :         struct axgbe_port *pdata = dev->data->dev_private;
     177                 :            :         unsigned int i;
     178                 :            :         unsigned int reg_val = 0;
     179                 :            : 
     180         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     181                 :          0 :                 rxq = dev->data->rx_queues[i];
     182                 :            :                 /* Enable Rx DMA channel */
     183                 :          0 :                 AXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, SR, 1);
     184                 :            :         }
     185                 :            : 
     186                 :            :         reg_val = 0;
     187         [ #  # ]:          0 :         for (i = 0; i < pdata->rx_q_count; i++)
     188                 :          0 :                 reg_val |= (0x02 << (i << 1));
     189                 :          0 :         AXGMAC_IOWRITE(pdata, MAC_RQC0R, reg_val);
     190                 :            : 
     191                 :            :         /* Enable MAC Rx */
     192                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 1);
     193                 :            :         /* Frame is forwarded after stripping CRC to application*/
     194         [ #  # ]:          0 :         if (pdata->crc_strip_enable) {
     195                 :          0 :                 AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 1);
     196                 :          0 :                 AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 1);
     197                 :            :         }
     198                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 1);
     199                 :          0 : }
     200                 :            : 
     201                 :            : /* Rx function one to one refresh */
     202                 :            : uint16_t
     203                 :          0 : axgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
     204                 :            :                 uint16_t nb_pkts)
     205                 :            : {
     206                 :            :         PMD_INIT_FUNC_TRACE();
     207                 :            :         uint16_t nb_rx = 0;
     208                 :            :         struct axgbe_rx_queue *rxq = rx_queue;
     209                 :            :         volatile union axgbe_rx_desc *desc;
     210                 :          0 :         uint64_t old_dirty = rxq->dirty;
     211                 :            :         struct rte_mbuf *mbuf, *tmbuf;
     212                 :            :         unsigned int err, etlt;
     213                 :            :         uint32_t error_status;
     214                 :            :         uint16_t idx, pidx, pkt_len;
     215                 :            : 
     216                 :          0 :         idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur);
     217         [ #  # ]:          0 :         while (nb_rx < nb_pkts) {
     218         [ #  # ]:          0 :                 if (unlikely(idx == rxq->nb_desc))
     219                 :            :                         idx = 0;
     220                 :            : 
     221                 :          0 :                 desc = &rxq->desc[idx];
     222                 :            : 
     223         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, OWN))
     224                 :            :                         break;
     225                 :          0 :                 tmbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     226         [ #  # ]:          0 :                 if (unlikely(!tmbuf)) {
     227                 :          0 :                         PMD_DRV_LOG_LINE(ERR, "RX mbuf alloc failed port_id = %u"
     228                 :            :                                     " queue_id = %u",
     229                 :            :                                     (unsigned int)rxq->port_id,
     230                 :            :                                     (unsigned int)rxq->queue_id);
     231                 :            :                         rte_eth_devices[
     232                 :          0 :                                 rxq->port_id].data->rx_mbuf_alloc_failed++;
     233                 :          0 :                         rxq->rx_mbuf_alloc_failed++;
     234                 :          0 :                         break;
     235                 :            :                 }
     236                 :          0 :                 pidx = idx + 1;
     237         [ #  # ]:          0 :                 if (unlikely(pidx == rxq->nb_desc))
     238                 :            :                         pidx = 0;
     239                 :            : 
     240                 :          0 :                 rte_prefetch0(rxq->sw_ring[pidx]);
     241         [ #  # ]:          0 :                 if ((pidx & 0x3) == 0) {
     242                 :          0 :                         rte_prefetch0(&rxq->desc[pidx]);
     243                 :            :                         rte_prefetch0(&rxq->sw_ring[pidx]);
     244                 :            :                 }
     245                 :            : 
     246                 :          0 :                 mbuf = rxq->sw_ring[idx];
     247                 :            :                 /* Check for any errors and free mbuf*/
     248                 :          0 :                 err = AXGMAC_GET_BITS_LE(desc->write.desc3,
     249                 :            :                                          RX_NORMAL_DESC3, ES);
     250                 :            :                 error_status = 0;
     251         [ #  # ]:          0 :                 if (unlikely(err)) {
     252                 :          0 :                         error_status = desc->write.desc3 & AXGBE_ERR_STATUS;
     253                 :          0 :                         if ((error_status != AXGBE_L3_CSUM_ERR) &&
     254         [ #  # ]:          0 :                             (error_status != AXGBE_L4_CSUM_ERR)) {
     255                 :          0 :                                 rxq->errors++;
     256                 :          0 :                                 rte_pktmbuf_free(mbuf);
     257                 :          0 :                                 goto err_set;
     258                 :            :                         }
     259                 :            :                 }
     260         [ #  # ]:          0 :                 if (rxq->pdata->rx_csum_enable) {
     261                 :            :                         mbuf->ol_flags = 0;
     262                 :            :                         mbuf->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     263                 :          0 :                         mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     264         [ #  # ]:          0 :                         if (unlikely(error_status == AXGBE_L3_CSUM_ERR)) {
     265                 :            :                                 mbuf->ol_flags &= ~RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     266                 :            :                                 mbuf->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
     267                 :          0 :                                 mbuf->ol_flags &= ~RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     268                 :            :                                 mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN;
     269                 :          0 :                         } else if (
     270         [ #  # ]:          0 :                                 unlikely(error_status == AXGBE_L4_CSUM_ERR)) {
     271                 :            :                                 mbuf->ol_flags &= ~RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     272                 :          0 :                                 mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
     273                 :            :                         }
     274                 :            :                 }
     275                 :          0 :                 rte_prefetch1(rte_pktmbuf_mtod(mbuf, void *));
     276                 :            :                 /* Get the RSS hash */
     277         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, RSV))
     278                 :          0 :                         mbuf->hash.rss = rte_le_to_cpu_32(desc->write.desc1);
     279                 :          0 :                 etlt = AXGMAC_GET_BITS_LE(desc->write.desc3,
     280                 :            :                                 RX_NORMAL_DESC3, ETLT);
     281         [ #  # ]:          0 :                 if (!err || !etlt) {
     282         [ #  # ]:          0 :                         if (etlt == RX_CVLAN_TAG_PRESENT) {
     283                 :          0 :                                 mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN;
     284                 :          0 :                                 mbuf->vlan_tci =
     285                 :          0 :                                         AXGMAC_GET_BITS_LE(desc->write.desc0,
     286                 :            :                                                         RX_NORMAL_DESC0, OVT);
     287         [ #  # ]:          0 :                                 if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
     288                 :          0 :                                         mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN_STRIPPED;
     289                 :            :                                 else
     290                 :          0 :                                         mbuf->ol_flags &= ~RTE_MBUF_F_RX_VLAN_STRIPPED;
     291                 :            :                         } else {
     292                 :          0 :                                 mbuf->ol_flags &=
     293                 :            :                                         ~(RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED);
     294                 :          0 :                                 mbuf->vlan_tci = 0;
     295                 :            :                         }
     296                 :            :                 }
     297                 :            :                 /* Indicate if a Context Descriptor is next */
     298         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, CDA))
     299                 :          0 :                         mbuf->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP
     300                 :            :                                         | RTE_MBUF_F_RX_IEEE1588_TMST;
     301                 :          0 :                 pkt_len = AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3,
     302                 :          0 :                                              PL) - rxq->crc_len;
     303                 :            :                 /* Mbuf populate */
     304                 :          0 :                 mbuf->next = NULL;
     305                 :          0 :                 mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     306                 :          0 :                 mbuf->nb_segs = 1;
     307                 :          0 :                 mbuf->port = rxq->port_id;
     308                 :          0 :                 mbuf->pkt_len = pkt_len;
     309                 :          0 :                 mbuf->data_len = pkt_len;
     310                 :          0 :                 rxq->bytes += pkt_len;
     311                 :          0 :                 rx_pkts[nb_rx++] = mbuf;
     312                 :          0 : err_set:
     313                 :          0 :                 rxq->cur++;
     314                 :          0 :                 rxq->sw_ring[idx++] = tmbuf;
     315                 :          0 :                 desc->read.baddr =
     316                 :            :                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(tmbuf));
     317                 :          0 :                 memset((void *)(&desc->read.desc2), 0, 8);
     318                 :          0 :                 AXGMAC_SET_BITS_LE(desc->read.desc3, RX_NORMAL_DESC3, OWN, 1);
     319                 :          0 :                 rxq->dirty++;
     320                 :            :         }
     321                 :          0 :         rxq->pkts += nb_rx;
     322         [ #  # ]:          0 :         if (rxq->dirty != old_dirty) {
     323                 :            :                 rte_wmb();
     324                 :          0 :                 idx = AXGBE_GET_DESC_IDX(rxq, rxq->dirty - 1);
     325                 :          0 :                 AXGMAC_DMA_IOWRITE(rxq, DMA_CH_RDTR_LO,
     326                 :            :                                    low32_value(rxq->ring_phys_addr +
     327                 :            :                                    (idx * sizeof(union axgbe_rx_desc))));
     328                 :            :         }
     329                 :            : 
     330                 :          0 :         return nb_rx;
     331                 :            : }
     332                 :            : 
     333                 :            : 
     334                 :          0 : uint16_t eth_axgbe_recv_scattered_pkts(void *rx_queue,
     335                 :            :                 struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
     336                 :            : {
     337                 :            :         PMD_INIT_FUNC_TRACE();
     338                 :            :         uint16_t nb_rx = 0;
     339                 :            :         struct axgbe_rx_queue *rxq = rx_queue;
     340                 :            :         volatile union axgbe_rx_desc *desc;
     341                 :            : 
     342                 :            :         struct rte_mbuf *first_seg = NULL;
     343                 :            :         struct rte_mbuf *mbuf, *tmbuf;
     344                 :            :         unsigned int err = 0, etlt;
     345                 :            :         uint32_t error_status = 0;
     346                 :            :         uint16_t idx, pidx, data_len = 0, pkt_len = 0;
     347                 :            :         bool eop = 0;
     348                 :            : 
     349                 :            :         idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur);
     350                 :            : 
     351         [ #  # ]:          0 :         while (nb_rx < nb_pkts) {
     352                 :          0 : next_desc:
     353                 :          0 :                 idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur);
     354                 :            : 
     355                 :          0 :                 desc = &rxq->desc[idx];
     356                 :            : 
     357         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, OWN))
     358                 :            :                         break;
     359                 :            : 
     360                 :          0 :                 tmbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     361         [ #  # ]:          0 :                 if (unlikely(!tmbuf)) {
     362                 :          0 :                         PMD_DRV_LOG_LINE(ERR, "RX mbuf alloc failed port_id = %u"
     363                 :            :                                     " queue_id = %u",
     364                 :            :                                     (unsigned int)rxq->port_id,
     365                 :            :                                     (unsigned int)rxq->queue_id);
     366                 :          0 :                         rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed++;
     367                 :          0 :                         break;
     368                 :            :                 }
     369                 :            : 
     370                 :          0 :                 pidx = idx + 1;
     371         [ #  # ]:          0 :                 if (unlikely(pidx == rxq->nb_desc))
     372                 :            :                         pidx = 0;
     373                 :            : 
     374                 :          0 :                 rte_prefetch0(rxq->sw_ring[pidx]);
     375         [ #  # ]:          0 :                 if ((pidx & 0x3) == 0) {
     376                 :          0 :                         rte_prefetch0(&rxq->desc[pidx]);
     377                 :            :                         rte_prefetch0(&rxq->sw_ring[pidx]);
     378                 :            :                 }
     379                 :            : 
     380                 :          0 :                 mbuf = rxq->sw_ring[idx];
     381                 :          0 :                 rte_prefetch1(rte_pktmbuf_mtod(mbuf, void *));
     382                 :            : 
     383         [ #  # ]:          0 :                 if (!AXGMAC_GET_BITS_LE(desc->write.desc3,
     384                 :            :                                         RX_NORMAL_DESC3, LD)) {
     385                 :            :                         eop = 0;
     386                 :          0 :                         pkt_len = rxq->buf_size;
     387                 :            :                         data_len = pkt_len;
     388                 :            :                 } else {
     389                 :            :                         eop = 1;
     390                 :          0 :                         pkt_len = AXGMAC_GET_BITS_LE(desc->write.desc3,
     391                 :          0 :                                         RX_NORMAL_DESC3, PL) - rxq->crc_len;
     392                 :          0 :                         data_len = pkt_len % rxq->buf_size;
     393                 :            :                         /* Check for any errors and free mbuf*/
     394                 :          0 :                         err = AXGMAC_GET_BITS_LE(desc->write.desc3,
     395                 :            :                                         RX_NORMAL_DESC3, ES);
     396                 :            :                         error_status = 0;
     397         [ #  # ]:          0 :                         if (unlikely(err)) {
     398                 :          0 :                                 error_status = desc->write.desc3 &
     399                 :            :                                         AXGBE_ERR_STATUS;
     400                 :          0 :                                 if (error_status != AXGBE_L3_CSUM_ERR &&
     401         [ #  # ]:          0 :                                                 error_status != AXGBE_L4_CSUM_ERR) {
     402                 :          0 :                                         rxq->errors++;
     403                 :          0 :                                         rte_pktmbuf_free(mbuf);
     404                 :          0 :                                         rte_pktmbuf_free(first_seg);
     405                 :            :                                         first_seg = NULL;
     406                 :            :                                         eop = 0;
     407                 :          0 :                                         goto err_set;
     408                 :            :                                 }
     409                 :            :                         }
     410                 :            : 
     411                 :            :                 }
     412                 :            :                 /* Mbuf populate */
     413                 :          0 :                 mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     414                 :          0 :                 mbuf->data_len = data_len;
     415                 :          0 :                 mbuf->pkt_len = data_len;
     416                 :            : 
     417         [ #  # ]:          0 :                 if (rxq->saved_mbuf) {
     418                 :            :                         first_seg = rxq->saved_mbuf;
     419                 :          0 :                         rxq->saved_mbuf = NULL;
     420                 :            :                 }
     421                 :            : 
     422         [ #  # ]:          0 :                 if (first_seg != NULL) {
     423                 :            :                         if (rte_pktmbuf_chain(first_seg, mbuf) != 0) {
     424                 :          0 :                                 rte_pktmbuf_free(first_seg);
     425                 :            :                                 first_seg = NULL;
     426                 :          0 :                                 rte_pktmbuf_free(mbuf);
     427                 :          0 :                                 rxq->saved_mbuf = NULL;
     428                 :          0 :                                 rxq->errors++;
     429                 :            :                                 eop = 0;
     430                 :          0 :                                 break;
     431                 :            :                         }
     432                 :            :                 } else {
     433                 :            :                         first_seg = mbuf;
     434                 :            :                 }
     435                 :            : 
     436                 :            :                 /* Get the RSS hash */
     437         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, RSV))
     438                 :          0 :                         first_seg->hash.rss =
     439                 :          0 :                                 rte_le_to_cpu_32(desc->write.desc1);
     440                 :          0 :                 etlt = AXGMAC_GET_BITS_LE(desc->write.desc3,
     441                 :            :                                 RX_NORMAL_DESC3, ETLT);
     442         [ #  # ]:          0 :                 if (!err || !etlt) {
     443         [ #  # ]:          0 :                         if (etlt == RX_CVLAN_TAG_PRESENT) {
     444                 :          0 :                                 first_seg->ol_flags |= RTE_MBUF_F_RX_VLAN;
     445                 :          0 :                                 first_seg->vlan_tci =
     446                 :          0 :                                         AXGMAC_GET_BITS_LE(desc->write.desc0,
     447                 :            :                                                         RX_NORMAL_DESC0, OVT);
     448         [ #  # ]:          0 :                                 if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
     449                 :          0 :                                         first_seg->ol_flags |=
     450                 :            :                                                 RTE_MBUF_F_RX_VLAN_STRIPPED;
     451                 :            :                                 else
     452                 :          0 :                                         first_seg->ol_flags &=
     453                 :            :                                                 ~RTE_MBUF_F_RX_VLAN_STRIPPED;
     454                 :            :                         } else {
     455                 :          0 :                                 first_seg->ol_flags &=
     456                 :            :                                         ~(RTE_MBUF_F_RX_VLAN |
     457                 :            :                                                         RTE_MBUF_F_RX_VLAN_STRIPPED);
     458                 :          0 :                                 first_seg->vlan_tci = 0;
     459                 :            :                         }
     460                 :            :                 }
     461                 :            : 
     462                 :          0 : err_set:
     463                 :          0 :                 rxq->cur++;
     464         [ #  # ]:          0 :                 rxq->sw_ring[idx] = tmbuf;
     465                 :          0 :                 desc->read.baddr =
     466                 :            :                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(tmbuf));
     467         [ #  # ]:          0 :                 memset((void *)(&desc->read.desc2), 0, 8);
     468                 :          0 :                 AXGMAC_SET_BITS_LE(desc->read.desc3, RX_NORMAL_DESC3, OWN, 1);
     469                 :            : 
     470         [ #  # ]:          0 :                 if (!eop)
     471                 :          0 :                         goto next_desc;
     472                 :            :                 eop = 0;
     473                 :            : 
     474                 :          0 :                 rxq->bytes += pkt_len;
     475                 :            : 
     476                 :          0 :                 first_seg->port = rxq->port_id;
     477         [ #  # ]:          0 :                 if (rxq->pdata->rx_csum_enable) {
     478                 :            :                         first_seg->ol_flags = 0;
     479                 :            :                         first_seg->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     480                 :          0 :                         first_seg->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     481         [ #  # ]:          0 :                         if (unlikely(error_status == AXGBE_L3_CSUM_ERR)) {
     482                 :            :                                 first_seg->ol_flags &=
     483                 :            :                                         ~RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     484                 :            :                                 first_seg->ol_flags |=
     485                 :            :                                         RTE_MBUF_F_RX_IP_CKSUM_BAD;
     486                 :          0 :                                 first_seg->ol_flags &=
     487                 :            :                                         ~RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     488                 :            :                                 first_seg->ol_flags |=
     489                 :            :                                         RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN;
     490         [ #  # ]:          0 :                         } else if (unlikely(error_status
     491                 :            :                                                 == AXGBE_L4_CSUM_ERR)) {
     492                 :            :                                 first_seg->ol_flags &=
     493                 :            :                                         ~RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     494                 :          0 :                                 first_seg->ol_flags |=
     495                 :            :                                         RTE_MBUF_F_RX_L4_CKSUM_BAD;
     496                 :            :                         }
     497                 :            :                 }
     498                 :            : 
     499                 :          0 :                 rx_pkts[nb_rx++] = first_seg;
     500                 :            : 
     501                 :            :                  /* Setup receipt context for a new packet.*/
     502                 :            :                 first_seg = NULL;
     503                 :            :         }
     504                 :            : 
     505                 :            :         /* Check if we need to save state before leaving */
     506         [ #  # ]:          0 :         if (first_seg != NULL && eop == 0)
     507                 :          0 :                 rxq->saved_mbuf = first_seg;
     508                 :            : 
     509                 :            :         /* Save receive context.*/
     510                 :          0 :         rxq->pkts += nb_rx;
     511                 :            : 
     512         [ #  # ]:          0 :         if (rxq->dirty != rxq->cur) {
     513                 :            :                 rte_wmb();
     514                 :          0 :                 idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur - 1);
     515                 :          0 :                 AXGMAC_DMA_IOWRITE(rxq, DMA_CH_RDTR_LO,
     516                 :            :                                    low32_value(rxq->ring_phys_addr +
     517                 :            :                                    (idx * sizeof(union axgbe_rx_desc))));
     518                 :          0 :                 rxq->dirty = rxq->cur;
     519                 :            :         }
     520                 :          0 :         return nb_rx;
     521                 :            : }
     522                 :            : 
     523                 :            : /* Tx Apis */
     524                 :          0 : static void axgbe_tx_queue_release(struct axgbe_tx_queue *tx_queue)
     525                 :            : {
     526                 :            :         uint16_t i;
     527                 :            :         struct rte_mbuf **sw_ring;
     528                 :            : 
     529         [ #  # ]:          0 :         if (tx_queue) {
     530                 :          0 :                 sw_ring = tx_queue->sw_ring;
     531         [ #  # ]:          0 :                 if (sw_ring) {
     532         [ #  # ]:          0 :                         for (i = 0; i < tx_queue->nb_desc; i++) {
     533                 :          0 :                                 rte_pktmbuf_free(sw_ring[i]);
     534                 :            :                         }
     535                 :          0 :                         rte_free(sw_ring);
     536                 :            :                 }
     537                 :          0 :                 rte_free(tx_queue);
     538                 :            :         }
     539                 :          0 : }
     540                 :            : 
     541                 :          0 : void axgbe_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t queue_idx)
     542                 :            : {
     543                 :          0 :         axgbe_tx_queue_release(dev->data->tx_queues[queue_idx]);
     544                 :          0 : }
     545                 :            : 
     546                 :          0 : int axgbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
     547                 :            :                              uint16_t nb_desc, unsigned int socket_id,
     548                 :            :                              const struct rte_eth_txconf *tx_conf)
     549                 :            : {
     550                 :            :         PMD_INIT_FUNC_TRACE();
     551                 :            :         uint32_t tx_desc;
     552                 :            :         struct axgbe_port *pdata;
     553                 :            :         struct axgbe_tx_queue *txq;
     554                 :            :         unsigned int tsize;
     555                 :            :         const struct rte_memzone *tz;
     556                 :            :         uint64_t offloads;
     557                 :          0 :         struct rte_eth_dev_data *dev_data = dev->data;
     558                 :            : 
     559                 :          0 :         tx_desc = nb_desc;
     560         [ #  # ]:          0 :         pdata = dev->data->dev_private;
     561                 :            : 
     562                 :            :         /*
     563                 :            :          * validate tx descriptors count
     564                 :            :          * should be power of 2 and less than h/w supported
     565                 :            :          */
     566                 :          0 :         if ((!rte_is_power_of_2(tx_desc)) ||
     567   [ #  #  #  # ]:          0 :             tx_desc > pdata->tx_desc_count ||
     568                 :            :             tx_desc < AXGBE_MIN_RING_DESC)
     569                 :            :                 return -EINVAL;
     570                 :            : 
     571                 :            :         /* First allocate the tx queue data structure */
     572                 :          0 :         txq = rte_zmalloc("ethdev TX queue", sizeof(struct axgbe_tx_queue),
     573                 :            :                           RTE_CACHE_LINE_SIZE);
     574         [ #  # ]:          0 :         if (!txq)
     575                 :            :                 return -ENOMEM;
     576                 :          0 :         txq->pdata = pdata;
     577                 :          0 :         offloads = tx_conf->offloads |
     578                 :          0 :                 dev->data->dev_conf.txmode.offloads;
     579                 :          0 :         txq->nb_desc = tx_desc;
     580         [ #  # ]:          0 :         txq->free_thresh = tx_conf->tx_free_thresh ?
     581                 :            :                 tx_conf->tx_free_thresh : AXGBE_TX_FREE_THRESH;
     582         [ #  # ]:          0 :         if (txq->free_thresh > txq->nb_desc)
     583                 :          0 :                 txq->free_thresh = (txq->nb_desc >> 1);
     584                 :          0 :         txq->free_batch_cnt = txq->free_thresh;
     585                 :            : 
     586                 :            :         /* In vector_tx path threshold should be multiple of queue_size*/
     587         [ #  # ]:          0 :         if (txq->nb_desc % txq->free_thresh != 0)
     588                 :          0 :                 txq->vector_disable = 1;
     589                 :            : 
     590         [ #  # ]:          0 :         if (offloads != 0)
     591                 :          0 :                 txq->vector_disable = 1;
     592                 :            : 
     593                 :            :         /* Allocate TX ring hardware descriptors */
     594                 :          0 :         tsize = txq->nb_desc * sizeof(struct axgbe_tx_desc);
     595                 :          0 :         tz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx,
     596                 :            :                                       tsize, AXGBE_DESC_ALIGN, socket_id);
     597         [ #  # ]:          0 :         if (!tz) {
     598                 :          0 :                 axgbe_tx_queue_release(txq);
     599                 :          0 :                 return -ENOMEM;
     600                 :            :         }
     601                 :          0 :         memset(tz->addr, 0, tsize);
     602                 :          0 :         txq->ring_phys_addr = (uint64_t)tz->iova;
     603                 :          0 :         txq->desc = tz->addr;
     604                 :          0 :         txq->queue_id = queue_idx;
     605                 :          0 :         txq->port_id = dev->data->port_id;
     606                 :          0 :         txq->offloads = offloads;
     607                 :          0 :         txq->dma_regs = (void *)((uint8_t *)pdata->xgmac_regs + DMA_CH_BASE +
     608                 :          0 :                 (DMA_CH_INC * txq->queue_id));
     609                 :          0 :         txq->dma_tail_reg = (volatile uint32_t *)((uint8_t *)txq->dma_regs +
     610                 :            :                                                   DMA_CH_TDTR_LO);
     611                 :          0 :         txq->cur = 0;
     612                 :          0 :         txq->dirty = 0;
     613                 :          0 :         txq->nb_desc_free = txq->nb_desc;
     614                 :            :         /* Allocate software ring */
     615                 :          0 :         tsize = txq->nb_desc * sizeof(struct rte_mbuf *);
     616                 :          0 :         txq->sw_ring = rte_zmalloc("tx_sw_ring", tsize,
     617                 :            :                                    RTE_CACHE_LINE_SIZE);
     618         [ #  # ]:          0 :         if (!txq->sw_ring) {
     619                 :          0 :                 axgbe_tx_queue_release(txq);
     620                 :          0 :                 return -ENOMEM;
     621                 :            :         }
     622                 :          0 :         dev->data->tx_queues[queue_idx] = txq;
     623         [ #  # ]:          0 :         if (!pdata->tx_queues)
     624                 :          0 :                 pdata->tx_queues = dev->data->tx_queues;
     625                 :            : 
     626         [ #  # ]:          0 :         if ((dev_data->dev_conf.txmode.offloads &
     627                 :            :                                 RTE_ETH_TX_OFFLOAD_MULTI_SEGS))
     628                 :          0 :                 pdata->multi_segs_tx = true;
     629                 :            : 
     630                 :            : 
     631                 :            :         return 0;
     632                 :            : }
     633                 :            : 
     634                 :          0 : int axgbe_dev_fw_version_get(struct rte_eth_dev *eth_dev,
     635                 :            :                 char *fw_version, size_t fw_size)
     636                 :            : {
     637                 :            :         struct axgbe_port *pdata;
     638                 :            :         struct axgbe_hw_features *hw_feat;
     639                 :            :         int ret;
     640                 :            : 
     641                 :          0 :         pdata = (struct axgbe_port *)eth_dev->data->dev_private;
     642                 :            :         hw_feat = &pdata->hw_feat;
     643                 :            : 
     644                 :          0 :         ret = snprintf(fw_version, fw_size, "%d.%d.%d",
     645                 :          0 :                         AXGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
     646                 :          0 :                         AXGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
     647         [ #  # ]:          0 :                         AXGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
     648         [ #  # ]:          0 :         if (ret < 0)
     649                 :            :                 return -EINVAL;
     650                 :            : 
     651                 :          0 :         ret += 1; /* add the size of '\0' */
     652         [ #  # ]:          0 :         if (fw_size < (size_t)ret)
     653                 :            :                 return ret;
     654                 :            :         else
     655                 :          0 :                 return 0;
     656                 :            : }
     657                 :            : 
     658                 :          0 : static void axgbe_txq_prepare_tx_stop(struct axgbe_port *pdata,
     659                 :            :                                       unsigned int queue)
     660                 :            : {
     661                 :            :         unsigned int tx_status;
     662                 :            :         unsigned long tx_timeout;
     663                 :            : 
     664                 :            :         /* The Tx engine cannot be stopped if it is actively processing
     665                 :            :          * packets. Wait for the Tx queue to empty the Tx fifo.  Don't
     666                 :            :          * wait forever though...
     667                 :            :          */
     668                 :          0 :         tx_timeout = rte_get_timer_cycles() + (AXGBE_DMA_STOP_TIMEOUT *
     669                 :            :                                                rte_get_timer_hz());
     670         [ #  # ]:          0 :         while (time_before(rte_get_timer_cycles(), tx_timeout)) {
     671                 :          0 :                 tx_status = AXGMAC_MTL_IOREAD(pdata, queue, MTL_Q_TQDR);
     672         [ #  # ]:          0 :                 if ((AXGMAC_GET_BITS(tx_status, MTL_Q_TQDR, TRCSTS) != 1) &&
     673         [ #  # ]:          0 :                     (AXGMAC_GET_BITS(tx_status, MTL_Q_TQDR, TXQSTS) == 0))
     674                 :            :                         break;
     675                 :            : 
     676                 :          0 :                 rte_delay_us(900);
     677                 :            :         }
     678                 :            : 
     679         [ #  # ]:          0 :         if (!time_before(rte_get_timer_cycles(), tx_timeout))
     680                 :          0 :                 PMD_DRV_LOG_LINE(ERR,
     681                 :            :                             "timed out waiting for Tx queue %u to empty",
     682                 :            :                             queue);
     683                 :          0 : }
     684                 :            : 
     685                 :          0 : static void axgbe_prepare_tx_stop(struct axgbe_port *pdata,
     686                 :            :                                   unsigned int queue)
     687                 :            : {
     688                 :            :         unsigned int tx_dsr, tx_pos, tx_qidx;
     689                 :            :         unsigned int tx_status;
     690                 :            :         unsigned long tx_timeout;
     691                 :            : 
     692         [ #  # ]:          0 :         if (AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) > 0x20)
     693                 :          0 :                 return axgbe_txq_prepare_tx_stop(pdata, queue);
     694                 :            : 
     695                 :            :         /* Calculate the status register to read and the position within */
     696         [ #  # ]:          0 :         if (queue < DMA_DSRX_FIRST_QUEUE) {
     697                 :            :                 tx_dsr = DMA_DSR0;
     698                 :          0 :                 tx_pos = (queue * DMA_DSR_Q_WIDTH) + DMA_DSR0_TPS_START;
     699                 :            :         } else {
     700                 :          0 :                 tx_qidx = queue - DMA_DSRX_FIRST_QUEUE;
     701                 :            : 
     702                 :          0 :                 tx_dsr = DMA_DSR1 + ((tx_qidx / DMA_DSRX_QPR) * DMA_DSRX_INC);
     703                 :          0 :                 tx_pos = ((tx_qidx % DMA_DSRX_QPR) * DMA_DSR_Q_WIDTH) +
     704                 :            :                         DMA_DSRX_TPS_START;
     705                 :            :         }
     706                 :            : 
     707                 :            :         /* The Tx engine cannot be stopped if it is actively processing
     708                 :            :          * descriptors. Wait for the Tx engine to enter the stopped or
     709                 :            :          * suspended state.  Don't wait forever though...
     710                 :            :          */
     711                 :          0 :         tx_timeout = rte_get_timer_cycles() + (AXGBE_DMA_STOP_TIMEOUT *
     712                 :            :                                                rte_get_timer_hz());
     713         [ #  # ]:          0 :         while (time_before(rte_get_timer_cycles(), tx_timeout)) {
     714                 :          0 :                 tx_status = AXGMAC_IOREAD(pdata, tx_dsr);
     715                 :          0 :                 tx_status = GET_BITS(tx_status, tx_pos, DMA_DSR_TPS_WIDTH);
     716                 :          0 :                 if ((tx_status == DMA_TPS_STOPPED) ||
     717         [ #  # ]:          0 :                     (tx_status == DMA_TPS_SUSPENDED))
     718                 :            :                         break;
     719                 :            : 
     720                 :          0 :                 rte_delay_us(900);
     721                 :            :         }
     722                 :            : 
     723         [ #  # ]:          0 :         if (!time_before(rte_get_timer_cycles(), tx_timeout))
     724                 :          0 :                 PMD_DRV_LOG_LINE(ERR,
     725                 :            :                             "timed out waiting for Tx DMA channel %u to stop",
     726                 :            :                             queue);
     727                 :            : }
     728                 :            : 
     729                 :          0 : void axgbe_dev_disable_tx(struct rte_eth_dev *dev)
     730                 :            : {
     731                 :            :         struct axgbe_tx_queue *txq;
     732                 :          0 :         struct axgbe_port *pdata = dev->data->dev_private;
     733                 :            :         unsigned int i;
     734                 :            : 
     735                 :            :         /* Prepare for stopping DMA channel */
     736         [ #  # ]:          0 :         for (i = 0; i < pdata->tx_q_count; i++) {
     737                 :            :                 txq = dev->data->tx_queues[i];
     738                 :          0 :                 axgbe_prepare_tx_stop(pdata, i);
     739                 :            :         }
     740                 :            :         /* Disable MAC Tx */
     741                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
     742                 :            :         /* Disable each Tx queue*/
     743         [ #  # ]:          0 :         for (i = 0; i < pdata->tx_q_count; i++)
     744                 :          0 :                 AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN,
     745                 :            :                                         0);
     746                 :            :         /* Disable each  Tx DMA channel */
     747         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     748                 :          0 :                 txq = dev->data->tx_queues[i];
     749                 :          0 :                 AXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, ST, 0);
     750                 :            :         }
     751                 :          0 : }
     752                 :            : 
     753                 :          0 : void axgbe_dev_enable_tx(struct rte_eth_dev *dev)
     754                 :            : {
     755                 :            :         struct axgbe_tx_queue *txq;
     756                 :          0 :         struct axgbe_port *pdata = dev->data->dev_private;
     757                 :            :         unsigned int i;
     758                 :            : 
     759         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     760                 :          0 :                 txq = dev->data->tx_queues[i];
     761                 :            :                 /* Enable Tx DMA channel */
     762                 :          0 :                 AXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, ST, 1);
     763                 :            :         }
     764                 :            :         /* Enable Tx queue*/
     765         [ #  # ]:          0 :         for (i = 0; i < pdata->tx_q_count; i++)
     766                 :          0 :                 AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN,
     767                 :            :                                         MTL_Q_ENABLED);
     768                 :            :         /* Enable MAC Tx */
     769                 :          0 :         AXGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1);
     770                 :          0 : }
     771                 :            : 
     772                 :            : /* Free Tx conformed mbufs segments */
     773                 :            : static void
     774                 :          0 : axgbe_xmit_cleanup_seg(struct axgbe_tx_queue *txq)
     775                 :            : {
     776                 :            :         volatile struct axgbe_tx_desc *desc;
     777                 :            :         uint16_t idx;
     778                 :            : 
     779                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->dirty);
     780         [ #  # ]:          0 :         while (txq->cur != txq->dirty) {
     781         [ #  # ]:          0 :                 if (unlikely(idx == txq->nb_desc))
     782                 :            :                         idx = 0;
     783                 :          0 :                 desc = &txq->desc[idx];
     784                 :            :                 /* Check for ownership */
     785         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN))
     786                 :            :                         return;
     787                 :          0 :                 memset((void *)&desc->desc2, 0, 8);
     788                 :            :                 /* Free mbuf */
     789                 :          0 :                 rte_pktmbuf_free_seg(txq->sw_ring[idx]);
     790                 :          0 :                 txq->sw_ring[idx++] = NULL;
     791                 :          0 :                 txq->dirty++;
     792                 :            :         }
     793                 :            : }
     794                 :            : 
     795                 :            : /* Free Tx conformed mbufs */
     796                 :          0 : static void axgbe_xmit_cleanup(struct axgbe_tx_queue *txq)
     797                 :            : {
     798                 :            :         volatile struct axgbe_tx_desc *desc;
     799                 :            :         uint16_t idx;
     800                 :            : 
     801                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->dirty);
     802         [ #  # ]:          0 :         while (txq->cur != txq->dirty) {
     803         [ #  # ]:          0 :                 if (unlikely(idx == txq->nb_desc))
     804                 :            :                         idx = 0;
     805                 :          0 :                 desc = &txq->desc[idx];
     806                 :            :                 /* Check for ownership */
     807         [ #  # ]:          0 :                 if (AXGMAC_GET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN))
     808                 :            :                         return;
     809                 :          0 :                 memset((void *)&desc->desc2, 0, 8);
     810                 :            :                 /* Free mbuf */
     811                 :          0 :                 rte_pktmbuf_free(txq->sw_ring[idx]);
     812                 :          0 :                 txq->sw_ring[idx++] = NULL;
     813                 :          0 :                 txq->dirty++;
     814                 :            :         }
     815                 :            : }
     816                 :            : 
     817                 :            : /* Tx Descriptor formation
     818                 :            :  * Considering each mbuf requires one desc
     819                 :            :  * mbuf is linear
     820                 :            :  */
     821                 :          0 : static int axgbe_xmit_hw(struct axgbe_tx_queue *txq,
     822                 :            :                          struct rte_mbuf *mbuf)
     823                 :            : {
     824                 :            :         volatile struct axgbe_tx_desc *desc;
     825                 :            :         uint16_t idx;
     826                 :            :         uint64_t mask;
     827                 :            : 
     828                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->cur);
     829         [ #  # ]:          0 :         desc = &txq->desc[idx];
     830                 :            : 
     831                 :            :         /* Update buffer address  and length */
     832                 :          0 :         desc->baddr = rte_mbuf_data_iova(mbuf);
     833                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, HL_B1L,
     834                 :            :                            mbuf->pkt_len);
     835                 :            :         /* Total msg length to transmit */
     836                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, FL,
     837                 :            :                            mbuf->pkt_len);
     838                 :            :         /* Timestamp enablement check */
     839         [ #  # ]:          0 :         if (mbuf->ol_flags & RTE_MBUF_F_TX_IEEE1588_TMST)
     840                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, TTSE, 1);
     841                 :            :         rte_wmb();
     842                 :            :         /* Mark it as First and Last Descriptor */
     843                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, FD, 1);
     844                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, LD, 1);
     845                 :            :         /* Mark it as a NORMAL descriptor */
     846                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CTXT, 0);
     847                 :            :         /* configure h/w Offload */
     848                 :          0 :         mask = mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK;
     849         [ #  # ]:          0 :         if (mask == RTE_MBUF_F_TX_TCP_CKSUM || mask == RTE_MBUF_F_TX_UDP_CKSUM)
     850                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CIC, 0x3);
     851         [ #  # ]:          0 :         else if (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
     852                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CIC, 0x1);
     853                 :            :         rte_wmb();
     854                 :            : 
     855         [ #  # ]:          0 :         if (mbuf->ol_flags & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
     856                 :            :                 /* Mark it as a CONTEXT descriptor */
     857                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
     858                 :            :                                   CTXT, 1);
     859                 :            :                 /* Set the VLAN tag */
     860                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
     861                 :            :                                   VT, mbuf->vlan_tci);
     862                 :            :                 /* Indicate this descriptor contains the VLAN tag */
     863                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
     864                 :            :                                           VLTV, 1);
     865                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR,
     866                 :            :                                 TX_NORMAL_DESC2_VLAN_INSERT);
     867                 :            :         } else {
     868                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR, 0x0);
     869                 :            :         }
     870                 :            :         rte_wmb();
     871                 :            : 
     872                 :            :         /* Set OWN bit */
     873                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN, 1);
     874                 :            :         rte_wmb();
     875                 :            : 
     876                 :            : 
     877                 :            :         /* Save mbuf */
     878                 :          0 :         txq->sw_ring[idx] = mbuf;
     879                 :            :         /* Update current index*/
     880                 :          0 :         txq->cur++;
     881                 :            :         /* Update stats */
     882                 :          0 :         txq->bytes += mbuf->pkt_len;
     883                 :            : 
     884                 :          0 :         return 0;
     885                 :            : }
     886                 :            : 
     887                 :            : /* Tx Descriptor formation for segmented mbuf
     888                 :            :  * Each mbuf will require multiple descriptors
     889                 :            :  */
     890                 :            : 
     891                 :            : static int
     892                 :          0 : axgbe_xmit_hw_seg(struct axgbe_tx_queue *txq,
     893                 :            :                 struct rte_mbuf *mbuf)
     894                 :            : {
     895                 :            :         volatile struct axgbe_tx_desc *desc;
     896                 :            :         uint16_t idx;
     897                 :            :         uint64_t mask;
     898                 :            :         int start_index;
     899                 :            :         uint32_t pkt_len = 0;
     900                 :            :         int nb_desc_free;
     901                 :            :         struct rte_mbuf  *tx_pkt;
     902                 :            : 
     903                 :          0 :         nb_desc_free = txq->nb_desc - (txq->cur - txq->dirty);
     904                 :            : 
     905         [ #  # ]:          0 :         if (mbuf->nb_segs > nb_desc_free) {
     906                 :          0 :                 axgbe_xmit_cleanup_seg(txq);
     907                 :          0 :                 nb_desc_free = txq->nb_desc - (txq->cur - txq->dirty);
     908         [ #  # ]:          0 :                 if (unlikely(mbuf->nb_segs > nb_desc_free))
     909                 :            :                         return RTE_ETH_TX_DESC_UNAVAIL;
     910                 :            :         }
     911                 :            : 
     912                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->cur);
     913                 :          0 :         desc = &txq->desc[idx];
     914                 :            :         /* Saving the start index for setting the OWN bit finally */
     915                 :            :         start_index = idx;
     916                 :            : 
     917                 :            :         tx_pkt = mbuf;
     918                 :            :         /* Max_pkt len = 9018 ; need to update it according to Jumbo pkt size */
     919         [ #  # ]:          0 :         pkt_len = tx_pkt->pkt_len;
     920                 :            : 
     921                 :            :         /* Update buffer address  and length */
     922                 :          0 :         desc->baddr = rte_mbuf_data_iova(tx_pkt);
     923                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, HL_B1L,
     924                 :            :                                            tx_pkt->data_len);
     925                 :            :         /* Total msg length to transmit */
     926                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, FL,
     927                 :            :                                            tx_pkt->pkt_len);
     928                 :            :         /* Timestamp enablement check */
     929         [ #  # ]:          0 :         if (mbuf->ol_flags & RTE_MBUF_F_TX_IEEE1588_TMST)
     930                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, TTSE, 1);
     931                 :            : 
     932                 :            :         rte_wmb();
     933                 :            :         /* Mark it as First Descriptor */
     934                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, FD, 1);
     935                 :            :         /* Mark it as a NORMAL descriptor */
     936                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CTXT, 0);
     937                 :            :         /* configure h/w Offload */
     938                 :          0 :         mask = mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK;
     939         [ #  # ]:          0 :         if (mask == RTE_MBUF_F_TX_TCP_CKSUM || mask == RTE_MBUF_F_TX_UDP_CKSUM)
     940                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CIC, 0x3);
     941         [ #  # ]:          0 :         else if (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
     942                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CIC, 0x1);
     943                 :            :         rte_wmb();
     944                 :            : 
     945         [ #  # ]:          0 :         if (mbuf->ol_flags & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
     946                 :            :                 /* Mark it as a CONTEXT descriptor */
     947                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
     948                 :            :                                 CTXT, 1);
     949                 :            :                 /* Set the VLAN tag */
     950                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
     951                 :            :                                 VT, mbuf->vlan_tci);
     952                 :            :                 /* Indicate this descriptor contains the VLAN tag */
     953                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
     954                 :            :                                 VLTV, 1);
     955                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR,
     956                 :            :                                 TX_NORMAL_DESC2_VLAN_INSERT);
     957                 :            :         } else {
     958                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR, 0x0);
     959                 :            :         }
     960                 :            :         rte_wmb();
     961                 :            : 
     962                 :            :         /* Save mbuf */
     963                 :          0 :         txq->sw_ring[idx] = tx_pkt;
     964                 :            :         /* Update current index*/
     965                 :          0 :         txq->cur++;
     966                 :            : 
     967                 :          0 :         tx_pkt = tx_pkt->next;
     968                 :            : 
     969         [ #  # ]:          0 :         while (tx_pkt != NULL) {
     970                 :          0 :                 idx = AXGBE_GET_DESC_IDX(txq, txq->cur);
     971                 :          0 :                 desc = &txq->desc[idx];
     972                 :            : 
     973                 :            :                 /* Update buffer address  and length */
     974                 :          0 :                 desc->baddr = rte_mbuf_data_iova(tx_pkt);
     975                 :            : 
     976                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc2,
     977                 :            :                                 TX_NORMAL_DESC2, HL_B1L, tx_pkt->data_len);
     978                 :            : 
     979                 :            :                 rte_wmb();
     980                 :            : 
     981                 :            :                 /* Mark it as a NORMAL descriptor */
     982                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CTXT, 0);
     983                 :            :                 /* configure h/w Offload */
     984                 :          0 :                 mask = mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK;
     985                 :          0 :                 if (mask == RTE_MBUF_F_TX_TCP_CKSUM ||
     986         [ #  # ]:          0 :                                 mask == RTE_MBUF_F_TX_UDP_CKSUM)
     987                 :          0 :                         AXGMAC_SET_BITS_LE(desc->desc3,
     988                 :            :                                         TX_NORMAL_DESC3, CIC, 0x3);
     989         [ #  # ]:          0 :                 else if (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
     990                 :          0 :                         AXGMAC_SET_BITS_LE(desc->desc3,
     991                 :            :                                         TX_NORMAL_DESC3, CIC, 0x1);
     992                 :            : 
     993                 :            :                 rte_wmb();
     994                 :            : 
     995                 :            :                  /* Set OWN bit */
     996                 :          0 :                 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN, 1);
     997                 :            :                 rte_wmb();
     998                 :            : 
     999                 :            :                 /* Save mbuf */
    1000                 :          0 :                 txq->sw_ring[idx] = tx_pkt;
    1001                 :            :                 /* Update current index*/
    1002                 :          0 :                 txq->cur++;
    1003                 :            : 
    1004                 :          0 :                 tx_pkt = tx_pkt->next;
    1005                 :            :         }
    1006                 :            : 
    1007                 :            :         /* Set LD bit for the last descriptor */
    1008                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, LD, 1);
    1009                 :            :         rte_wmb();
    1010                 :            : 
    1011                 :            :         /* Update stats */
    1012                 :          0 :         txq->bytes += pkt_len;
    1013                 :            : 
    1014                 :            :         /* Set OWN bit for the first descriptor */
    1015                 :          0 :         desc = &txq->desc[start_index];
    1016                 :          0 :         AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN, 1);
    1017                 :            :         rte_wmb();
    1018                 :            : 
    1019                 :          0 :         return 0;
    1020                 :            : }
    1021                 :            : 
    1022                 :            : /* Eal supported tx wrapper- Segmented*/
    1023                 :            : uint16_t
    1024                 :          0 : axgbe_xmit_pkts_seg(void *tx_queue, struct rte_mbuf **tx_pkts,
    1025                 :            :                 uint16_t nb_pkts)
    1026                 :            : {
    1027                 :            :         PMD_INIT_FUNC_TRACE();
    1028                 :            : 
    1029                 :            :         struct axgbe_tx_queue *txq;
    1030                 :            :         uint16_t nb_desc_free;
    1031                 :            :         uint16_t nb_pkt_sent = 0;
    1032                 :            :         uint16_t idx;
    1033                 :            :         uint32_t tail_addr;
    1034                 :            :         struct rte_mbuf *mbuf = NULL;
    1035                 :            : 
    1036         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0))
    1037                 :            :                 return nb_pkts;
    1038                 :            : 
    1039                 :            :         txq = (struct axgbe_tx_queue *)tx_queue;
    1040                 :            : 
    1041                 :          0 :         nb_desc_free = txq->nb_desc - (txq->cur - txq->dirty);
    1042         [ #  # ]:          0 :         if (unlikely(nb_desc_free <= txq->free_thresh)) {
    1043                 :          0 :                 axgbe_xmit_cleanup_seg(txq);
    1044                 :          0 :                 nb_desc_free = txq->nb_desc - (txq->cur - txq->dirty);
    1045         [ #  # ]:          0 :                 if (unlikely(nb_desc_free == 0))
    1046                 :            :                         return 0;
    1047                 :            :         }
    1048                 :            : 
    1049         [ #  # ]:          0 :         while (nb_pkts--) {
    1050                 :          0 :                 mbuf = *tx_pkts++;
    1051                 :            : 
    1052         [ #  # ]:          0 :                 if (axgbe_xmit_hw_seg(txq, mbuf))
    1053                 :          0 :                         goto out;
    1054                 :          0 :                 nb_pkt_sent++;
    1055                 :            :         }
    1056                 :          0 : out:
    1057                 :            :         /* Sync read and write */
    1058                 :            :         rte_mb();
    1059                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->cur);
    1060                 :          0 :         tail_addr = low32_value(txq->ring_phys_addr +
    1061                 :          0 :                                 idx * sizeof(struct axgbe_tx_desc));
    1062                 :            :         /* Update tail reg with next immediate address to kick Tx DMA channel*/
    1063                 :          0 :         AXGMAC_DMA_IOWRITE(txq, DMA_CH_TDTR_LO, tail_addr);
    1064                 :          0 :         txq->pkts += nb_pkt_sent;
    1065                 :          0 :         return nb_pkt_sent;
    1066                 :            : }
    1067                 :            : 
    1068                 :            : /* Eal supported tx wrapper*/
    1069                 :            : uint16_t
    1070                 :          0 : axgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
    1071                 :            :                 uint16_t nb_pkts)
    1072                 :            : {
    1073                 :            :         PMD_INIT_FUNC_TRACE();
    1074                 :            : 
    1075         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0))
    1076                 :            :                 return nb_pkts;
    1077                 :            : 
    1078                 :            :         struct axgbe_tx_queue *txq;
    1079                 :            :         uint16_t nb_desc_free;
    1080                 :            :         uint16_t nb_pkt_sent = 0;
    1081                 :            :         uint16_t idx;
    1082                 :            :         uint32_t tail_addr;
    1083                 :            :         struct rte_mbuf *mbuf;
    1084                 :            : 
    1085                 :            :         txq  = (struct axgbe_tx_queue *)tx_queue;
    1086                 :          0 :         nb_desc_free = txq->nb_desc - (txq->cur - txq->dirty);
    1087                 :            : 
    1088         [ #  # ]:          0 :         if (unlikely(nb_desc_free <= txq->free_thresh)) {
    1089                 :          0 :                 axgbe_xmit_cleanup(txq);
    1090                 :          0 :                 nb_desc_free = txq->nb_desc - (txq->cur - txq->dirty);
    1091         [ #  # ]:          0 :                 if (unlikely(nb_desc_free == 0))
    1092                 :            :                         return 0;
    1093                 :            :         }
    1094                 :          0 :         nb_pkts = RTE_MIN(nb_desc_free, nb_pkts);
    1095         [ #  # ]:          0 :         while (nb_pkts--) {
    1096                 :          0 :                 mbuf = *tx_pkts++;
    1097         [ #  # ]:          0 :                 if (axgbe_xmit_hw(txq, mbuf))
    1098                 :          0 :                         goto out;
    1099                 :          0 :                 nb_pkt_sent++;
    1100                 :            :         }
    1101                 :          0 : out:
    1102                 :            :         /* Sync read and write */
    1103                 :            :         rte_mb();
    1104                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->cur);
    1105                 :          0 :         tail_addr = low32_value(txq->ring_phys_addr +
    1106                 :          0 :                                 idx * sizeof(struct axgbe_tx_desc));
    1107                 :            :         /* Update tail reg with next immediate address to kick Tx DMA channel*/
    1108                 :          0 :         AXGMAC_DMA_IOWRITE(txq, DMA_CH_TDTR_LO, tail_addr);
    1109                 :          0 :         txq->pkts += nb_pkt_sent;
    1110                 :          0 :         return nb_pkt_sent;
    1111                 :            : }
    1112                 :            : 
    1113                 :          0 : void axgbe_dev_clear_queues(struct rte_eth_dev *dev)
    1114                 :            : {
    1115                 :            :         PMD_INIT_FUNC_TRACE();
    1116                 :            :         uint8_t i;
    1117                 :            :         struct axgbe_rx_queue *rxq;
    1118                 :            :         struct axgbe_tx_queue *txq;
    1119                 :            : 
    1120         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
    1121                 :          0 :                 rxq = dev->data->rx_queues[i];
    1122                 :            : 
    1123         [ #  # ]:          0 :                 if (rxq) {
    1124                 :          0 :                         axgbe_rx_queue_release(rxq);
    1125                 :          0 :                         dev->data->rx_queues[i] = NULL;
    1126                 :            :                 }
    1127                 :          0 :                 dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
    1128                 :            :         }
    1129                 :            : 
    1130         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
    1131                 :          0 :                 txq = dev->data->tx_queues[i];
    1132                 :            : 
    1133         [ #  # ]:          0 :                 if (txq) {
    1134                 :          0 :                         axgbe_tx_queue_release(txq);
    1135                 :          0 :                         dev->data->tx_queues[i] = NULL;
    1136                 :            :                 }
    1137                 :          0 :                 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
    1138                 :            :         }
    1139                 :          0 : }
    1140                 :            : 
    1141                 :            : int
    1142                 :          0 : axgbe_dev_rx_descriptor_status(void *rx_queue, uint16_t offset)
    1143                 :            : {
    1144                 :            :         struct axgbe_rx_queue *rxq = rx_queue;
    1145                 :            :         volatile union axgbe_rx_desc *desc;
    1146                 :            :         uint16_t idx;
    1147                 :            : 
    1148                 :            : 
    1149         [ #  # ]:          0 :         if (unlikely(offset >= rxq->nb_desc))
    1150                 :            :                 return -EINVAL;
    1151                 :            : 
    1152         [ #  # ]:          0 :         if (offset >= rxq->nb_desc - rxq->dirty)
    1153                 :            :                 return RTE_ETH_RX_DESC_UNAVAIL;
    1154                 :            : 
    1155                 :          0 :         idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur);
    1156                 :          0 :         desc = &rxq->desc[idx + offset];
    1157                 :            : 
    1158         [ #  # ]:          0 :         if (!AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, OWN))
    1159                 :          0 :                 return RTE_ETH_RX_DESC_DONE;
    1160                 :            : 
    1161                 :            :         return RTE_ETH_RX_DESC_AVAIL;
    1162                 :            : }
    1163                 :            : 
    1164                 :            : int
    1165                 :          0 : axgbe_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
    1166                 :            : {
    1167                 :            :         struct axgbe_tx_queue *txq = tx_queue;
    1168                 :            :         volatile struct axgbe_tx_desc *desc;
    1169                 :            :         uint16_t idx;
    1170                 :            : 
    1171                 :            : 
    1172         [ #  # ]:          0 :         if (unlikely(offset >= txq->nb_desc))
    1173                 :            :                 return -EINVAL;
    1174                 :            : 
    1175         [ #  # ]:          0 :         if (offset >= txq->nb_desc - txq->dirty)
    1176                 :            :                 return RTE_ETH_TX_DESC_UNAVAIL;
    1177                 :            : 
    1178                 :          0 :         idx = AXGBE_GET_DESC_IDX(txq, txq->dirty + txq->free_batch_cnt - 1);
    1179                 :          0 :         desc = &txq->desc[idx + offset];
    1180                 :            : 
    1181         [ #  # ]:          0 :         if (!AXGMAC_GET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN))
    1182                 :          0 :                 return RTE_ETH_TX_DESC_DONE;
    1183                 :            : 
    1184                 :            :         return RTE_ETH_TX_DESC_FULL;
    1185                 :            : }

Generated by: LCOV version 1.14