LCOV - code coverage report
Current view: top level - drivers/net/enetfec - enet_rxtx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 87 0.0 %
Date: 2025-11-01 17:50:34 Functions: 0 2 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 58 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2021-2024 NXP
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_mbuf.h>
       6                 :            : #include <rte_io.h>
       7                 :            : #include <ethdev_driver.h>
       8                 :            : #include "enet_regs.h"
       9                 :            : #include "enet_ethdev.h"
      10                 :            : #include "enet_pmd_logs.h"
      11                 :            : 
      12                 :            : /* This function does enetfec_rx_queue processing. Dequeue packet from Rx queue
      13                 :            :  * When update through the ring, just set the empty indicator.
      14                 :            :  */
      15                 :            : uint16_t
      16                 :          0 : enetfec_recv_pkts(void *rxq1, struct rte_mbuf **rx_pkts,
      17                 :            :                 uint16_t nb_pkts)
      18                 :            : {
      19                 :            :         struct rte_mempool *pool;
      20                 :            :         struct rte_mbuf *mbuf, *new_mbuf = NULL;
      21                 :            :         unsigned short status;
      22                 :            :         unsigned short pkt_len;
      23                 :            :         int pkt_received = 0, index = 0;
      24                 :            :         struct rte_ether_hdr *eth;
      25                 :            :         void *data, *mbuf_data;
      26                 :            :         struct bufdesc *bdp;
      27                 :            :         uint16_t vlan_tag;
      28                 :            :         struct  bufdesc_ex *ebdp = NULL;
      29                 :            :         bool    vlan_packet_rcvd = false;
      30                 :            :         struct enetfec_priv_rx_q *rxq  = (struct enetfec_priv_rx_q *)rxq1;
      31                 :          0 :         struct rte_eth_stats *stats = &rxq->fep->stats;
      32                 :          0 :         struct rte_eth_conf *eth_conf = &rxq->fep->dev->data->dev_conf;
      33                 :          0 :         uint64_t rx_offloads = eth_conf->rxmode.offloads;
      34                 :          0 :         pool = rxq->pool;
      35                 :          0 :         bdp = rxq->bd.cur;
      36                 :            : 
      37                 :            :         /* Process the incoming packet */
      38                 :            :         status = rte_le_to_cpu_16(rte_read16(&bdp->bd_sc));
      39         [ #  # ]:          0 :         while ((status & RX_BD_EMPTY) == 0) {
      40         [ #  # ]:          0 :                 if (pkt_received >= nb_pkts)
      41                 :            :                         break;
      42                 :            : 
      43                 :            :                 /* Check for errors. */
      44                 :          0 :                 status ^= RX_BD_LAST;
      45         [ #  # ]:          0 :                 if (status & (RX_BD_LG | RX_BD_SH | RX_BD_NO |
      46                 :            :                         RX_BD_CR | RX_BD_OV | RX_BD_LAST |
      47                 :            :                         RX_BD_TR)) {
      48                 :          0 :                         stats->ierrors++;
      49         [ #  # ]:          0 :                         if (status & RX_BD_OV) {
      50                 :            :                                 /* FIFO overrun */
      51                 :            :                                 /* enet_dump_rx(rxq); */
      52                 :            :                                 ENETFEC_DP_LOG(DEBUG, "rx_fifo_error");
      53                 :          0 :                                 goto rx_processing_done;
      54                 :            :                         }
      55                 :            :                         if (status & (RX_BD_LG | RX_BD_SH
      56                 :            :                                                 | RX_BD_LAST)) {
      57                 :            :                                 /* Frame too long or too short. */
      58                 :            :                                 ENETFEC_DP_LOG(DEBUG, "rx_length_error");
      59                 :            :                                 if (status & RX_BD_LAST)
      60                 :            :                                         ENETFEC_DP_LOG(DEBUG, "rcv is not +last");
      61                 :            :                         }
      62                 :            :                         if (status & RX_BD_CR) {     /* CRC Error */
      63                 :            :                                 ENETFEC_DP_LOG(DEBUG, "rx_crc_errors");
      64                 :            :                         }
      65                 :            :                         /* Report late collisions as a frame error. */
      66                 :            :                         if (status & (RX_BD_NO | RX_BD_TR))
      67                 :            :                                 ENETFEC_DP_LOG(DEBUG, "rx_frame_error");
      68                 :          0 :                         goto rx_processing_done;
      69                 :            :                 }
      70                 :            : 
      71                 :          0 :                 new_mbuf = rte_pktmbuf_alloc(pool);
      72         [ #  # ]:          0 :                 if (unlikely(new_mbuf == NULL)) {
      73                 :          0 :                         stats->rx_nombuf++;
      74                 :          0 :                         break;
      75                 :            :                 }
      76                 :            : 
      77                 :            :                 /* Process the incoming frame. */
      78                 :          0 :                 stats->ipackets++;
      79                 :            :                 pkt_len = rte_le_to_cpu_16(rte_read16(&bdp->bd_datlen));
      80                 :          0 :                 stats->ibytes += pkt_len;
      81                 :            : 
      82                 :            :                 /* shows data with respect to the data_off field. */
      83                 :            :                 index = enet_get_bd_index(bdp, &rxq->bd);
      84                 :          0 :                 mbuf = rxq->rx_mbuf[index];
      85                 :            : 
      86                 :          0 :                 data = rte_pktmbuf_mtod(mbuf, uint8_t *);
      87                 :            :                 mbuf_data = data;
      88                 :            :                 rte_prefetch0(data);
      89                 :            :                 rte_pktmbuf_append((struct rte_mbuf *)mbuf,
      90                 :          0 :                                 pkt_len - 4);
      91                 :            : 
      92         [ #  # ]:          0 :                 if (rxq->fep->quirks & QUIRK_RACC)
      93                 :            :                         data = rte_pktmbuf_adj(mbuf, 2);
      94                 :            : 
      95                 :          0 :                 rx_pkts[pkt_received] = mbuf;
      96                 :            : 
      97                 :            :                 /* Assuming Ethernet packets, doing software packet type parsing.
      98                 :            :                  * To be replaced by HW packet parsing
      99                 :            :                  */
     100                 :          0 :                 eth = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *);
     101                 :          0 :                 mbuf->packet_type = RTE_PTYPE_L2_ETHER;
     102   [ #  #  #  # ]:          0 :                 if (rte_be_to_cpu_16(eth->ether_type) == RTE_ETHER_TYPE_IPV4)
     103                 :          0 :                         mbuf->packet_type |= RTE_PTYPE_L3_IPV4;
     104   [ #  #  #  # ]:          0 :                 if (rte_be_to_cpu_16(eth->ether_type) == RTE_ETHER_TYPE_IPV6)
     105                 :          0 :                         mbuf->packet_type |= RTE_PTYPE_L3_IPV6;
     106                 :          0 :                 pkt_received++;
     107                 :            : 
     108                 :            :                 /* Extract the enhanced buffer descriptor */
     109                 :            :                 ebdp = NULL;
     110         [ #  # ]:          0 :                 if (rxq->fep->bufdesc_ex)
     111                 :            :                         ebdp = (struct bufdesc_ex *)bdp;
     112                 :            : 
     113                 :            :                 /* If this is a VLAN packet remove the VLAN Tag */
     114                 :            :                 vlan_packet_rcvd = false;
     115   [ #  #  #  # ]:          0 :                 if ((rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN) &&
     116                 :          0 :                                 rxq->fep->bufdesc_ex &&
     117         [ #  # ]:          0 :                                 (rte_read32(&ebdp->bd_esc) &
     118                 :            :                                 rte_cpu_to_le_32(BD_ENETFEC_RX_VLAN))) {
     119                 :            :                         /* Push and remove the vlan tag */
     120                 :            :                         struct rte_vlan_hdr *vlan_header =
     121                 :            :                                 (struct rte_vlan_hdr *)
     122                 :            :                                 ((uint8_t *)data + ETH_HLEN);
     123         [ #  # ]:          0 :                         vlan_tag = rte_be_to_cpu_16(vlan_header->vlan_tci);
     124                 :            : 
     125                 :            :                         vlan_packet_rcvd = true;
     126         [ #  # ]:          0 :                         memmove((uint8_t *)mbuf_data + RTE_VLAN_HLEN,
     127                 :            :                                 data, RTE_ETHER_ADDR_LEN * 2);
     128                 :            :                         rte_pktmbuf_adj(mbuf, RTE_VLAN_HLEN);
     129                 :            :                 }
     130                 :            : 
     131         [ #  # ]:          0 :                 if (rxq->fep->bufdesc_ex &&
     132         [ #  # ]:          0 :                         (rxq->fep->flag_csum & RX_FLAG_CSUM_EN)) {
     133         [ #  # ]:          0 :                         if ((rte_read32(&ebdp->bd_esc) &
     134                 :            :                                 rte_cpu_to_le_32(RX_FLAG_CSUM_ERR)) == 0) {
     135                 :            :                                 /* No checksum error - checksum is good */
     136                 :          0 :                                 mbuf->ol_flags = RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     137                 :            :                         } else {
     138                 :            :                                 /* Checksum error detected */
     139                 :          0 :                                 mbuf->ol_flags = RTE_MBUF_F_RX_IP_CKSUM_BAD;
     140                 :            :                         }
     141                 :            :                 }
     142                 :            : 
     143                 :            :                 /* Handle received VLAN packets */
     144         [ #  # ]:          0 :                 if (vlan_packet_rcvd) {
     145                 :          0 :                         mbuf->vlan_tci = vlan_tag;
     146                 :          0 :                         mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN_STRIPPED
     147                 :            :                                                 | RTE_MBUF_F_RX_VLAN;
     148                 :            :                 }
     149                 :            : 
     150                 :          0 :                 rxq->rx_mbuf[index] = new_mbuf;
     151                 :          0 :                 rte_write32(rte_cpu_to_le_32(rte_pktmbuf_iova(new_mbuf)),
     152                 :            :                                 &bdp->bd_bufaddr);
     153                 :          0 : rx_processing_done:
     154                 :            :                 /* when rx_processing_done clear the status flags
     155                 :            :                  * for this buffer
     156                 :            :                  */
     157                 :          0 :                 status &= ~RX_BD_STATS;
     158                 :            : 
     159                 :            :                 /* Mark the buffer empty */
     160                 :          0 :                 status |= RX_BD_EMPTY;
     161                 :            : 
     162         [ #  # ]:          0 :                 if (rxq->fep->bufdesc_ex) {
     163                 :            :                         struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
     164                 :            :                         rte_write32(rte_cpu_to_le_32(RX_BD_INT),
     165                 :            :                                     &ebdp->bd_esc);
     166                 :            :                         rte_write32(0, &ebdp->bd_prot);
     167                 :            :                         rte_write32(0, &ebdp->bd_bdu);
     168                 :            :                 }
     169                 :            : 
     170                 :            :                 /* Make sure the updates to rest of the descriptor are
     171                 :            :                  * performed before transferring ownership.
     172                 :            :                  */
     173                 :            :                 rte_wmb();
     174                 :            :                 rte_write16(rte_cpu_to_le_16(status), &bdp->bd_sc);
     175                 :            : 
     176                 :            :                 /* Update BD pointer to next entry */
     177                 :            :                 bdp = enet_get_nextdesc(bdp, &rxq->bd);
     178                 :            : 
     179                 :            :                 /* Doing this here will keep the FEC running while we process
     180                 :            :                  * incoming frames.
     181                 :            :                  */
     182                 :          0 :                 rte_write32(0, rxq->bd.active_reg_desc);
     183                 :            :                 status = rte_le_to_cpu_16(rte_read16(&bdp->bd_sc));
     184                 :            :         }
     185                 :          0 :         rxq->bd.cur = bdp;
     186                 :          0 :         return pkt_received;
     187                 :            : }
     188                 :            : 
     189                 :            : uint16_t
     190                 :          0 : enetfec_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     191                 :            : {
     192                 :            :         struct enetfec_priv_tx_q *txq  =
     193                 :            :                         (struct enetfec_priv_tx_q *)tx_queue;
     194                 :          0 :         struct rte_eth_stats *stats = &txq->fep->stats;
     195                 :            :         struct bufdesc *bdp, *last_bdp;
     196                 :            :         struct rte_mbuf *mbuf;
     197                 :            :         unsigned short status;
     198                 :            :         unsigned short buflen;
     199                 :            :         unsigned int index, estatus = 0;
     200                 :            :         unsigned int i, pkt_transmitted = 0;
     201                 :            :         uint8_t *data;
     202                 :            :         int tx_st = 1;
     203                 :            : 
     204                 :          0 :         while (tx_st) {
     205         [ #  # ]:          0 :                 if (pkt_transmitted >= nb_pkts) {
     206                 :            :                         tx_st = 0;
     207                 :            :                         break;
     208                 :            :                 }
     209                 :            : 
     210                 :          0 :                 mbuf = *(tx_pkts);
     211         [ #  # ]:          0 :                 if (mbuf->nb_segs > 1) {
     212                 :            :                         ENETFEC_DP_LOG(DEBUG, "SG not supported");
     213                 :          0 :                         return pkt_transmitted;
     214                 :            :                 }
     215                 :            : 
     216                 :          0 :                 tx_pkts++;
     217                 :          0 :                 bdp = txq->bd.cur;
     218                 :            : 
     219                 :            :                 /* First clean the ring */
     220                 :          0 :                 index = enet_get_bd_index(bdp, &txq->bd);
     221                 :            :                 status = rte_le_to_cpu_16(rte_read16(&bdp->bd_sc));
     222                 :            : 
     223         [ #  # ]:          0 :                 if (status & TX_BD_READY) {
     224                 :          0 :                         stats->oerrors++;
     225                 :          0 :                         break;
     226                 :            :                 }
     227         [ #  # ]:          0 :                 if (txq->tx_mbuf[index]) {
     228                 :          0 :                         rte_pktmbuf_free(txq->tx_mbuf[index]);
     229                 :          0 :                         txq->tx_mbuf[index] = NULL;
     230                 :            :                 }
     231                 :            : 
     232                 :            :                 /* Fill in a Tx ring entry */
     233                 :            :                 last_bdp = bdp;
     234                 :          0 :                 status &= ~TX_BD_STATS;
     235                 :            : 
     236                 :            :                 /* Set buffer length and buffer pointer */
     237                 :          0 :                 buflen = rte_pktmbuf_pkt_len(mbuf);
     238                 :          0 :                 stats->opackets++;
     239                 :          0 :                 stats->obytes += buflen;
     240                 :            : 
     241                 :            :                 status |= (TX_BD_LAST);
     242                 :          0 :                 data = rte_pktmbuf_mtod(mbuf, void *);
     243         [ #  # ]:          0 :                 for (i = 0; i <= buflen; i += RTE_CACHE_LINE_SIZE)
     244                 :            :                         dccivac(data + i);
     245                 :            : 
     246                 :          0 :                 rte_write32(rte_cpu_to_le_32(rte_pktmbuf_iova(mbuf)),
     247                 :            :                             &bdp->bd_bufaddr);
     248                 :            :                 rte_write16(rte_cpu_to_le_16(buflen), &bdp->bd_datlen);
     249                 :            : 
     250         [ #  # ]:          0 :                 if (txq->fep->bufdesc_ex) {
     251                 :            :                         struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
     252                 :            : 
     253         [ #  # ]:          0 :                         if (mbuf->ol_flags & (RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_TCP_CKSUM |
     254                 :            :                                         RTE_MBUF_F_TX_UDP_CKSUM | RTE_MBUF_F_TX_SCTP_CKSUM))
     255                 :            :                                 estatus |= TX_BD_PINS | TX_BD_IINS;
     256                 :            : 
     257                 :            :                         rte_write32(0, &ebdp->bd_bdu);
     258                 :            :                         rte_write32(rte_cpu_to_le_32(estatus),
     259                 :            :                                     &ebdp->bd_esc);
     260                 :            :                 }
     261                 :            : 
     262                 :          0 :                 index = enet_get_bd_index(last_bdp, &txq->bd);
     263                 :            :                 /* Save mbuf pointer */
     264                 :          0 :                 txq->tx_mbuf[index] = mbuf;
     265                 :            : 
     266                 :            :                 /* Make sure the updates to rest of the descriptor are performed
     267                 :            :                  * before transferring ownership.
     268                 :            :                  */
     269                 :          0 :                 status |= (TX_BD_READY | TX_BD_TC);
     270                 :            :                 rte_wmb();
     271                 :            :                 rte_write16(rte_cpu_to_le_16(status), &bdp->bd_sc);
     272                 :            : 
     273                 :            :                 /* Trigger transmission start */
     274                 :          0 :                 rte_write32(0, txq->bd.active_reg_desc);
     275         [ #  # ]:          0 :                 pkt_transmitted++;
     276                 :            : 
     277                 :            :                 /* If this was the last BD in the ring, start at the
     278                 :            :                  * beginning again.
     279                 :            :                  */
     280                 :            :                 bdp = enet_get_nextdesc(last_bdp, &txq->bd);
     281                 :            : 
     282                 :            :                 /* Make sure the update to bdp and tx_skbuff are performed
     283                 :            :                  * before txq->bd.cur.
     284                 :            :                  */
     285                 :          0 :                 txq->bd.cur = bdp;
     286                 :            :         }
     287                 :          0 :         return pkt_transmitted;
     288                 :            : }

Generated by: LCOV version 1.14