LCOV - code coverage report
Current view: top level - drivers/net/zxdh - zxdh_rxtx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 399 0.0 %
Date: 2026-04-01 20:02:27 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 244 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2024 ZTE Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdint.h>
       6                 :            : #include <stdalign.h>
       7                 :            : 
       8                 :            : #include <rte_net.h>
       9                 :            : 
      10                 :            : #include "zxdh_logs.h"
      11                 :            : #include "zxdh_pci.h"
      12                 :            : #include "zxdh_common.h"
      13                 :            : #include "zxdh_rxtx.h"
      14                 :            : #include "zxdh_queue.h"
      15                 :            : 
      16                 :            : #define ZXDH_SVLAN_TPID                       0x88a8
      17                 :            : #define ZXDH_CVLAN_TPID                       0x8100
      18                 :            : 
      19                 :            : #define ZXDH_PKT_FORM_CPU                     0x20    /* 1-cpu 0-np */
      20                 :            : #define ZXDH_NO_IP_FRAGMENT                   0x2000  /* ip fragment flag */
      21                 :            : #define ZXDH_NO_IPID_UPDATE                   0x4000  /* ipid update flag */
      22                 :            : 
      23                 :            : #define ZXDH_PI_L3TYPE_IP                     0x00
      24                 :            : #define ZXDH_PI_L3TYPE_IPV6                   0x40
      25                 :            : #define ZXDH_PI_L3TYPE_NOIP                   0x80
      26                 :            : #define ZXDH_PI_L3TYPE_RSV                    0xC0
      27                 :            : #define ZXDH_PI_L3TYPE_MASK                   0xC0
      28                 :            : 
      29                 :            : #define  ZXDH_PD_OFFLOAD_SPEC_PHYPORT         (1 << 15)
      30                 :            : #define  ZXDH_PD_OFFLOAD_SVLAN_INSERT         (1 << 14)
      31                 :            : #define  ZXDH_PD_OFFLOAD_CVLAN_INSERT         (1 << 13)
      32                 :            : #define  ZXDH_PD_OFFLOAD_OUTER_IPCSUM         (1 << 12)
      33                 :            : #define  ZXDH_PD_OFFLOAD_PRIO_MASK            (0x7 << 8)
      34                 :            : #define  ZXDH_PD_OFFLOAD_DELAY_STAT           (1 << 7)
      35                 :            : 
      36                 :            : #define ZXDH_PCODE_MASK                       0x1F
      37                 :            : #define ZXDH_PCODE_IP_PKT_TYPE                0x01
      38                 :            : #define ZXDH_PCODE_TCP_PKT_TYPE               0x02
      39                 :            : #define ZXDH_PCODE_UDP_PKT_TYPE               0x03
      40                 :            : #define ZXDH_PCODE_NO_IP_PKT_TYPE             0x09
      41                 :            : #define ZXDH_PCODE_NO_REASSMBLE_TCP_PKT_TYPE  0x0C
      42                 :            : 
      43                 :            : /* Uplink pd header byte0~1 */
      44                 :            : #define ZXDH_MBUF_F_RX_OUTER_L4_CKSUM_BAD                0x00080000
      45                 :            : #define ZXDH_MBUF_F_RX_QINQ                              0x00100000
      46                 :            : #define ZXDH_MBUF_F_RX_SEC_OFFLOAD                       0x00200000
      47                 :            : #define ZXDH_MBUF_F_RX_QINQ_STRIPPED                     0x00400000
      48                 :            : #define FELX_4BYTE                                       0x00800000
      49                 :            : #define FELX_8BYTE                                       0x01000000
      50                 :            : #define ZXDH_MBUF_F_RX_FDIR_FLX_MASK                     0x01800000
      51                 :            : #define ZXDH_MBUF_F_RX_FDIR_ID                           0x02000000
      52                 :            : #define ZXDH_MBUF_F_RX_1588_TMST                         0x04000000
      53                 :            : #define ZXDH_MBUF_F_RX_1588_PTP                          0x08000000
      54                 :            : #define ZXDH_MBUF_F_RX_VLAN_STRIPPED                     0x10000000
      55                 :            : #define ZXDH_MBUF_F_RX_OUTER_IP_CKSUM_BAD                0x20000000
      56                 :            : #define ZXDH_MBUF_F_RX_FDIR                              0x40000000
      57                 :            : #define ZXDH_MBUF_F_RX_RSS_HASH                          0x80000000
      58                 :            : #define ZXDH_MBUF_F_RX_INNER_IP_CKSUM_BAD                0x00020000
      59                 :            : #define ZXDH_MBUF_RX_CHECKSUM_BASED_OUTER                0x00010000
      60                 :            : 
      61                 :            : /* Outer/Inner L2 type */
      62                 :            : #define ZXDH_PD_L2TYPE_MASK                              0xf000
      63                 :            : #define ZXDH_PTYPE_L2_ETHER                              0x1000
      64                 :            : #define ZXDH_PTYPE_L2_ETHER_TIMESYNC                     0x2000
      65                 :            : #define ZXDH_PTYPE_L2_ETHER_ARP                          0x3000
      66                 :            : #define ZXDH_PTYPE_L2_ETHER_LLDP                         0x4000
      67                 :            : #define ZXDH_PTYPE_L2_ETHER_NSH                          0x5000
      68                 :            : #define ZXDH_PTYPE_L2_ETHER_VLAN                         0x6000
      69                 :            : #define ZXDH_PTYPE_L2_ETHER_QINQ                         0x7000
      70                 :            : #define ZXDH_PTYPE_L2_ETHER_PPPOE                        0x8000
      71                 :            : #define ZXDH_PTYPE_L2_ETHER_FCOE                         0x9000
      72                 :            : #define ZXDH_PTYPE_L2_ETHER_MPLS                         0xa000
      73                 :            : 
      74                 :            : /* Outer/Inner L3 type */
      75                 :            : #define ZXDH_PD_L3TYPE_MASK                              0x0f00
      76                 :            : #define ZXDH_PTYPE_L3_IPV4                               0x0100
      77                 :            : #define ZXDH_PTYPE_L3_IPV4_EXT                           0x0200
      78                 :            : #define ZXDH_PTYPE_L3_IPV6                               0x0300
      79                 :            : #define ZXDH_PTYPE_L3_IPV4_EXT_UNKNOWN                   0x0400
      80                 :            : #define ZXDH_PTYPE_L3_IPV6_EXT                           0x0500
      81                 :            : #define ZXDH_PTYPE_L3_IPV6_EXT_UNKNOWN                   0x0600
      82                 :            : 
      83                 :            : /* Outer/Inner L4 type */
      84                 :            : #define ZXDH_PD_L4TYPE_MASK    0x00f0
      85                 :            : #define ZXDH_PTYPE_L4_TCP      0x0010
      86                 :            : #define ZXDH_PTYPE_L4_UDP      0x0020
      87                 :            : #define ZXDH_PTYPE_L4_FRAG     0x0030
      88                 :            : #define ZXDH_PTYPE_L4_SCTP     0x0040
      89                 :            : #define ZXDH_PTYPE_L4_ICMP     0x0050
      90                 :            : #define ZXDH_PTYPE_L4_NONFRAG  0x0060
      91                 :            : #define ZXDH_PTYPE_L4_IGMP     0x0070
      92                 :            : 
      93                 :            : #define ZXDH_TX_MAX_SEGS                      31
      94                 :            : #define ZXDH_RX_MAX_SEGS                      31
      95                 :            : 
      96                 :            : #define ZXDH_PI_LRO_FLAG    0x00000001
      97                 :            : 
      98                 :            : #define ZXDH_MIN_MSS                                     64
      99                 :            : #define ZXDH_VLAN_ID_MASK                                0xfff
     100                 :            : 
     101                 :            : #define ZXDH_MTU_MSS_UNIT_SHIFTBIT                       2
     102                 :            : #define ZXDH_MTU_MSS_MASK                                0xFFF
     103                 :            : #define ZXDH_PD_HDR_SIZE_MAX                             256
     104                 :            : 
     105                 :            : /* error code */
     106                 :            : #define ZXDH_UDP_CSUM_ERR  0x0020
     107                 :            : #define ZXDH_TCP_CSUM_ERR  0x0040
     108                 :            : #define ZXDH_IPV4_CSUM_ERR 0x0100
     109                 :            : 
     110                 :            : #define ZXDH_DTPOFFLOAD_MASK ( \
     111                 :            :                 RTE_MBUF_F_TX_IP_CKSUM |        \
     112                 :            :                 RTE_MBUF_F_TX_L4_MASK |         \
     113                 :            :                 RTE_MBUF_F_TX_TCP_SEG |         \
     114                 :            :                 RTE_MBUF_F_TX_SEC_OFFLOAD |     \
     115                 :            :                 RTE_MBUF_F_TX_UDP_SEG)
     116                 :            : 
     117                 :            : uint32_t zxdh_outer_l2_type[16] = {
     118                 :            :         0,
     119                 :            :         RTE_PTYPE_L2_ETHER,
     120                 :            :         RTE_PTYPE_L2_ETHER_TIMESYNC,
     121                 :            :         RTE_PTYPE_L2_ETHER_ARP,
     122                 :            :         RTE_PTYPE_L2_ETHER_LLDP,
     123                 :            :         RTE_PTYPE_L2_ETHER_NSH,
     124                 :            :         RTE_PTYPE_L2_ETHER_VLAN,
     125                 :            :         RTE_PTYPE_L2_ETHER_QINQ,
     126                 :            :         RTE_PTYPE_L2_ETHER_PPPOE,
     127                 :            :         RTE_PTYPE_L2_ETHER_FCOE,
     128                 :            :         RTE_PTYPE_L2_ETHER_MPLS,
     129                 :            : };
     130                 :            : 
     131                 :            : uint32_t zxdh_outer_l3_type[16] = {
     132                 :            :         0,
     133                 :            :         RTE_PTYPE_L3_IPV4,
     134                 :            :         RTE_PTYPE_L3_IPV4_EXT,
     135                 :            :         RTE_PTYPE_L3_IPV6,
     136                 :            :         RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
     137                 :            :         RTE_PTYPE_L3_IPV6_EXT,
     138                 :            :         RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
     139                 :            : };
     140                 :            : 
     141                 :            : uint32_t zxdh_outer_l4_type[16] = {
     142                 :            :         0,
     143                 :            :         RTE_PTYPE_L4_TCP,
     144                 :            :         RTE_PTYPE_L4_UDP,
     145                 :            :         RTE_PTYPE_L4_FRAG,
     146                 :            :         RTE_PTYPE_L4_SCTP,
     147                 :            :         RTE_PTYPE_L4_ICMP,
     148                 :            :         RTE_PTYPE_L4_NONFRAG,
     149                 :            :         RTE_PTYPE_L4_IGMP,
     150                 :            : };
     151                 :            : 
     152                 :            : uint32_t zxdh_tunnel_type[16] = {
     153                 :            :         0,
     154                 :            :         RTE_PTYPE_TUNNEL_IP,
     155                 :            :         RTE_PTYPE_TUNNEL_GRE,
     156                 :            :         RTE_PTYPE_TUNNEL_VXLAN,
     157                 :            :         RTE_PTYPE_TUNNEL_NVGRE,
     158                 :            :         RTE_PTYPE_TUNNEL_GENEVE,
     159                 :            :         RTE_PTYPE_TUNNEL_GRENAT,
     160                 :            :         RTE_PTYPE_TUNNEL_GTPC,
     161                 :            :         RTE_PTYPE_TUNNEL_GTPU,
     162                 :            :         RTE_PTYPE_TUNNEL_ESP,
     163                 :            :         RTE_PTYPE_TUNNEL_L2TP,
     164                 :            :         RTE_PTYPE_TUNNEL_VXLAN_GPE,
     165                 :            :         RTE_PTYPE_TUNNEL_MPLS_IN_GRE,
     166                 :            :         RTE_PTYPE_TUNNEL_MPLS_IN_UDP,
     167                 :            : };
     168                 :            : 
     169                 :            : uint32_t zxdh_inner_l2_type[16] = {
     170                 :            :         0,
     171                 :            :         RTE_PTYPE_INNER_L2_ETHER,
     172                 :            :         0,
     173                 :            :         0,
     174                 :            :         0,
     175                 :            :         0,
     176                 :            :         RTE_PTYPE_INNER_L2_ETHER_VLAN,
     177                 :            :         RTE_PTYPE_INNER_L2_ETHER_QINQ,
     178                 :            :         0,
     179                 :            :         0,
     180                 :            :         0,
     181                 :            : };
     182                 :            : 
     183                 :            : uint32_t zxdh_inner_l3_type[16] = {
     184                 :            :         0,
     185                 :            :         RTE_PTYPE_INNER_L3_IPV4,
     186                 :            :         RTE_PTYPE_INNER_L3_IPV4_EXT,
     187                 :            :         RTE_PTYPE_INNER_L3_IPV6,
     188                 :            :         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
     189                 :            :         RTE_PTYPE_INNER_L3_IPV6_EXT,
     190                 :            :         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
     191                 :            : };
     192                 :            : 
     193                 :            : uint32_t zxdh_inner_l4_type[16] = {
     194                 :            :         0,
     195                 :            :         RTE_PTYPE_INNER_L4_TCP,
     196                 :            :         RTE_PTYPE_INNER_L4_UDP,
     197                 :            :         RTE_PTYPE_INNER_L4_FRAG,
     198                 :            :         RTE_PTYPE_INNER_L4_SCTP,
     199                 :            :         RTE_PTYPE_INNER_L4_ICMP,
     200                 :            :         0,
     201                 :            :         0,
     202                 :            : };
     203                 :            : 
     204                 :            : static void
     205                 :          0 : zxdh_xmit_cleanup_inorder_packed(struct zxdh_virtqueue *vq, int32_t num)
     206                 :            : {
     207                 :            :         uint16_t used_idx = 0;
     208                 :            :         uint16_t id       = 0;
     209                 :            :         uint16_t curr_id  = 0;
     210                 :            :         uint16_t free_cnt = 0;
     211                 :          0 :         uint16_t size     = vq->vq_nentries;
     212                 :          0 :         struct zxdh_vring_packed_desc *desc = vq->vq_packed.ring.desc;
     213                 :            :         struct zxdh_vq_desc_extra     *dxp  = NULL;
     214                 :            : 
     215                 :          0 :         used_idx = vq->vq_used_cons_idx;
     216                 :            :         /* desc_is_used has a load-acquire or rte_io_rmb inside
     217                 :            :          * and wait for used desc in virtqueue.
     218                 :            :          */
     219         [ #  # ]:          0 :         while (num > 0 && zxdh_desc_used(&desc[used_idx], vq)) {
     220                 :          0 :                 id = desc[used_idx].id;
     221                 :            :                 do {
     222                 :            :                         curr_id = used_idx;
     223                 :          0 :                         dxp = &vq->vq_descx[used_idx];
     224                 :          0 :                         used_idx += dxp->ndescs;
     225                 :          0 :                         free_cnt += dxp->ndescs;
     226                 :          0 :                         num -= dxp->ndescs;
     227         [ #  # ]:          0 :                         if (used_idx >= size) {
     228                 :          0 :                                 used_idx -= size;
     229                 :          0 :                                 vq->vq_packed.used_wrap_counter ^= 1;
     230                 :            :                         }
     231         [ #  # ]:          0 :                         if (dxp->cookie != NULL) {
     232                 :          0 :                                 rte_pktmbuf_free(dxp->cookie);
     233                 :          0 :                                 dxp->cookie = NULL;
     234                 :            :                         }
     235         [ #  # ]:          0 :                 } while (curr_id != id);
     236                 :            :         }
     237                 :          0 :         vq->vq_used_cons_idx = used_idx;
     238                 :          0 :         vq->vq_free_cnt += free_cnt;
     239                 :          0 : }
     240                 :            : 
     241                 :            : static inline uint16_t
     242                 :            : zxdh_get_mtu(struct zxdh_virtqueue *vq)
     243                 :            : {
     244                 :          0 :         struct rte_eth_dev *eth_dev = vq->hw->eth_dev;
     245                 :            : 
     246                 :          0 :         return eth_dev->data->mtu;
     247                 :            : }
     248                 :            : 
     249                 :            : static void
     250                 :          0 : zxdh_xmit_fill_net_hdr(struct zxdh_virtqueue *vq, struct rte_mbuf *cookie,
     251                 :            :                                 struct zxdh_net_hdr_dl *hdr)
     252                 :            : {
     253                 :            :         uint16_t mtu_or_mss = 0;
     254                 :            :         uint16_t pkt_flag_lw16 = ZXDH_NO_IPID_UPDATE;
     255                 :            :         uint16_t l3_offset;
     256                 :            :         uint8_t pcode = ZXDH_PCODE_NO_IP_PKT_TYPE;
     257                 :            :         uint8_t l3_ptype = ZXDH_PI_L3TYPE_NOIP;
     258                 :            :         struct zxdh_pi_hdr *pi_hdr = NULL;
     259                 :            :         struct zxdh_pd_hdr_dl *pd_hdr = NULL;
     260                 :          0 :         struct zxdh_hw *hw = vq->hw;
     261                 :          0 :         struct zxdh_net_hdr_dl *net_hdr_dl = hw->net_hdr_dl;
     262                 :          0 :         uint8_t hdr_len = hw->dl_net_hdr_len;
     263                 :            :         uint32_t ol_flag = 0;
     264                 :            : 
     265         [ #  # ]:          0 :         rte_memcpy(hdr, net_hdr_dl, hdr_len);
     266         [ #  # ]:          0 :         if (hw->has_tx_offload) {
     267                 :            :                 pi_hdr = &hdr->pipd_hdr_dl.pi_hdr;
     268                 :          0 :                 pd_hdr = &hdr->pipd_hdr_dl.pd_hdr;
     269                 :            : 
     270                 :            :                 pcode = ZXDH_PCODE_IP_PKT_TYPE;
     271         [ #  # ]:          0 :                 if (cookie->ol_flags & RTE_MBUF_F_TX_IPV6)
     272                 :            :                         l3_ptype = ZXDH_PI_L3TYPE_IPV6;
     273         [ #  # ]:          0 :                 else if (cookie->ol_flags & RTE_MBUF_F_TX_IPV4)
     274                 :            :                         l3_ptype = ZXDH_PI_L3TYPE_IP;
     275                 :            :                 else
     276                 :            :                         pcode = ZXDH_PCODE_NO_IP_PKT_TYPE;
     277                 :            : 
     278         [ #  # ]:          0 :                 if (cookie->ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
     279                 :          0 :                         mtu_or_mss = (cookie->tso_segsz >= ZXDH_MIN_MSS)
     280                 :            :                                 ? cookie->tso_segsz
     281                 :            :                                 : ZXDH_MIN_MSS;
     282                 :          0 :                         pi_hdr->pkt_flag_hi8  |= ZXDH_TX_TCPUDP_CKSUM_CAL;
     283                 :            :                         pkt_flag_lw16 |= ZXDH_NO_IP_FRAGMENT | ZXDH_TX_IP_CKSUM_CAL;
     284                 :            :                         pcode = ZXDH_PCODE_TCP_PKT_TYPE;
     285         [ #  # ]:          0 :                 } else if (cookie->ol_flags & RTE_MBUF_F_TX_UDP_SEG) {
     286                 :            :                         mtu_or_mss = zxdh_get_mtu(vq);
     287                 :          0 :                         mtu_or_mss = (mtu_or_mss >= ZXDH_MIN_MSS) ? mtu_or_mss : ZXDH_MIN_MSS;
     288                 :            :                         pkt_flag_lw16 |= ZXDH_TX_IP_CKSUM_CAL;
     289                 :          0 :                         pi_hdr->pkt_flag_hi8 |= ZXDH_NO_TCP_FRAGMENT | ZXDH_TX_TCPUDP_CKSUM_CAL;
     290                 :            :                         pcode = ZXDH_PCODE_UDP_PKT_TYPE;
     291                 :            :                 } else {
     292                 :            :                         pkt_flag_lw16 |= ZXDH_NO_IP_FRAGMENT;
     293                 :          0 :                         pi_hdr->pkt_flag_hi8 |= ZXDH_NO_TCP_FRAGMENT;
     294                 :            :                 }
     295                 :            : 
     296         [ #  # ]:          0 :                 if (cookie->ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
     297                 :          0 :                         pkt_flag_lw16 |= ZXDH_TX_IP_CKSUM_CAL;
     298                 :            : 
     299         [ #  # ]:          0 :                 if ((cookie->ol_flags & RTE_MBUF_F_TX_UDP_CKSUM) ==
     300                 :            :                         RTE_MBUF_F_TX_UDP_CKSUM){
     301                 :            :                         pcode = ZXDH_PCODE_UDP_PKT_TYPE;
     302                 :          0 :                         pi_hdr->pkt_flag_hi8 |= ZXDH_TX_TCPUDP_CKSUM_CAL;
     303         [ #  # ]:          0 :                 } else if ((cookie->ol_flags & RTE_MBUF_F_TX_TCP_CKSUM) ==
     304                 :            :                                  RTE_MBUF_F_TX_TCP_CKSUM) {
     305                 :            :                         pcode = ZXDH_PCODE_TCP_PKT_TYPE;
     306                 :          0 :                         pi_hdr->pkt_flag_hi8 |= ZXDH_TX_TCPUDP_CKSUM_CAL;
     307                 :            :                 }
     308                 :            : 
     309                 :          0 :                 pkt_flag_lw16 |= (mtu_or_mss >> ZXDH_MTU_MSS_UNIT_SHIFTBIT) & ZXDH_MTU_MSS_MASK;
     310         [ #  # ]:          0 :                 pi_hdr->pkt_flag_lw16 = rte_be_to_cpu_16(pkt_flag_lw16);
     311                 :          0 :                 pi_hdr->pkt_type = l3_ptype | ZXDH_PKT_FORM_CPU | pcode;
     312                 :            : 
     313                 :          0 :                 l3_offset = hdr_len + cookie->l2_len;
     314         [ #  # ]:          0 :                 l3_offset += (cookie->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) ?
     315                 :          0 :                                         cookie->outer_l2_len + cookie->outer_l3_len : 0;
     316         [ #  # ]:          0 :                 pi_hdr->l3_offset = rte_be_to_cpu_16(l3_offset);
     317         [ #  # ]:          0 :                 pi_hdr->l4_offset = rte_be_to_cpu_16(l3_offset + cookie->l3_len);
     318         [ #  # ]:          0 :                 if (cookie->ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM)
     319                 :            :                         ol_flag |= ZXDH_PD_OFFLOAD_OUTER_IPCSUM;
     320                 :            :         } else {
     321                 :          0 :                 pd_hdr = &hdr->pd_hdr;
     322                 :            :         }
     323                 :            : 
     324         [ #  # ]:          0 :         if (cookie->ol_flags & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
     325                 :          0 :                 ol_flag |= ZXDH_PD_OFFLOAD_CVLAN_INSERT;
     326         [ #  # ]:          0 :                 pd_hdr->cvlan_insert = rte_be_to_cpu_16(cookie->vlan_tci);
     327         [ #  # ]:          0 :                 if (unlikely(cookie->ol_flags & RTE_MBUF_F_TX_QINQ)) {
     328                 :          0 :                         ol_flag |= ZXDH_PD_OFFLOAD_SVLAN_INSERT;
     329         [ #  # ]:          0 :                         pd_hdr->svlan_insert = rte_be_to_cpu_16(cookie->vlan_tci_outer);
     330                 :            :                 }
     331                 :            :         }
     332                 :            : 
     333         [ #  # ]:          0 :         pd_hdr->ol_flag = rte_be_to_cpu_16(ol_flag);
     334                 :          0 : }
     335                 :            : 
     336                 :            : static inline void
     337                 :          0 : zxdh_enqueue_xmit_packed_fast(struct zxdh_virtnet_tx *txvq,
     338                 :            :                                                 struct rte_mbuf *cookie)
     339                 :            : {
     340                 :          0 :         struct zxdh_virtqueue *vq = txvq->vq;
     341                 :          0 :         uint16_t id = vq->vq_avail_idx;
     342                 :          0 :         struct zxdh_vq_desc_extra *dxp = &vq->vq_descx[id];
     343                 :          0 :         uint16_t flags = vq->vq_packed.cached_flags;
     344                 :            :         struct zxdh_net_hdr_dl *hdr = NULL;
     345                 :          0 :         uint8_t hdr_len = vq->hw->dl_net_hdr_len;
     346                 :          0 :         struct zxdh_vring_packed_desc *dp = &vq->vq_packed.ring.desc[id];
     347                 :            : 
     348                 :          0 :         dxp->ndescs = 1;
     349                 :          0 :         dxp->cookie = cookie;
     350                 :          0 :         hdr = rte_pktmbuf_mtod_offset(cookie, struct zxdh_net_hdr_dl *, -hdr_len);
     351                 :          0 :         zxdh_xmit_fill_net_hdr(vq, cookie, hdr);
     352                 :            : 
     353                 :          0 :         dp->addr = rte_pktmbuf_iova(cookie) - hdr_len;
     354                 :          0 :         dp->len  = cookie->data_len + hdr_len;
     355                 :          0 :         dp->id   = id;
     356         [ #  # ]:          0 :         if (++vq->vq_avail_idx >= vq->vq_nentries) {
     357                 :          0 :                 vq->vq_avail_idx -= vq->vq_nentries;
     358                 :          0 :                 vq->vq_packed.cached_flags ^= ZXDH_VRING_PACKED_DESC_F_AVAIL_USED;
     359                 :            :         }
     360                 :          0 :         vq->vq_free_cnt--;
     361                 :            :         zxdh_queue_store_flags_packed(dp, flags);
     362                 :          0 : }
     363                 :            : 
     364                 :            : static inline void
     365                 :          0 : zxdh_enqueue_xmit_packed(struct zxdh_virtnet_tx *txvq,
     366                 :            :                                                 struct rte_mbuf *cookie,
     367                 :            :                                                 uint16_t needed)
     368                 :            : {
     369                 :          0 :         struct zxdh_tx_region *txr = txvq->zxdh_net_hdr_mz->addr;
     370                 :          0 :         struct zxdh_virtqueue *vq = txvq->vq;
     371                 :          0 :         uint16_t id = vq->vq_avail_idx;
     372                 :          0 :         struct zxdh_vq_desc_extra *dxp = &vq->vq_descx[id];
     373                 :            :         uint16_t head_idx = vq->vq_avail_idx;
     374                 :            :         uint16_t idx = head_idx;
     375                 :          0 :         struct zxdh_vring_packed_desc *start_dp = vq->vq_packed.ring.desc;
     376                 :          0 :         struct zxdh_vring_packed_desc *head_dp = &vq->vq_packed.ring.desc[idx];
     377                 :            :         struct zxdh_net_hdr_dl *hdr = NULL;
     378                 :            : 
     379                 :          0 :         uint16_t head_flags = cookie->next ? ZXDH_VRING_DESC_F_NEXT : 0;
     380                 :          0 :         uint8_t hdr_len = vq->hw->dl_net_hdr_len;
     381                 :            : 
     382                 :          0 :         dxp->ndescs = needed;
     383                 :          0 :         dxp->cookie = cookie;
     384                 :          0 :         head_flags |= vq->vq_packed.cached_flags;
     385                 :            : 
     386                 :          0 :         start_dp[idx].addr = txvq->zxdh_net_hdr_mem + RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
     387                 :          0 :         start_dp[idx].len  = hdr_len;
     388                 :          0 :         head_flags |= ZXDH_VRING_DESC_F_NEXT;
     389                 :            :         hdr = (void *)&txr[idx].tx_hdr;
     390                 :            : 
     391                 :            :         rte_prefetch1(hdr);
     392                 :          0 :         idx++;
     393         [ #  # ]:          0 :         if (idx >= vq->vq_nentries) {
     394                 :          0 :                 idx -= vq->vq_nentries;
     395                 :          0 :                 vq->vq_packed.cached_flags ^= ZXDH_VRING_PACKED_DESC_F_AVAIL_USED;
     396                 :            :         }
     397                 :            : 
     398                 :          0 :         zxdh_xmit_fill_net_hdr(vq, cookie, hdr);
     399                 :            : 
     400                 :            :         do {
     401                 :          0 :                 start_dp[idx].addr = rte_pktmbuf_iova(cookie);
     402                 :          0 :                 start_dp[idx].len  = cookie->data_len;
     403                 :          0 :                 start_dp[idx].id = id;
     404         [ #  # ]:          0 :                 if (likely(idx != head_idx)) {
     405                 :          0 :                         uint16_t flags = cookie->next ? ZXDH_VRING_DESC_F_NEXT : 0;
     406                 :            : 
     407                 :          0 :                         flags |= vq->vq_packed.cached_flags;
     408                 :          0 :                         start_dp[idx].flags = flags;
     409                 :            :                 }
     410                 :            : 
     411                 :          0 :                 idx++;
     412         [ #  # ]:          0 :                 if (idx >= vq->vq_nentries) {
     413                 :          0 :                         idx -= vq->vq_nentries;
     414                 :          0 :                         vq->vq_packed.cached_flags ^= ZXDH_VRING_PACKED_DESC_F_AVAIL_USED;
     415                 :            :                 }
     416         [ #  # ]:          0 :         } while ((cookie = cookie->next) != NULL);
     417                 :            : 
     418                 :          0 :         vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - needed);
     419                 :          0 :         vq->vq_avail_idx = idx;
     420                 :            : 
     421                 :            :         zxdh_queue_store_flags_packed(head_dp, head_flags);
     422                 :          0 : }
     423                 :            : 
     424                 :            : static void
     425                 :            : zxdh_update_packet_stats(struct zxdh_virtnet_stats *stats, struct rte_mbuf *mbuf)
     426                 :            : {
     427                 :          0 :         uint32_t s = mbuf->pkt_len;
     428                 :            : 
     429                 :          0 :         stats->bytes += s;
     430                 :            :         #ifdef QUEUE_XSTAT
     431                 :            :         if (s == 64) {
     432                 :            :                 stats->size_bins[1]++;
     433                 :            :         } else if (s > 64 && s < 1024) {
     434                 :            :                 uint32_t bin;
     435                 :            : 
     436                 :            :                 /* count zeros, and offset into correct bin */
     437                 :            :                 bin = (sizeof(s) * 8) - rte_clz32(s) - 5;
     438                 :            :                 stats->size_bins[bin]++;
     439                 :            :         } else {
     440                 :            :                 if (s < 64)
     441                 :            :                         stats->size_bins[0]++;
     442                 :            :                 else if (s < 1519)
     443                 :            :                         stats->size_bins[6]++;
     444                 :            :                 else
     445                 :            :                         stats->size_bins[7]++;
     446                 :            :         }
     447                 :            : 
     448                 :            :         ea = rte_pktmbuf_mtod(mbuf, struct rte_ether_addr *);
     449                 :            :         if (rte_is_multicast_ether_addr(ea)) {
     450                 :            :                 if (rte_is_broadcast_ether_addr(ea))
     451                 :            :                         stats->broadcast++;
     452                 :            :                 else
     453                 :            :                         stats->multicast++;
     454                 :            :         }
     455                 :            :         #endif
     456                 :            : }
     457                 :            : 
     458                 :            : static void
     459                 :          0 : zxdh_xmit_flush(struct zxdh_virtqueue *vq)
     460                 :            : {
     461                 :            :         uint16_t id       = 0;
     462                 :            :         uint16_t curr_id  = 0;
     463                 :            :         uint16_t free_cnt = 0;
     464                 :          0 :         uint16_t size     = vq->vq_nentries;
     465                 :          0 :         struct zxdh_vring_packed_desc *desc = vq->vq_packed.ring.desc;
     466                 :            :         struct zxdh_vq_desc_extra     *dxp  = NULL;
     467                 :          0 :         uint16_t used_idx = vq->vq_used_cons_idx;
     468                 :            : 
     469                 :            :         /*
     470                 :            :          * The function desc_is_used performs a load-acquire operation
     471                 :            :          * or calls rte_io_rmb to ensure memory consistency. It waits
     472                 :            :          * for a used descriptor in the virtqueue.
     473                 :            :          */
     474                 :          0 :         while (desc_is_used(&desc[used_idx], vq)) {
     475                 :          0 :                 id = desc[used_idx].id;
     476                 :            :                 do {
     477                 :            :                         curr_id = used_idx;
     478                 :          0 :                         dxp = &vq->vq_descx[used_idx];
     479                 :          0 :                         used_idx += dxp->ndescs;
     480                 :          0 :                         free_cnt += dxp->ndescs;
     481         [ #  # ]:          0 :                         if (used_idx >= size) {
     482                 :          0 :                                 used_idx -= size;
     483                 :          0 :                                 vq->vq_packed.used_wrap_counter ^= 1;
     484                 :            :                         }
     485         [ #  # ]:          0 :                         if (dxp->cookie != NULL) {
     486                 :          0 :                                 rte_pktmbuf_free(dxp->cookie);
     487                 :          0 :                                 dxp->cookie = NULL;
     488                 :            :                         }
     489         [ #  # ]:          0 :                 } while (curr_id != id);
     490                 :            :         }
     491                 :          0 :         vq->vq_used_cons_idx = used_idx;
     492                 :          0 :         vq->vq_free_cnt += free_cnt;
     493                 :          0 : }
     494                 :            : 
     495                 :            : uint16_t
     496                 :          0 : zxdh_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     497                 :            : {
     498                 :            :         struct zxdh_virtnet_tx *txvq = tx_queue;
     499                 :          0 :         struct zxdh_virtqueue  *vq   = txvq->vq;
     500                 :            :         uint16_t nb_tx = 0;
     501                 :            : 
     502                 :          0 :         zxdh_xmit_flush(vq);
     503                 :            : 
     504         [ #  # ]:          0 :         for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
     505                 :          0 :                 struct rte_mbuf *txm = tx_pkts[nb_tx];
     506                 :            :                 int32_t can_push     = 0;
     507                 :            :                 int32_t slots        = 0;
     508                 :            :                 int32_t need         = 0;
     509                 :            : 
     510                 :            :                 rte_prefetch0(txm);
     511                 :            :                 /* optimize ring usage */
     512         [ #  # ]:          0 :                 if (rte_mbuf_refcnt_read(txm) == 1 &&
     513         [ #  # ]:          0 :                         RTE_MBUF_DIRECT(txm) &&
     514         [ #  # ]:          0 :                         txm->nb_segs == 1 &&
     515         [ #  # ]:          0 :                         txm->data_off >= ZXDH_DL_NET_HDR_SIZE) {
     516                 :            :                         can_push = 1;
     517                 :            :                 }
     518                 :            :                 /**
     519                 :            :                  * How many main ring entries are needed to this Tx?
     520                 :            :                  * indirect   => 1
     521                 :            :                  * any_layout => number of segments
     522                 :            :                  * default    => number of segments + 1
     523                 :            :                  **/
     524                 :          0 :                 slots = txm->nb_segs + !can_push;
     525                 :          0 :                 need = slots - vq->vq_free_cnt;
     526                 :            :                 /* Positive value indicates it need free vring descriptors */
     527         [ #  # ]:          0 :                 if (unlikely(need > 0)) {
     528                 :          0 :                         zxdh_xmit_cleanup_inorder_packed(vq, need);
     529                 :          0 :                         need = slots - vq->vq_free_cnt;
     530         [ #  # ]:          0 :                         if (unlikely(need > 0)) {
     531                 :          0 :                                 PMD_TX_LOG(ERR,
     532                 :            :                                                 " No enough %d free tx descriptors to transmit."
     533                 :            :                                                 "freecnt %d",
     534                 :            :                                                 need,
     535                 :            :                                                 vq->vq_free_cnt);
     536                 :          0 :                                 break;
     537                 :            :                         }
     538                 :            :                 }
     539                 :            : 
     540                 :            :                 /* Enqueue Packet buffers */
     541         [ #  # ]:          0 :                 if (can_push)
     542                 :          0 :                         zxdh_enqueue_xmit_packed_fast(txvq, txm);
     543                 :            :                 else
     544                 :          0 :                         zxdh_enqueue_xmit_packed(txvq, txm, slots);
     545                 :            :                 zxdh_update_packet_stats(&txvq->stats, txm);
     546                 :            :         }
     547                 :          0 :         txvq->stats.packets += nb_tx;
     548         [ #  # ]:          0 :         if (likely(nb_tx))
     549                 :            :                 zxdh_queue_notify(vq);
     550                 :          0 :         return nb_tx;
     551                 :            : }
     552                 :            : 
     553                 :          0 : static inline int dl_net_hdr_check(struct rte_mbuf *m, struct zxdh_hw *hw)
     554                 :            : {
     555   [ #  #  #  # ]:          0 :         if ((m->ol_flags & ZXDH_DTPOFFLOAD_MASK) && !hw->has_tx_offload) {
     556                 :          0 :                 PMD_TX_LOG(ERR, "port:[%d], vfid[%d]. "
     557                 :            :                                         "not support tx_offload", hw->port_id, hw->vfid);
     558                 :          0 :                 return -EINVAL;
     559                 :            :         }
     560                 :            :         return 0;
     561                 :            : }
     562                 :            : 
     563                 :          0 : uint16_t zxdh_xmit_pkts_prepare(void *tx_queue, struct rte_mbuf **tx_pkts,
     564                 :            :                                 uint16_t nb_pkts)
     565                 :            : {
     566                 :            :         struct zxdh_virtnet_tx *txvq = tx_queue;
     567                 :          0 :         struct zxdh_hw *hw = txvq->vq->hw;
     568                 :            :         uint16_t nb_tx;
     569                 :            : 
     570         [ #  # ]:          0 :         for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
     571                 :          0 :                 struct rte_mbuf *m = tx_pkts[nb_tx];
     572                 :            :                 int32_t error;
     573                 :            : 
     574                 :            : #ifdef RTE_LIBRTE_ETHDEV_DEBUG
     575                 :            :                 error = rte_validate_tx_offload(m);
     576                 :            :                 if (unlikely(error)) {
     577                 :            :                         rte_errno = -error;
     578                 :            :                         break;
     579                 :            :                 }
     580                 :            : #endif
     581                 :            : 
     582                 :            :                 error = rte_net_intel_cksum_prepare(m);
     583         [ #  # ]:          0 :                 if (unlikely(error)) {
     584                 :          0 :                         rte_errno = -error;
     585                 :          0 :                         break;
     586                 :            :                 }
     587         [ #  # ]:          0 :                 if (m->nb_segs > ZXDH_TX_MAX_SEGS) {
     588                 :          0 :                         PMD_TX_LOG(ERR, "%d segs dropped", m->nb_segs);
     589                 :          0 :                         txvq->stats.truncated_err += nb_pkts - nb_tx;
     590                 :          0 :                         rte_errno = ENOMEM;
     591                 :          0 :                         break;
     592                 :            :                 }
     593                 :            : 
     594                 :          0 :                 error = dl_net_hdr_check(m, hw);
     595         [ #  # ]:          0 :                 if (unlikely(error)) {
     596                 :          0 :                         rte_errno = ENOTSUP;
     597                 :          0 :                         txvq->stats.errors += nb_pkts - nb_tx;
     598                 :          0 :                         txvq->stats.offload_cfg_err += nb_pkts - nb_tx;
     599                 :          0 :                         break;
     600                 :            :                 }
     601                 :            :         }
     602                 :          0 :         return nb_tx;
     603                 :            : }
     604                 :            : 
     605                 :            : static uint16_t
     606                 :          0 : zxdh_dequeue_burst_rx_packed(struct zxdh_virtqueue *vq,
     607                 :            :                                         struct rte_mbuf **rx_pkts,
     608                 :            :                                         uint32_t *len,
     609                 :            :                                         uint16_t num)
     610                 :            : {
     611                 :          0 :         struct zxdh_vring_packed_desc *desc = vq->vq_packed.ring.desc;
     612                 :            :         struct rte_mbuf *cookie = NULL;
     613                 :            :         uint16_t i, used_idx;
     614                 :            :         uint16_t id;
     615                 :            : 
     616         [ #  # ]:          0 :         for (i = 0; i < num; i++) {
     617                 :          0 :                 used_idx = vq->vq_used_cons_idx;
     618                 :            :                 /**
     619                 :            :                  * desc_is_used has a load-acquire or rte_io_rmb inside
     620                 :            :                  * and wait for used desc in virtqueue.
     621                 :            :                  */
     622                 :          0 :                 if (!zxdh_desc_used(&desc[used_idx], vq))
     623                 :          0 :                         return i;
     624                 :          0 :                 len[i] = desc[used_idx].len;
     625                 :          0 :                 id = desc[used_idx].id;
     626                 :          0 :                 cookie = (struct rte_mbuf *)vq->vq_descx[id].cookie;
     627                 :          0 :                 vq->vq_descx[id].cookie = NULL;
     628         [ #  # ]:          0 :                 if (unlikely(cookie == NULL)) {
     629                 :          0 :                         PMD_RX_LOG(ERR,
     630                 :            :                                 "vring descriptor with no mbuf cookie at %u", vq->vq_used_cons_idx);
     631                 :          0 :                         break;
     632                 :            :                 }
     633                 :            :                 rte_prefetch0(cookie);
     634                 :            :                 rte_packet_prefetch(rte_pktmbuf_mtod(cookie, void *));
     635                 :          0 :                 rx_pkts[i] = cookie;
     636                 :          0 :                 vq->vq_free_cnt++;
     637                 :          0 :                 vq->vq_used_cons_idx++;
     638         [ #  # ]:          0 :                 if (vq->vq_used_cons_idx >= vq->vq_nentries) {
     639                 :          0 :                         vq->vq_used_cons_idx -= vq->vq_nentries;
     640                 :          0 :                         vq->vq_packed.used_wrap_counter ^= 1;
     641                 :            :                 }
     642                 :            :         }
     643                 :            :         return i;
     644                 :            : }
     645                 :            : 
     646                 :            : static inline void
     647                 :          0 : update_outer_rx_l4_csum(struct zxdh_hw *hw, struct zxdh_pi_hdr *pi_hdr,
     648                 :            :                 struct zxdh_pd_hdr_ul *pd_hdr, struct rte_mbuf *m)
     649                 :            : {
     650         [ #  # ]:          0 :         uint32_t pd_pkt_flag = ntohl(pd_hdr->pkt_flag);
     651                 :            :         uint32_t packet_type = 0;
     652                 :            :         uint32_t idx = 0;
     653                 :          0 :         bool has_ip_verify = hw->eth_dev->data->dev_conf.rxmode.offloads &
     654                 :            :                         RTE_ETH_RX_OFFLOAD_IPV4_CKSUM;
     655         [ #  # ]:          0 :         uint16_t pkt_type_in = rte_be_to_cpu_16(pd_hdr->pkt_type_in);
     656                 :            : 
     657                 :            :         /* pi_hdr as outer csum and pd_hdr as inner csum */
     658         [ #  # ]:          0 :         if ((pd_pkt_flag & ZXDH_MBUF_RX_CHECKSUM_BASED_OUTER)) {
     659                 :          0 :                 m->ol_flags &= ~RTE_MBUF_F_RX_L4_CKSUM_MASK;
     660                 :          0 :                 m->ol_flags &= ~RTE_MBUF_F_RX_IP_CKSUM_MASK;
     661                 :            : 
     662         [ #  # ]:          0 :                 if (pi_hdr) {
     663         [ #  # ]:          0 :                         uint16_t err_code = rte_be_to_cpu_16(pi_hdr->ul.err_code);
     664         [ #  # ]:          0 :                         if (pi_hdr->pkt_flag_hi8 & ZXDH_RX_TCPUDP_CKSUM_VERIFY) {
     665         [ #  # ]:          0 :                                 if (err_code & ZXDH_UDP_CSUM_ERR)
     666                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
     667                 :            :                                 else
     668                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD;
     669                 :            :                         }
     670                 :            : 
     671         [ #  # ]:          0 :                         if (pi_hdr->pkt_flag_hi8 & ZXDH_RX_IP_CKSUM_VERIFY) {
     672         [ #  # ]:          0 :                                 if (err_code & ZXDH_IPV4_CSUM_ERR)
     673                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
     674                 :            :                         }
     675                 :            :                 }
     676         [ #  # ]:          0 :                 if (pd_pkt_flag & ZXDH_MBUF_F_RX_INNER_IP_CKSUM_BAD) {
     677                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
     678                 :            :                 } else {
     679         [ #  # ]:          0 :                         if (has_ip_verify) {
     680                 :          0 :                                 idx = (pkt_type_in >> 8)  & 0xF;
     681                 :          0 :                                 packet_type = zxdh_inner_l3_type[idx];
     682                 :          0 :                                 if (((packet_type & RTE_PTYPE_INNER_L3_MASK) ==
     683         [ #  # ]:          0 :                                                 RTE_PTYPE_INNER_L3_IPV4) ||
     684                 :            :                                 ((packet_type & RTE_PTYPE_INNER_L3_MASK) ==
     685                 :            :                                                 RTE_PTYPE_INNER_L3_IPV4_EXT))
     686                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     687                 :            :                         }
     688                 :            :                 }
     689                 :            : 
     690                 :            :         } else {
     691         [ #  # ]:          0 :                 if ((m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_BAD) ==
     692                 :            :                                 RTE_MBUF_F_RX_L4_CKSUM_BAD)
     693                 :            :                         m->ol_flags |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_UNKNOWN;
     694         [ #  # ]:          0 :                 else if ((m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD) ==
     695                 :            :                                         RTE_MBUF_F_RX_L4_CKSUM_GOOD) {
     696         [ #  # ]:          0 :                         if (pd_pkt_flag & ZXDH_MBUF_F_RX_OUTER_L4_CKSUM_BAD)
     697                 :          0 :                                 m->ol_flags |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
     698                 :            :                         else
     699                 :          0 :                                 m->ol_flags |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD;
     700                 :            :                 }
     701                 :            :         }
     702                 :          0 : }
     703                 :            : 
     704                 :            : static inline void
     705                 :          0 : zxdh_rx_update_mbuf(struct zxdh_hw *hw, struct rte_mbuf *m, struct zxdh_net_hdr_ul *hdr)
     706                 :            : {
     707                 :          0 :         uint8_t has_pi = (uint64_t)(hdr->type_hdr.pd_len << 1) > ZXDH_UL_NOPI_HDR_SIZE_MAX;
     708         [ #  # ]:          0 :         struct zxdh_pd_hdr_ul *pd_hdr = has_pi ? &hdr->pipd_hdr_ul.pd_hdr : &hdr->pd_hdr;
     709                 :            :         struct zxdh_pi_hdr *pi_hdr = NULL;
     710         [ #  # ]:          0 :         uint32_t pkt_flag = ntohl(pd_hdr->pkt_flag);
     711                 :            :         uint32_t idx = 0;
     712         [ #  # ]:          0 :         uint32_t striped_vlan_tci = rte_be_to_cpu_32(pd_hdr->striped_vlan_tci);
     713         [ #  # ]:          0 :         uint16_t pkt_type_outer = rte_be_to_cpu_16(pd_hdr->pkt_type_out);
     714         [ #  # ]:          0 :         uint16_t pkt_type_inner = rte_be_to_cpu_16(pd_hdr->pkt_type_in);
     715                 :            : 
     716         [ #  # ]:          0 :         if (unlikely(pkt_flag & (ZXDH_MBUF_F_RX_1588_PTP | ZXDH_MBUF_F_RX_1588_TMST))) {
     717         [ #  # ]:          0 :                 if (pkt_flag & ZXDH_MBUF_F_RX_1588_PTP)
     718                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP;
     719         [ #  # ]:          0 :                 if (pkt_flag & ZXDH_MBUF_F_RX_1588_TMST)
     720                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_IEEE1588_TMST;
     721                 :            :         }
     722                 :            : 
     723         [ #  # ]:          0 :         if (pkt_flag & ZXDH_MBUF_F_RX_VLAN_STRIPPED) {
     724                 :          0 :                 m->ol_flags |= (RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_RX_VLAN);
     725         [ #  # ]:          0 :                 m->vlan_tci = (unlikely(pkt_flag & ZXDH_MBUF_F_RX_QINQ))
     726                 :          0 :                                 ? (striped_vlan_tci >> 16) & ZXDH_VLAN_ID_MASK
     727                 :          0 :                                 : striped_vlan_tci & ZXDH_VLAN_ID_MASK;
     728                 :            :         }
     729                 :            : 
     730         [ #  # ]:          0 :         if (unlikely(pkt_flag & ZXDH_MBUF_F_RX_QINQ_STRIPPED)) {
     731                 :            :                 /*
     732                 :            :                  * When PKT_RX_QINQ_STRIPPED is set and PKT_RX_VLAN_STRIPPED is unset:
     733                 :            :                  * - Only the outer VLAN is removed from the packet data.
     734                 :            :                  * - Both TCI values are saved: the inner TCI in mbuf->vlan_tci and
     735                 :            :                  *   the outer TCI in mbuf->vlan_tci_outer.
     736                 :            :                  *
     737                 :            :                  * When PKT_RX_QINQ is set, PKT_RX_VLAN must also be set, and the inner
     738                 :            :                  * TCI is saved in mbuf->vlan_tci.
     739                 :            :                  */
     740                 :          0 :                 m->ol_flags |= (RTE_MBUF_F_RX_QINQ_STRIPPED | RTE_MBUF_F_RX_QINQ);
     741                 :          0 :                 m->ol_flags |= (RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_RX_VLAN);
     742                 :          0 :                 m->vlan_tci = striped_vlan_tci & ZXDH_VLAN_ID_MASK;
     743                 :          0 :                 m->vlan_tci_outer = (striped_vlan_tci >> 16) & ZXDH_VLAN_ID_MASK;
     744                 :            :         }
     745                 :            : 
     746                 :            :         /* rss hash/fd handle */
     747         [ #  # ]:          0 :         if (pkt_flag & ZXDH_MBUF_F_RX_RSS_HASH) {
     748         [ #  # ]:          0 :                 m->hash.rss = rte_be_to_cpu_32(pd_hdr->rss_hash);
     749                 :          0 :                 m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
     750                 :            :         }
     751         [ #  # ]:          0 :         if (pkt_flag & ZXDH_MBUF_F_RX_FDIR) {
     752                 :          0 :                 m->ol_flags |= RTE_MBUF_F_RX_FDIR;
     753         [ #  # ]:          0 :                 if (pkt_flag & ZXDH_MBUF_F_RX_FDIR_ID) {
     754         [ #  # ]:          0 :                         m->hash.fdir.hi = rte_be_to_cpu_32(pd_hdr->fd);
     755                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_FDIR_ID;
     756         [ #  # ]:          0 :                 } else if ((pkt_flag & ZXDH_MBUF_F_RX_FDIR_FLX_MASK) == FELX_4BYTE) {
     757         [ #  # ]:          0 :                         m->hash.fdir.hi = rte_be_to_cpu_32(pd_hdr->fd);
     758                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_FDIR_FLX;
     759         [ #  # ]:          0 :                 } else if (((pkt_flag & ZXDH_MBUF_F_RX_FDIR_FLX_MASK) == FELX_8BYTE)) {
     760         [ #  # ]:          0 :                         m->hash.fdir.hi = rte_be_to_cpu_32(pd_hdr->rss_hash);
     761         [ #  # ]:          0 :                         m->hash.fdir.lo = rte_be_to_cpu_32(pd_hdr->fd);
     762                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_FDIR_FLX;
     763                 :            :                 }
     764                 :            :         }
     765                 :            :         /* checksum handle */
     766         [ #  # ]:          0 :         if (pkt_flag & ZXDH_MBUF_F_RX_OUTER_IP_CKSUM_BAD)
     767                 :          0 :                 m->ol_flags |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
     768                 :            : 
     769         [ #  # ]:          0 :         if (has_pi) {
     770                 :          0 :                 pi_hdr = &hdr->pipd_hdr_ul.pi_hdr;
     771         [ #  # ]:          0 :                 uint16_t err_code = rte_be_to_cpu_16(pi_hdr->ul.err_code);
     772   [ #  #  #  # ]:          0 :                 if (pi_hdr->pkt_type == ZXDH_PCODE_IP_PKT_TYPE ||
     773                 :            :                         ((pi_hdr->pkt_type & ZXDH_PI_L3TYPE_MASK) == ZXDH_PI_L3TYPE_IP)) {
     774         [ #  # ]:          0 :                         if (pi_hdr->pkt_flag_hi8 & ZXDH_RX_IP_CKSUM_VERIFY) {
     775         [ #  # ]:          0 :                                 if (err_code & ZXDH_IPV4_CSUM_ERR)
     776                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
     777                 :            :                                 else
     778                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     779                 :            :                         }
     780                 :            :                 }
     781                 :            : 
     782         [ #  # ]:          0 :                 if (((pi_hdr->pkt_type & ZXDH_PCODE_MASK) == ZXDH_PCODE_UDP_PKT_TYPE) ||
     783                 :            :                         ((pi_hdr->pkt_type & ZXDH_PCODE_MASK) ==
     784         [ #  # ]:          0 :                                 ZXDH_PCODE_NO_REASSMBLE_TCP_PKT_TYPE) ||
     785                 :            :                         ((pi_hdr->pkt_type & ZXDH_PCODE_MASK) == ZXDH_PCODE_TCP_PKT_TYPE)) {
     786         [ #  # ]:          0 :                         if (pi_hdr->pkt_flag_hi8 & ZXDH_RX_TCPUDP_CKSUM_VERIFY) {
     787         [ #  # ]:          0 :                                 if ((err_code & ZXDH_TCP_CSUM_ERR) ||
     788                 :            :                                         (err_code & ZXDH_UDP_CSUM_ERR))
     789                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
     790                 :            :                                 else
     791                 :          0 :                                         m->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     792                 :            :                         }
     793                 :            :                 }
     794                 :            : 
     795         [ #  # ]:          0 :                 if (ntohl(pi_hdr->ul.lro_flag) & ZXDH_PI_LRO_FLAG)
     796                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_LRO;
     797                 :            : 
     798         [ #  # ]:          0 :                 m->pkt_len = rte_be_to_cpu_16(pi_hdr->ul.pkt_len);
     799                 :            :         } else {
     800         [ #  # ]:          0 :                 m->pkt_len = rte_be_to_cpu_16(pd_hdr->pkt_len);
     801                 :            :         }
     802                 :            : 
     803                 :          0 :         idx = (pkt_type_outer >> 12) & 0xF;
     804                 :          0 :         m->packet_type  = zxdh_outer_l2_type[idx];
     805                 :          0 :         idx = (pkt_type_outer >> 8)  & 0xF;
     806                 :          0 :         m->packet_type |= zxdh_outer_l3_type[idx];
     807                 :          0 :         idx = (pkt_type_outer >> 4)  & 0xF;
     808                 :          0 :         m->packet_type |= zxdh_outer_l4_type[idx];
     809                 :          0 :         idx = pkt_type_outer         & 0xF;
     810                 :          0 :         m->packet_type |= zxdh_tunnel_type[idx];
     811                 :            : 
     812         [ #  # ]:          0 :         if (pkt_type_inner) {
     813                 :          0 :                 idx = (pkt_type_inner >> 12) & 0xF;
     814                 :          0 :                 m->packet_type |= zxdh_inner_l2_type[idx];
     815                 :          0 :                 idx = (pkt_type_inner >> 8)  & 0xF;
     816                 :          0 :                 m->packet_type |= zxdh_inner_l3_type[idx];
     817                 :          0 :                 idx = (pkt_type_inner >> 4)  & 0xF;
     818                 :          0 :                 m->packet_type |= zxdh_inner_l4_type[idx];
     819                 :            : 
     820         [ #  # ]:          0 :                 if (hw->eth_dev->data->dev_conf.rxmode.offloads &
     821                 :            :                                 RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM)
     822                 :          0 :                         update_outer_rx_l4_csum(hw, pi_hdr, pd_hdr, m);
     823                 :            :         }
     824                 :          0 : }
     825                 :            : 
     826                 :          0 : static void zxdh_discard_rxbuf(struct zxdh_virtqueue *vq, struct rte_mbuf *m)
     827                 :            : {
     828                 :            :         int32_t error = 0;
     829                 :            :         /*
     830                 :            :          * Requeue the discarded mbuf. This should always be
     831                 :            :          * successful since it was just dequeued.
     832                 :            :          */
     833                 :          0 :         error = zxdh_enqueue_recv_refill_packed(vq, &m, 1);
     834         [ #  # ]:          0 :         if (unlikely(error)) {
     835                 :          0 :                 PMD_RX_LOG(ERR, "cannot enqueue discarded mbuf");
     836                 :          0 :                 rte_pktmbuf_free(m);
     837                 :            :         }
     838                 :          0 : }
     839                 :            : 
     840                 :            : uint16_t
     841                 :          0 : zxdh_recv_pkts_packed(void *rx_queue, struct rte_mbuf **rx_pkts,
     842                 :            :                                 uint16_t nb_pkts)
     843                 :            : {
     844                 :            :         struct zxdh_virtnet_rx *rxvq = rx_queue;
     845                 :          0 :         struct zxdh_virtqueue *vq = rxvq->vq;
     846                 :          0 :         struct zxdh_hw *hw = vq->hw;
     847                 :            :         struct rte_mbuf *rxm = NULL;
     848                 :            :         struct rte_mbuf *prev = NULL;
     849                 :            :         struct zxdh_net_hdr_ul *header = NULL;
     850                 :          0 :         uint32_t lens[ZXDH_MBUF_BURST_SZ] = {0};
     851                 :          0 :         struct rte_mbuf *rcv_pkts[ZXDH_MBUF_BURST_SZ] = {NULL};
     852                 :            :         uint16_t len = 0;
     853                 :            :         uint32_t seg_num = 0;
     854                 :            :         uint32_t seg_res = 0;
     855                 :            :         uint32_t error = 0;
     856                 :            :         uint16_t hdr_size = 0;
     857                 :            :         uint16_t nb_rx = 0;
     858                 :            :         uint16_t i;
     859                 :            :         uint16_t rcvd_pkt_len = 0;
     860                 :            :         uint16_t num = nb_pkts;
     861                 :            : 
     862         [ #  # ]:          0 :         if (unlikely(num > ZXDH_MBUF_BURST_SZ))
     863                 :            :                 num = ZXDH_MBUF_BURST_SZ;
     864                 :            : 
     865                 :          0 :         num = zxdh_dequeue_burst_rx_packed(vq, rcv_pkts, lens, num);
     866         [ #  # ]:          0 :         if (num == 0) {
     867                 :          0 :                 rxvq->stats.idle++;
     868                 :          0 :                 goto refill;
     869                 :            :         }
     870                 :            : 
     871         [ #  # ]:          0 :         for (i = 0; i < num; i++) {
     872                 :          0 :                 rxm = rcv_pkts[i];
     873                 :          0 :                 rx_pkts[nb_rx] = rxm;
     874                 :            :                 prev = rxm;
     875                 :          0 :                 len = lens[i];
     876                 :          0 :                 header = rte_pktmbuf_mtod(rxm, struct zxdh_net_hdr_ul *);
     877                 :            : 
     878                 :          0 :                 seg_num  = header->type_hdr.num_buffers;
     879                 :            : 
     880                 :            :                 /* Private queue only handle type hdr */
     881                 :          0 :                 hdr_size = header->type_hdr.pd_len << 1;
     882   [ #  #  #  # ]:          0 :                 if (unlikely(hdr_size > lens[i] || hdr_size < ZXDH_TYPE_HDR_SIZE)) {
     883                 :          0 :                         PMD_RX_LOG(ERR, "hdr_size:%u is invalid", hdr_size);
     884                 :          0 :                         rte_pktmbuf_free(rxm);
     885                 :          0 :                         rxvq->stats.errors++;
     886                 :          0 :                         rxvq->stats.invalid_hdr_len_err++;
     887                 :          0 :                         continue;
     888                 :            :                 }
     889                 :          0 :                 rxm->data_off += hdr_size;
     890                 :          0 :                 rxm->nb_segs = seg_num;
     891                 :          0 :                 rxm->ol_flags = 0;
     892                 :          0 :                 rcvd_pkt_len = len - hdr_size;
     893                 :          0 :                 rxm->data_len = rcvd_pkt_len;
     894                 :          0 :                 rxm->port = rxvq->port_id;
     895                 :            : 
     896                 :            :                 /* Update rte_mbuf according to pi/pd header */
     897                 :          0 :                 zxdh_rx_update_mbuf(hw, rxm, header);
     898                 :          0 :                 seg_res = seg_num - 1;
     899                 :            :                 /* Merge remaining segments */
     900   [ #  #  #  # ]:          0 :                 while (seg_res != 0 && i < (num - 1)) {
     901                 :          0 :                         i++;
     902                 :          0 :                         len = lens[i];
     903                 :          0 :                         rxm = rcv_pkts[i];
     904                 :          0 :                         rxm->data_len = len;
     905                 :          0 :                         rcvd_pkt_len += len;
     906                 :          0 :                         prev->next = rxm;
     907                 :            :                         prev = rxm;
     908                 :          0 :                         rxm->next = NULL;
     909                 :          0 :                         seg_res -= 1;
     910                 :            :                 }
     911                 :            : 
     912         [ #  # ]:          0 :                 if (!seg_res) {
     913         [ #  # ]:          0 :                         if (rcvd_pkt_len != rx_pkts[nb_rx]->pkt_len) {
     914                 :          0 :                                 PMD_RX_LOG(ERR, "dropped rcvd_pkt_len %d pktlen %d",
     915                 :            :                                         rcvd_pkt_len, rx_pkts[nb_rx]->pkt_len);
     916                 :          0 :                                 zxdh_discard_rxbuf(vq, rx_pkts[nb_rx]);
     917                 :          0 :                                 rxvq->stats.errors++;
     918                 :          0 :                                 rxvq->stats.truncated_err++;
     919                 :          0 :                                 continue;
     920                 :            :                         }
     921                 :            :                         zxdh_update_packet_stats(&rxvq->stats, rx_pkts[nb_rx]);
     922                 :          0 :                         nb_rx++;
     923                 :            :                 }
     924                 :            :         }
     925                 :            :         /* Last packet still need merge segments */
     926         [ #  # ]:          0 :         while (seg_res != 0) {
     927                 :          0 :                 uint16_t rcv_cnt = RTE_MIN((uint16_t)seg_res, ZXDH_MBUF_BURST_SZ);
     928                 :            :                 uint16_t extra_idx = 0;
     929                 :            : 
     930                 :          0 :                 rcv_cnt = zxdh_dequeue_burst_rx_packed(vq, rcv_pkts, lens, rcv_cnt);
     931         [ #  # ]:          0 :                 if (unlikely(rcv_cnt == 0)) {
     932                 :          0 :                         PMD_RX_LOG(ERR, "No enough segments for packet");
     933                 :          0 :                         rte_pktmbuf_free(rx_pkts[nb_rx]);
     934                 :          0 :                         rxvq->stats.errors++;
     935                 :          0 :                         rxvq->stats.no_segs_err++;
     936                 :          0 :                         break;
     937                 :            :                 }
     938         [ #  # ]:          0 :                 while (extra_idx < rcv_cnt) {
     939                 :          0 :                         rxm = rcv_pkts[extra_idx];
     940                 :          0 :                         rcvd_pkt_len += (uint16_t)(lens[extra_idx]);
     941                 :          0 :                         rxm->data_len = lens[extra_idx];
     942                 :          0 :                         prev->next = rxm;
     943                 :            :                         prev = rxm;
     944                 :          0 :                         rxm->next = NULL;
     945                 :          0 :                         extra_idx += 1;
     946                 :            :                 }
     947                 :          0 :                 seg_res -= rcv_cnt;
     948         [ #  # ]:          0 :                 if (!seg_res) {
     949         [ #  # ]:          0 :                         if (unlikely(rcvd_pkt_len != rx_pkts[nb_rx]->pkt_len)) {
     950                 :          0 :                                 PMD_RX_LOG(ERR, "dropped rcvd_pkt_len %d pktlen %d",
     951                 :            :                                         rcvd_pkt_len, rx_pkts[nb_rx]->pkt_len);
     952                 :          0 :                                 zxdh_discard_rxbuf(vq, rx_pkts[nb_rx]);
     953                 :          0 :                                 rxvq->stats.errors++;
     954                 :          0 :                                 rxvq->stats.truncated_err++;
     955                 :          0 :                                 continue;
     956                 :            :                         }
     957                 :            :                         zxdh_update_packet_stats(&rxvq->stats, rx_pkts[nb_rx]);
     958                 :          0 :                         nb_rx++;
     959                 :            :                 }
     960                 :            :         }
     961                 :          0 :         rxvq->stats.packets += nb_rx;
     962                 :            : 
     963         [ #  # ]:          0 : refill:
     964                 :            :         /* Allocate new mbuf for the used descriptor */
     965         [ #  # ]:          0 :         if (likely(!zxdh_queue_full(vq))) {
     966                 :            :                 struct rte_mbuf *new_pkts[ZXDH_MBUF_BURST_SZ];
     967                 :            :                 /* free_cnt may include mrg descs */
     968                 :          0 :                 uint16_t free_cnt = RTE_MIN(vq->vq_free_cnt, ZXDH_MBUF_BURST_SZ);
     969                 :            : 
     970         [ #  # ]:          0 :                 if (!rte_pktmbuf_alloc_bulk(rxvq->mpool, new_pkts, free_cnt)) {
     971                 :          0 :                         error = zxdh_enqueue_recv_refill_packed(vq, new_pkts, free_cnt);
     972         [ #  # ]:          0 :                         if (unlikely(error)) {
     973         [ #  # ]:          0 :                                 for (i = 0; i < free_cnt; i++)
     974                 :          0 :                                         rte_pktmbuf_free(new_pkts[i]);
     975                 :            :                         }
     976                 :            : 
     977         [ #  # ]:          0 :                         if (unlikely(zxdh_queue_kick_prepare_packed(vq)))
     978                 :            :                                 zxdh_queue_notify(vq);
     979                 :            :                 } else {
     980                 :          0 :                         struct rte_eth_dev *dev = hw->eth_dev;
     981                 :            : 
     982                 :          0 :                         dev->data->rx_mbuf_alloc_failed += free_cnt;
     983                 :            :                 }
     984                 :            :         }
     985                 :          0 :         return nb_rx;
     986                 :            : }

Generated by: LCOV version 1.14