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

Generated by: LCOV version 1.14