LCOV - code coverage report
Current view: top level - drivers/net/intel/cpfl - cpfl_ethdev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 4 1471 0.3 %
Date: 2026-10-01 18:19:24 Functions: 4 82 4.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 770 0.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2023 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_atomic.h>
       6                 :            : #include <rte_eal.h>
       7                 :            : #include <rte_ether.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include <rte_memzone.h>
      10                 :            : #include <rte_dev.h>
      11                 :            : #include <errno.h>
      12                 :            : #include <rte_alarm.h>
      13                 :            : #include <rte_hash_crc.h>
      14                 :            : 
      15                 :            : #include "cpfl_ethdev.h"
      16                 :            : #include <ethdev_private.h>
      17                 :            : #include <sys/utsname.h>
      18                 :            : #include "cpfl_rxtx.h"
      19                 :            : #include "cpfl_flow.h"
      20                 :            : #include "cpfl_rules.h"
      21                 :            : #include "../common/tx.h"
      22                 :            : 
      23                 :            : #define CPFL_REPRESENTOR        "representor"
      24                 :            : #define CPFL_TX_SINGLE_Q        "tx_single"
      25                 :            : #define CPFL_RX_SINGLE_Q        "rx_single"
      26                 :            : #define CPFL_VPORT              "vport"
      27                 :            : 
      28                 :            : #ifdef RTE_HAS_JANSSON
      29                 :            : #define CPFL_FLOW_PARSER        "flow_parser"
      30                 :            : #endif
      31                 :            : 
      32                 :            : #define VCPF_FID        0
      33                 :            : #define CPFL_FID        6
      34                 :            : 
      35                 :            : rte_spinlock_t cpfl_adapter_lock;
      36                 :            : /* A list for all adapters, one adapter matches one PCI device */
      37                 :            : struct cpfl_adapter_list cpfl_adapter_list;
      38                 :            : bool cpfl_adapter_list_init;
      39                 :            : 
      40                 :            : static const char * const cpfl_valid_args_first[] = {
      41                 :            :         CPFL_REPRESENTOR,
      42                 :            :         CPFL_TX_SINGLE_Q,
      43                 :            :         CPFL_RX_SINGLE_Q,
      44                 :            :         CPFL_VPORT,
      45                 :            : #ifdef RTE_HAS_JANSSON
      46                 :            :         CPFL_FLOW_PARSER,
      47                 :            : #endif
      48                 :            :         NULL
      49                 :            : };
      50                 :            : 
      51                 :            : static const char * const cpfl_valid_args_again[] = {
      52                 :            :         CPFL_REPRESENTOR,
      53                 :            :         NULL
      54                 :            : };
      55                 :            : 
      56                 :            : uint32_t cpfl_supported_speeds[] = {
      57                 :            :         RTE_ETH_SPEED_NUM_NONE,
      58                 :            :         RTE_ETH_SPEED_NUM_10M,
      59                 :            :         RTE_ETH_SPEED_NUM_100M,
      60                 :            :         RTE_ETH_SPEED_NUM_1G,
      61                 :            :         RTE_ETH_SPEED_NUM_2_5G,
      62                 :            :         RTE_ETH_SPEED_NUM_5G,
      63                 :            :         RTE_ETH_SPEED_NUM_10G,
      64                 :            :         RTE_ETH_SPEED_NUM_20G,
      65                 :            :         RTE_ETH_SPEED_NUM_25G,
      66                 :            :         RTE_ETH_SPEED_NUM_40G,
      67                 :            :         RTE_ETH_SPEED_NUM_50G,
      68                 :            :         RTE_ETH_SPEED_NUM_56G,
      69                 :            :         RTE_ETH_SPEED_NUM_100G,
      70                 :            :         RTE_ETH_SPEED_NUM_200G
      71                 :            : };
      72                 :            : 
      73                 :            : static const uint64_t cpfl_map_hena_rss[] = {
      74                 :            :         [IDPF_HASH_NONF_UNICAST_IPV4_UDP] =
      75                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_UDP,
      76                 :            :         [IDPF_HASH_NONF_MULTICAST_IPV4_UDP] =
      77                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_UDP,
      78                 :            :         [IDPF_HASH_NONF_IPV4_UDP] =
      79                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_UDP,
      80                 :            :         [IDPF_HASH_NONF_IPV4_TCP_SYN_NO_ACK] =
      81                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_TCP,
      82                 :            :         [IDPF_HASH_NONF_IPV4_TCP] =
      83                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_TCP,
      84                 :            :         [IDPF_HASH_NONF_IPV4_SCTP] =
      85                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
      86                 :            :         [IDPF_HASH_NONF_IPV4_OTHER] =
      87                 :            :                         RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
      88                 :            :         [IDPF_HASH_FRAG_IPV4] = RTE_ETH_RSS_FRAG_IPV4,
      89                 :            : 
      90                 :            :         /* IPv6 */
      91                 :            :         [IDPF_HASH_NONF_UNICAST_IPV6_UDP] =
      92                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_UDP,
      93                 :            :         [IDPF_HASH_NONF_MULTICAST_IPV6_UDP] =
      94                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_UDP,
      95                 :            :         [IDPF_HASH_NONF_IPV6_UDP] =
      96                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_UDP,
      97                 :            :         [IDPF_HASH_NONF_IPV6_TCP_SYN_NO_ACK] =
      98                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_TCP,
      99                 :            :         [IDPF_HASH_NONF_IPV6_TCP] =
     100                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_TCP,
     101                 :            :         [IDPF_HASH_NONF_IPV6_SCTP] =
     102                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
     103                 :            :         [IDPF_HASH_NONF_IPV6_OTHER] =
     104                 :            :                         RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
     105                 :            :         [IDPF_HASH_FRAG_IPV6] = RTE_ETH_RSS_FRAG_IPV6,
     106                 :            : 
     107                 :            :         /* L2 Payload */
     108                 :            :         [IDPF_HASH_L2_PAYLOAD] = RTE_ETH_RSS_L2_PAYLOAD
     109                 :            : };
     110                 :            : 
     111                 :            : static const uint64_t cpfl_ipv4_rss = RTE_ETH_RSS_NONFRAG_IPV4_UDP |
     112                 :            :                           RTE_ETH_RSS_NONFRAG_IPV4_TCP |
     113                 :            :                           RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
     114                 :            :                           RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
     115                 :            :                           RTE_ETH_RSS_FRAG_IPV4;
     116                 :            : 
     117                 :            : static const uint64_t cpfl_ipv6_rss = RTE_ETH_RSS_NONFRAG_IPV6_UDP |
     118                 :            :                           RTE_ETH_RSS_NONFRAG_IPV6_TCP |
     119                 :            :                           RTE_ETH_RSS_NONFRAG_IPV6_SCTP |
     120                 :            :                           RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
     121                 :            :                           RTE_ETH_RSS_FRAG_IPV6;
     122                 :            : 
     123                 :            : struct rte_cpfl_xstats_name_off {
     124                 :            :         char name[RTE_ETH_XSTATS_NAME_SIZE];
     125                 :            :         unsigned int offset;
     126                 :            : };
     127                 :            : 
     128                 :            : static const struct rte_cpfl_xstats_name_off rte_cpfl_stats_strings[] = {
     129                 :            :         {"rx_bytes", offsetof(struct virtchnl2_vport_stats, rx_bytes)},
     130                 :            :         {"rx_unicast_packets", offsetof(struct virtchnl2_vport_stats, rx_unicast)},
     131                 :            :         {"rx_multicast_packets", offsetof(struct virtchnl2_vport_stats, rx_multicast)},
     132                 :            :         {"rx_broadcast_packets", offsetof(struct virtchnl2_vport_stats, rx_broadcast)},
     133                 :            :         {"rx_dropped_packets", offsetof(struct virtchnl2_vport_stats, rx_discards)},
     134                 :            :         {"rx_errors", offsetof(struct virtchnl2_vport_stats, rx_errors)},
     135                 :            :         {"rx_unknown_protocol_packets", offsetof(struct virtchnl2_vport_stats,
     136                 :            :                                                  rx_unknown_protocol)},
     137                 :            :         {"tx_bytes", offsetof(struct virtchnl2_vport_stats, tx_bytes)},
     138                 :            :         {"tx_unicast_packets", offsetof(struct virtchnl2_vport_stats, tx_unicast)},
     139                 :            :         {"tx_multicast_packets", offsetof(struct virtchnl2_vport_stats, tx_multicast)},
     140                 :            :         {"tx_broadcast_packets", offsetof(struct virtchnl2_vport_stats, tx_broadcast)},
     141                 :            :         {"tx_dropped_packets", offsetof(struct virtchnl2_vport_stats, tx_discards)},
     142                 :            :         {"tx_error_packets", offsetof(struct virtchnl2_vport_stats, tx_errors)}};
     143                 :            : 
     144                 :            : #define CPFL_NB_XSTATS                  RTE_DIM(rte_cpfl_stats_strings)
     145                 :            : 
     146                 :            : static int
     147                 :          0 : cpfl_dev_link_update(struct rte_eth_dev *dev,
     148                 :            :                      __rte_unused int wait_to_complete)
     149                 :            : {
     150                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     151                 :            :         struct idpf_vport *vport = &cpfl_vport->base;
     152                 :            :         struct rte_eth_link new_link;
     153                 :            :         unsigned int i;
     154                 :            : 
     155                 :            :         memset(&new_link, 0, sizeof(new_link));
     156                 :            : 
     157         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(cpfl_supported_speeds); i++) {
     158         [ #  # ]:          0 :                 if (vport->link_speed == cpfl_supported_speeds[i]) {
     159                 :          0 :                         new_link.link_speed = vport->link_speed;
     160                 :          0 :                         break;
     161                 :            :                 }
     162                 :            :         }
     163                 :            : 
     164         [ #  # ]:          0 :         if (i == RTE_DIM(cpfl_supported_speeds)) {
     165         [ #  # ]:          0 :                 if (vport->link_up)
     166                 :          0 :                         new_link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
     167                 :            :                 else
     168                 :          0 :                         new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
     169                 :            :         }
     170                 :            : 
     171                 :          0 :         new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     172                 :          0 :         new_link.link_status = vport->link_up ? RTE_ETH_LINK_UP :
     173                 :            :                 RTE_ETH_LINK_DOWN;
     174                 :          0 :         new_link.link_autoneg = (dev->data->dev_conf.link_speeds & RTE_ETH_LINK_SPEED_FIXED) ?
     175         [ #  # ]:          0 :                                  RTE_ETH_LINK_FIXED : RTE_ETH_LINK_AUTONEG;
     176                 :            : 
     177                 :          0 :         return rte_eth_linkstatus_set(dev, &new_link);
     178                 :            : }
     179                 :            : 
     180                 :            : static int
     181                 :          0 : cpfl_hairpin_cap_get(struct rte_eth_dev *dev,
     182                 :            :                      struct rte_eth_hairpin_cap *cap)
     183                 :            : {
     184                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     185                 :            : 
     186         [ #  # ]:          0 :         if (cpfl_vport->p2p_q_chunks_info == NULL)
     187                 :            :                 return -ENOTSUP;
     188                 :            : 
     189                 :          0 :         cap->max_nb_queues = CPFL_MAX_P2P_NB_QUEUES;
     190                 :          0 :         cap->max_rx_2_tx = CPFL_MAX_HAIRPINQ_RX_2_TX;
     191                 :          0 :         cap->max_tx_2_rx = CPFL_MAX_HAIRPINQ_TX_2_RX;
     192                 :          0 :         cap->max_nb_desc = CPFL_MAX_HAIRPINQ_NB_DESC;
     193                 :            : 
     194                 :          0 :         return 0;
     195                 :            : }
     196                 :            : 
     197                 :            : static int
     198                 :          0 : cpfl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
     199                 :            : {
     200                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     201                 :            :         struct idpf_vport *vport = &cpfl_vport->base;
     202                 :          0 :         struct idpf_adapter *base = vport->adapter;
     203                 :            : 
     204                 :          0 :         dev_info->max_rx_queues = base->caps.max_rx_q;
     205                 :          0 :         dev_info->max_tx_queues = base->caps.max_tx_q;
     206                 :          0 :         dev_info->min_rx_bufsize = CPFL_MIN_BUF_SIZE;
     207                 :          0 :         dev_info->max_rx_pktlen = vport->max_mtu + CPFL_ETH_OVERHEAD;
     208                 :            : 
     209                 :          0 :         dev_info->max_mtu = vport->max_mtu;
     210                 :          0 :         dev_info->min_mtu = RTE_ETHER_MIN_MTU;
     211                 :            : 
     212                 :          0 :         dev_info->hash_key_size = vport->rss_key_size;
     213                 :          0 :         dev_info->reta_size = vport->rss_lut_size;
     214                 :            : 
     215                 :          0 :         dev_info->flow_type_rss_offloads = CPFL_RSS_OFFLOAD_ALL;
     216                 :            : 
     217                 :          0 :         dev_info->rx_offload_capa =
     218                 :            :                 RTE_ETH_RX_OFFLOAD_IPV4_CKSUM           |
     219                 :            :                 RTE_ETH_RX_OFFLOAD_UDP_CKSUM            |
     220                 :            :                 RTE_ETH_RX_OFFLOAD_TCP_CKSUM            |
     221                 :            :                 RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM     |
     222                 :            :                 RTE_ETH_RX_OFFLOAD_TIMESTAMP            |
     223                 :            :                 RTE_ETH_RX_OFFLOAD_SCATTER;
     224                 :            : 
     225                 :          0 :         dev_info->tx_offload_capa =
     226                 :            :                 RTE_ETH_TX_OFFLOAD_IPV4_CKSUM           |
     227                 :            :                 RTE_ETH_TX_OFFLOAD_UDP_CKSUM            |
     228                 :            :                 RTE_ETH_TX_OFFLOAD_TCP_CKSUM            |
     229                 :            :                 RTE_ETH_TX_OFFLOAD_SCTP_CKSUM           |
     230                 :            :                 RTE_ETH_TX_OFFLOAD_TCP_TSO              |
     231                 :            :                 RTE_ETH_TX_OFFLOAD_MULTI_SEGS           |
     232                 :            :                 RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
     233                 :            : 
     234                 :          0 :         dev_info->default_txconf = (struct rte_eth_txconf) {
     235                 :            :                 .tx_free_thresh = CPFL_DEFAULT_TX_FREE_THRESH,
     236                 :            :                 .tx_rs_thresh = CPFL_DEFAULT_TX_RS_THRESH,
     237                 :            :         };
     238                 :            : 
     239                 :          0 :         dev_info->default_rxconf = (struct rte_eth_rxconf) {
     240                 :            :                 .rx_free_thresh = CPFL_DEFAULT_RX_FREE_THRESH,
     241                 :            :         };
     242                 :            : 
     243                 :          0 :         dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
     244                 :            :                 .nb_max = CPFL_MAX_RING_DESC,
     245                 :            :                 .nb_min = CPFL_MIN_RING_DESC,
     246                 :            :                 .nb_align = CPFL_ALIGN_RING_DESC,
     247                 :            :         };
     248                 :            : 
     249                 :          0 :         dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
     250                 :            :                 .nb_max = CPFL_MAX_RING_DESC,
     251                 :            :                 .nb_min = CPFL_MIN_RING_DESC,
     252                 :            :                 .nb_align = CPFL_ALIGN_RING_DESC,
     253                 :            :         };
     254                 :            : 
     255                 :          0 :         return 0;
     256                 :            : }
     257                 :            : 
     258                 :            : static int
     259                 :          0 : cpfl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
     260                 :            : {
     261                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     262                 :            :         struct idpf_vport *vport = &cpfl_vport->base;
     263                 :            : 
     264                 :            :         /* mtu setting is forbidden if port is start */
     265         [ #  # ]:          0 :         if (dev->data->dev_started) {
     266                 :          0 :                 PMD_DRV_LOG(ERR, "port must be stopped before configuration");
     267                 :          0 :                 return -EBUSY;
     268                 :            :         }
     269                 :            : 
     270         [ #  # ]:          0 :         if (mtu > vport->max_mtu) {
     271                 :          0 :                 PMD_DRV_LOG(ERR, "MTU should be less than %d", vport->max_mtu);
     272                 :          0 :                 return -EINVAL;
     273                 :            :         }
     274                 :            : 
     275                 :          0 :         vport->max_pkt_len = mtu + CPFL_ETH_OVERHEAD;
     276                 :            : 
     277                 :          0 :         return 0;
     278                 :            : }
     279                 :            : 
     280                 :            : static const uint32_t *
     281                 :          0 : cpfl_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
     282                 :            :                               size_t *no_of_elements)
     283                 :            : {
     284                 :            :         static const uint32_t ptypes[] = {
     285                 :            :                 RTE_PTYPE_L2_ETHER,
     286                 :            :                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
     287                 :            :                 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
     288                 :            :                 RTE_PTYPE_L4_FRAG,
     289                 :            :                 RTE_PTYPE_L4_UDP,
     290                 :            :                 RTE_PTYPE_L4_TCP,
     291                 :            :                 RTE_PTYPE_L4_SCTP,
     292                 :            :                 RTE_PTYPE_L4_ICMP,
     293                 :            :         };
     294                 :            : 
     295                 :          0 :         *no_of_elements = RTE_DIM(ptypes);
     296                 :          0 :         return ptypes;
     297                 :            : }
     298                 :            : 
     299                 :            : static uint64_t
     300                 :          0 : cpfl_get_mbuf_alloc_failed_stats(struct rte_eth_dev *dev)
     301                 :            : {
     302                 :            :         uint64_t mbuf_alloc_failed = 0;
     303                 :            :         struct cpfl_rx_queue *cpfl_rxq;
     304                 :            :         int i = 0;
     305                 :            : 
     306         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     307                 :          0 :                 cpfl_rxq = dev->data->rx_queues[i];
     308                 :          0 :                 mbuf_alloc_failed +=
     309                 :          0 :                         rte_atomic_load_explicit(&cpfl_rxq->base.rx_stats.mbuf_alloc_failed,
     310                 :            :                                                  rte_memory_order_relaxed);
     311                 :            :         }
     312                 :            : 
     313                 :          0 :         return mbuf_alloc_failed;
     314                 :            : }
     315                 :            : 
     316                 :            : static int
     317                 :          0 : cpfl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
     318                 :            :                 struct eth_queue_stats *qstats __rte_unused)
     319                 :            : {
     320                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     321                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     322                 :          0 :         struct virtchnl2_vport_stats *pstats = NULL;
     323                 :            :         int ret;
     324                 :            : 
     325                 :          0 :         ret = idpf_vc_stats_query(vport, &pstats);
     326         [ #  # ]:          0 :         if (ret == 0) {
     327         [ #  # ]:          0 :                 uint8_t crc_stats_len = (dev->data->dev_conf.rxmode.offloads &
     328                 :            :                                          RTE_ETH_RX_OFFLOAD_KEEP_CRC) ? 0 :
     329                 :            :                                          RTE_ETHER_CRC_LEN;
     330                 :            : 
     331                 :          0 :                 idpf_vport_stats_update(&vport->eth_stats_offset, pstats);
     332                 :          0 :                 stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
     333                 :          0 :                                   pstats->rx_broadcast;
     334                 :          0 :                 stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
     335                 :          0 :                                                 pstats->tx_unicast;
     336                 :          0 :                 stats->imissed = pstats->rx_discards;
     337                 :          0 :                 stats->ierrors = pstats->rx_errors;
     338                 :          0 :                 stats->oerrors = pstats->tx_errors + pstats->tx_discards;
     339                 :          0 :                 stats->ibytes = pstats->rx_bytes;
     340                 :          0 :                 stats->ibytes -= stats->ipackets * crc_stats_len;
     341                 :          0 :                 stats->obytes = pstats->tx_bytes;
     342                 :            : 
     343                 :          0 :                 dev->data->rx_mbuf_alloc_failed = cpfl_get_mbuf_alloc_failed_stats(dev);
     344                 :          0 :                 stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
     345                 :            :         } else {
     346                 :          0 :                 PMD_DRV_LOG(ERR, "Get statistics failed");
     347                 :            :         }
     348                 :          0 :         return ret;
     349                 :            : }
     350                 :            : 
     351                 :            : static void
     352                 :          0 : cpfl_reset_mbuf_alloc_failed_stats(struct rte_eth_dev *dev)
     353                 :            : {
     354                 :            :         struct cpfl_rx_queue *cpfl_rxq;
     355                 :            :         int i;
     356                 :            : 
     357         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     358                 :          0 :                 cpfl_rxq = dev->data->rx_queues[i];
     359                 :          0 :                 rte_atomic_store_explicit(&cpfl_rxq->base.rx_stats.mbuf_alloc_failed, 0,
     360                 :            :                                           rte_memory_order_relaxed);
     361                 :            :         }
     362                 :          0 : }
     363                 :            : 
     364                 :            : static int
     365                 :          0 : cpfl_dev_stats_reset(struct rte_eth_dev *dev)
     366                 :            : {
     367                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     368                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     369                 :          0 :         struct virtchnl2_vport_stats *pstats = NULL;
     370                 :            :         int ret;
     371                 :            : 
     372                 :            :         /* VF devices do not support VIRTCHNL2_OP_GET_STATS */
     373         [ #  # ]:          0 :         if (idpf_is_vf_device(&vport->adapter->hw)) {
     374                 :          0 :                 cpfl_reset_mbuf_alloc_failed_stats(dev);
     375                 :          0 :                 return 0;
     376                 :            :         }
     377                 :            : 
     378                 :          0 :         ret = idpf_vc_stats_query(vport, &pstats);
     379         [ #  # ]:          0 :         if (ret != 0)
     380                 :            :                 return ret;
     381                 :            : 
     382                 :            :         /* set stats offset base on current values */
     383                 :          0 :         vport->eth_stats_offset = *pstats;
     384                 :            : 
     385                 :          0 :         cpfl_reset_mbuf_alloc_failed_stats(dev);
     386                 :            : 
     387                 :          0 :         return 0;
     388                 :            : }
     389                 :            : 
     390                 :          0 : static int cpfl_dev_xstats_reset(struct rte_eth_dev *dev)
     391                 :            : {
     392                 :          0 :         cpfl_dev_stats_reset(dev);
     393                 :          0 :         return 0;
     394                 :            : }
     395                 :            : 
     396                 :          0 : static int cpfl_dev_xstats_get(struct rte_eth_dev *dev,
     397                 :            :                                struct rte_eth_xstat *xstats, unsigned int n)
     398                 :            : {
     399                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     400                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     401                 :          0 :         struct virtchnl2_vport_stats *pstats = NULL;
     402                 :            :         unsigned int i;
     403                 :            :         int ret;
     404                 :            : 
     405         [ #  # ]:          0 :         if (n < CPFL_NB_XSTATS)
     406                 :            :                 return CPFL_NB_XSTATS;
     407                 :            : 
     408         [ #  # ]:          0 :         if (!xstats)
     409                 :            :                 return CPFL_NB_XSTATS;
     410                 :            : 
     411                 :          0 :         ret = idpf_vc_stats_query(vport, &pstats);
     412         [ #  # ]:          0 :         if (ret) {
     413                 :          0 :                 PMD_DRV_LOG(ERR, "Get statistics failed");
     414                 :          0 :                 return 0;
     415                 :            :         }
     416                 :            : 
     417                 :          0 :         idpf_vport_stats_update(&vport->eth_stats_offset, pstats);
     418                 :            : 
     419                 :            :         /* loop over xstats array and values from pstats */
     420         [ #  # ]:          0 :         for (i = 0; i < CPFL_NB_XSTATS; i++) {
     421                 :          0 :                 xstats[i].id = i;
     422                 :          0 :                 xstats[i].value = *(uint64_t *)(((char *)pstats) +
     423                 :          0 :                         rte_cpfl_stats_strings[i].offset);
     424                 :            :         }
     425                 :            :         return CPFL_NB_XSTATS;
     426                 :            : }
     427                 :            : 
     428                 :          0 : static int cpfl_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
     429                 :            :                                      struct rte_eth_xstat_name *xstats_names,
     430                 :            :                                      __rte_unused unsigned int limit)
     431                 :            : {
     432                 :            :         unsigned int i;
     433                 :            : 
     434         [ #  # ]:          0 :         if (xstats_names) {
     435         [ #  # ]:          0 :                 for (i = 0; i < CPFL_NB_XSTATS; i++) {
     436                 :          0 :                         snprintf(xstats_names[i].name,
     437                 :            :                                  sizeof(xstats_names[i].name),
     438                 :          0 :                                  "%s", rte_cpfl_stats_strings[i].name);
     439                 :            :                 }
     440                 :            :         }
     441                 :          0 :         return CPFL_NB_XSTATS;
     442                 :            : }
     443                 :            : 
     444                 :          0 : static int cpfl_config_rss_hf(struct idpf_vport *vport, uint64_t rss_hf)
     445                 :            : {
     446                 :            :         uint64_t hena = 0;
     447                 :            :         uint16_t i;
     448                 :            : 
     449                 :            :         /**
     450                 :            :          * RTE_ETH_RSS_IPV4 and RTE_ETH_RSS_IPV6 can be considered as 2
     451                 :            :          * generalizations of all other IPv4 and IPv6 RSS types.
     452                 :            :          */
     453         [ #  # ]:          0 :         if (rss_hf & RTE_ETH_RSS_IPV4)
     454                 :          0 :                 rss_hf |= cpfl_ipv4_rss;
     455                 :            : 
     456         [ #  # ]:          0 :         if (rss_hf & RTE_ETH_RSS_IPV6)
     457                 :          0 :                 rss_hf |= cpfl_ipv6_rss;
     458                 :            : 
     459         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(cpfl_map_hena_rss); i++) {
     460         [ #  # ]:          0 :                 if (cpfl_map_hena_rss[i] & rss_hf)
     461                 :          0 :                         hena |= BIT_ULL(i);
     462                 :            :         }
     463                 :            : 
     464                 :            :         /**
     465                 :            :          * At present, cp doesn't process the virtual channel msg of rss_hf configuration,
     466                 :            :          * tips are given below.
     467                 :            :          */
     468         [ #  # ]:          0 :         if (hena != vport->rss_hf)
     469                 :          0 :                 PMD_DRV_LOG(WARNING, "Updating RSS Hash Function is not supported at present.");
     470                 :            : 
     471                 :          0 :         return 0;
     472                 :            : }
     473                 :            : 
     474                 :            : static int
     475                 :          0 : cpfl_init_rss(struct idpf_vport *vport)
     476                 :            : {
     477                 :            :         struct rte_eth_rss_conf *rss_conf;
     478                 :            :         struct rte_eth_dev_data *dev_data;
     479                 :            :         uint16_t i, nb_q;
     480                 :            :         int ret = 0;
     481                 :            : 
     482                 :          0 :         dev_data = vport->dev_data;
     483                 :            :         rss_conf = &dev_data->dev_conf.rx_adv_conf.rss_conf;
     484                 :          0 :         nb_q = dev_data->nb_rx_queues;
     485                 :            : 
     486         [ #  # ]:          0 :         if (rss_conf->rss_key == NULL) {
     487         [ #  # ]:          0 :                 for (i = 0; i < vport->rss_key_size; i++)
     488                 :          0 :                         vport->rss_key[i] = (uint8_t)rte_rand();
     489         [ #  # ]:          0 :         } else if (rss_conf->rss_key_len != vport->rss_key_size) {
     490                 :          0 :                 PMD_INIT_LOG(ERR, "Invalid RSS key length in RSS configuration, should be %d",
     491                 :            :                              vport->rss_key_size);
     492                 :          0 :                 return -EINVAL;
     493                 :            :         } else {
     494                 :          0 :                 memcpy(vport->rss_key, rss_conf->rss_key,
     495                 :            :                            vport->rss_key_size);
     496                 :            :         }
     497                 :            : 
     498         [ #  # ]:          0 :         for (i = 0; i < vport->rss_lut_size; i++)
     499                 :          0 :                 vport->rss_lut[i] = i % nb_q;
     500                 :            : 
     501                 :          0 :         vport->rss_hf = IDPF_DEFAULT_RSS_HASH_EXPANDED;
     502                 :            : 
     503                 :          0 :         ret = idpf_vport_rss_config(vport);
     504         [ #  # ]:          0 :         if (ret != 0)
     505                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to configure RSS");
     506                 :            : 
     507                 :            :         return ret;
     508                 :            : }
     509                 :            : 
     510                 :            : static int
     511                 :          0 : cpfl_rss_reta_update(struct rte_eth_dev *dev,
     512                 :            :                      struct rte_eth_rss_reta_entry64 *reta_conf,
     513                 :            :                      uint16_t reta_size)
     514                 :            : {
     515                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     516                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     517                 :          0 :         struct idpf_adapter *base = vport->adapter;
     518                 :            :         uint16_t idx, shift;
     519                 :            :         int ret = 0;
     520                 :            :         uint16_t i;
     521                 :            : 
     522   [ #  #  #  # ]:          0 :         if (base->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
     523                 :          0 :                 PMD_DRV_LOG(DEBUG, "RSS is not supported");
     524                 :          0 :                 return -ENOTSUP;
     525                 :            :         }
     526                 :            : 
     527         [ #  # ]:          0 :         if (reta_size != vport->rss_lut_size) {
     528                 :          0 :                 PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
     529                 :            :                                  "(%d) doesn't match the number of hardware can "
     530                 :            :                                  "support (%d)",
     531                 :            :                             reta_size, vport->rss_lut_size);
     532                 :          0 :                 return -EINVAL;
     533                 :            :         }
     534                 :            : 
     535         [ #  # ]:          0 :         for (i = 0; i < reta_size; i++) {
     536                 :          0 :                 idx = i / RTE_ETH_RETA_GROUP_SIZE;
     537                 :          0 :                 shift = i % RTE_ETH_RETA_GROUP_SIZE;
     538         [ #  # ]:          0 :                 if (reta_conf[idx].mask & (1ULL << shift))
     539                 :          0 :                         vport->rss_lut[i] = reta_conf[idx].reta[shift];
     540                 :            :         }
     541                 :            : 
     542                 :            :         /* send virtchnl ops to configure RSS */
     543                 :          0 :         ret = idpf_vc_rss_lut_set(vport);
     544         [ #  # ]:          0 :         if (ret)
     545                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to configure RSS lut");
     546                 :            : 
     547                 :            :         return ret;
     548                 :            : }
     549                 :            : 
     550                 :            : static int
     551                 :          0 : cpfl_rss_reta_query(struct rte_eth_dev *dev,
     552                 :            :                     struct rte_eth_rss_reta_entry64 *reta_conf,
     553                 :            :                     uint16_t reta_size)
     554                 :            : {
     555                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     556                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     557                 :          0 :         struct idpf_adapter *base = vport->adapter;
     558                 :            :         uint16_t idx, shift;
     559                 :            :         int ret = 0;
     560                 :            :         uint16_t i;
     561                 :            : 
     562   [ #  #  #  # ]:          0 :         if (base->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
     563                 :          0 :                 PMD_DRV_LOG(DEBUG, "RSS is not supported");
     564                 :          0 :                 return -ENOTSUP;
     565                 :            :         }
     566                 :            : 
     567         [ #  # ]:          0 :         if (reta_size != vport->rss_lut_size) {
     568                 :          0 :                 PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
     569                 :            :                         "(%d) doesn't match the number of hardware can "
     570                 :            :                         "support (%d)", reta_size, vport->rss_lut_size);
     571                 :          0 :                 return -EINVAL;
     572                 :            :         }
     573                 :            : 
     574                 :          0 :         ret = idpf_vc_rss_lut_get(vport);
     575         [ #  # ]:          0 :         if (ret) {
     576                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to get RSS LUT");
     577                 :          0 :                 return ret;
     578                 :            :         }
     579                 :            : 
     580         [ #  # ]:          0 :         for (i = 0; i < reta_size; i++) {
     581                 :          0 :                 idx = i / RTE_ETH_RETA_GROUP_SIZE;
     582                 :          0 :                 shift = i % RTE_ETH_RETA_GROUP_SIZE;
     583         [ #  # ]:          0 :                 if (reta_conf[idx].mask & (1ULL << shift))
     584                 :          0 :                         reta_conf[idx].reta[shift] = vport->rss_lut[i];
     585                 :            :         }
     586                 :            : 
     587                 :            :         return 0;
     588                 :            : }
     589                 :            : 
     590                 :            : static int
     591                 :          0 : cpfl_rss_hash_update(struct rte_eth_dev *dev,
     592                 :            :                      struct rte_eth_rss_conf *rss_conf)
     593                 :            : {
     594                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     595                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     596                 :          0 :         struct idpf_adapter *base = vport->adapter;
     597                 :            :         int ret = 0;
     598                 :            : 
     599   [ #  #  #  # ]:          0 :         if (base->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
     600                 :          0 :                 PMD_DRV_LOG(DEBUG, "RSS is not supported");
     601                 :          0 :                 return -ENOTSUP;
     602                 :            :         }
     603                 :            : 
     604   [ #  #  #  # ]:          0 :         if (!rss_conf->rss_key || rss_conf->rss_key_len == 0) {
     605                 :          0 :                 PMD_DRV_LOG(DEBUG, "No key to be configured");
     606                 :          0 :                 goto skip_rss_key;
     607         [ #  # ]:          0 :         } else if (rss_conf->rss_key_len != vport->rss_key_size) {
     608                 :          0 :                 PMD_DRV_LOG(ERR, "The size of hash key configured "
     609                 :            :                                  "(%d) doesn't match the size of hardware can "
     610                 :            :                                  "support (%d)",
     611                 :            :                             rss_conf->rss_key_len,
     612                 :            :                             vport->rss_key_size);
     613                 :          0 :                 return -EINVAL;
     614                 :            :         }
     615                 :            : 
     616                 :          0 :         memcpy(vport->rss_key, rss_conf->rss_key,
     617                 :            :                    vport->rss_key_size);
     618                 :          0 :         ret = idpf_vc_rss_key_set(vport);
     619         [ #  # ]:          0 :         if (ret != 0) {
     620                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to configure RSS key");
     621                 :          0 :                 return ret;
     622                 :            :         }
     623                 :            : 
     624                 :          0 : skip_rss_key:
     625                 :          0 :         ret = cpfl_config_rss_hf(vport, rss_conf->rss_hf);
     626         [ #  # ]:          0 :         if (ret != 0) {
     627                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to configure RSS hash");
     628                 :          0 :                 return ret;
     629                 :            :         }
     630                 :            : 
     631                 :            :         return 0;
     632                 :            : }
     633                 :            : 
     634                 :            : static uint64_t
     635                 :          0 : cpfl_map_general_rss_hf(uint64_t config_rss_hf, uint64_t last_general_rss_hf)
     636                 :            : {
     637                 :            :         uint64_t valid_rss_hf = 0;
     638                 :            :         uint16_t i;
     639                 :            : 
     640         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(cpfl_map_hena_rss); i++) {
     641                 :          0 :                 uint64_t bit = BIT_ULL(i);
     642                 :            : 
     643         [ #  # ]:          0 :                 if (bit & config_rss_hf)
     644                 :          0 :                         valid_rss_hf |= cpfl_map_hena_rss[i];
     645                 :            :         }
     646                 :            : 
     647         [ #  # ]:          0 :         if (valid_rss_hf & cpfl_ipv4_rss)
     648                 :          0 :                 valid_rss_hf |= last_general_rss_hf & RTE_ETH_RSS_IPV4;
     649                 :            : 
     650         [ #  # ]:          0 :         if (valid_rss_hf & cpfl_ipv6_rss)
     651                 :          0 :                 valid_rss_hf |= last_general_rss_hf & RTE_ETH_RSS_IPV6;
     652                 :            : 
     653                 :          0 :         return valid_rss_hf;
     654                 :            : }
     655                 :            : 
     656                 :            : static int
     657                 :          0 : cpfl_rss_hash_conf_get(struct rte_eth_dev *dev,
     658                 :            :                        struct rte_eth_rss_conf *rss_conf)
     659                 :            : {
     660                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     661                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     662                 :          0 :         struct idpf_adapter *base = vport->adapter;
     663                 :            :         int ret = 0;
     664                 :            : 
     665   [ #  #  #  # ]:          0 :         if (base->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
     666                 :          0 :                 PMD_DRV_LOG(DEBUG, "RSS is not supported");
     667                 :          0 :                 return -ENOTSUP;
     668                 :            :         }
     669                 :            : 
     670                 :          0 :         ret = idpf_vc_rss_hash_get(vport);
     671         [ #  # ]:          0 :         if (ret) {
     672                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to get RSS hf");
     673                 :          0 :                 return ret;
     674                 :            :         }
     675                 :            : 
     676                 :          0 :         rss_conf->rss_hf = cpfl_map_general_rss_hf(vport->rss_hf, vport->last_general_rss_hf);
     677                 :            : 
     678         [ #  # ]:          0 :         if (!rss_conf->rss_key)
     679                 :            :                 return 0;
     680                 :            : 
     681                 :          0 :         ret = idpf_vc_rss_key_get(vport);
     682         [ #  # ]:          0 :         if (ret) {
     683                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to get RSS key");
     684                 :          0 :                 return ret;
     685                 :            :         }
     686                 :            : 
     687         [ #  # ]:          0 :         if (rss_conf->rss_key_len > vport->rss_key_size)
     688                 :          0 :                 rss_conf->rss_key_len = vport->rss_key_size;
     689                 :            : 
     690                 :          0 :         memcpy(rss_conf->rss_key, vport->rss_key, rss_conf->rss_key_len);
     691                 :            : 
     692                 :          0 :         return 0;
     693                 :            : }
     694                 :            : 
     695                 :            : static int
     696                 :          0 : cpfl_dev_configure(struct rte_eth_dev *dev)
     697                 :            : {
     698                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     699                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     700                 :            :         struct rte_eth_conf *conf = &dev->data->dev_conf;
     701                 :          0 :         struct idpf_adapter *base = vport->adapter;
     702                 :            :         int ret;
     703                 :            : 
     704         [ #  # ]:          0 :         if (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) {
     705                 :          0 :                 PMD_INIT_LOG(ERR, "Setting link speed is not supported");
     706                 :          0 :                 return -ENOTSUP;
     707                 :            :         }
     708                 :            : 
     709         [ #  # ]:          0 :         if (conf->txmode.mq_mode != RTE_ETH_MQ_TX_NONE) {
     710                 :          0 :                 PMD_INIT_LOG(ERR, "Multi-queue TX mode %d is not supported",
     711                 :            :                              conf->txmode.mq_mode);
     712                 :          0 :                 return -ENOTSUP;
     713                 :            :         }
     714                 :            : 
     715         [ #  # ]:          0 :         if (conf->lpbk_mode != 0) {
     716                 :          0 :                 PMD_INIT_LOG(ERR, "Loopback operation mode %d is not supported",
     717                 :            :                              conf->lpbk_mode);
     718                 :          0 :                 return -ENOTSUP;
     719                 :            :         }
     720                 :            : 
     721         [ #  # ]:          0 :         if (conf->dcb_capability_en != 0) {
     722                 :          0 :                 PMD_INIT_LOG(ERR, "Priority Flow Control(PFC) if not supported");
     723                 :          0 :                 return -ENOTSUP;
     724                 :            :         }
     725                 :            : 
     726         [ #  # ]:          0 :         if (conf->intr_conf.lsc != 0) {
     727                 :          0 :                 PMD_INIT_LOG(ERR, "LSC interrupt is not supported");
     728                 :          0 :                 return -ENOTSUP;
     729                 :            :         }
     730                 :            : 
     731         [ #  # ]:          0 :         if (conf->intr_conf.rxq != 0) {
     732                 :          0 :                 PMD_INIT_LOG(ERR, "RXQ interrupt is not supported");
     733                 :          0 :                 return -ENOTSUP;
     734                 :            :         }
     735                 :            : 
     736         [ #  # ]:          0 :         if (conf->intr_conf.rmv != 0) {
     737                 :          0 :                 PMD_INIT_LOG(ERR, "RMV interrupt is not supported");
     738                 :          0 :                 return -ENOTSUP;
     739                 :            :         }
     740                 :            : 
     741         [ #  # ]:          0 :         if (conf->rxmode.mq_mode != RTE_ETH_MQ_RX_RSS &&
     742                 :            :             conf->rxmode.mq_mode != RTE_ETH_MQ_RX_NONE) {
     743                 :          0 :                 PMD_INIT_LOG(ERR, "RX mode %d is not supported.",
     744                 :            :                              conf->rxmode.mq_mode);
     745                 :          0 :                 return -EINVAL;
     746                 :            :         }
     747                 :            : 
     748   [ #  #  #  # ]:          0 :         if (base->caps.rss_caps != 0 && dev->data->nb_rx_queues != 0) {
     749                 :          0 :                 ret = cpfl_init_rss(vport);
     750         [ #  # ]:          0 :                 if (ret != 0) {
     751                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to init rss");
     752                 :          0 :                         return ret;
     753                 :            :                 }
     754         [ #  # ]:          0 :         } else if (conf->rxmode.mq_mode == RTE_ETH_MQ_RX_RSS) {
     755                 :          0 :                 PMD_INIT_LOG(ERR, "RSS is not supported.");
     756                 :          0 :                 return -ENOTSUP;
     757                 :            :         }
     758                 :            : 
     759                 :          0 :         vport->max_pkt_len =
     760         [ #  # ]:          0 :                 (dev->data->mtu == 0) ? CPFL_DEFAULT_MTU : dev->data->mtu +
     761                 :            :                 CPFL_ETH_OVERHEAD;
     762                 :            : 
     763                 :          0 :         return 0;
     764                 :            : }
     765                 :            : 
     766                 :            : static int
     767                 :          0 : cpfl_config_rx_queues_irqs(struct rte_eth_dev *dev)
     768                 :            : {
     769                 :          0 :         uint32_t qids[CPFL_MAX_P2P_NB_QUEUES + IDPF_DEFAULT_RXQ_NUM] = {0};
     770                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     771                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     772                 :          0 :         uint16_t nb_rx_queues = dev->data->nb_rx_queues;
     773                 :            :         struct cpfl_rx_queue *cpfl_rxq;
     774                 :            :         int i;
     775                 :            : 
     776         [ #  # ]:          0 :         for (i = 0; i < nb_rx_queues; i++) {
     777                 :          0 :                 cpfl_rxq = dev->data->rx_queues[i];
     778         [ #  # ]:          0 :                 if (cpfl_rxq->hairpin_info.hairpin_q)
     779                 :          0 :                         qids[i] = cpfl_hw_qid_get(cpfl_vport->p2p_q_chunks_info->rx_start_qid,
     780                 :          0 :                                                   (i - cpfl_vport->nb_data_rxq));
     781                 :            :                 else
     782                 :          0 :                         qids[i] = cpfl_hw_qid_get(vport->chunks_info.rx_start_qid, i);
     783                 :            :         }
     784                 :          0 :         return idpf_vport_irq_map_config_by_qids(vport, qids, nb_rx_queues);
     785                 :            : }
     786                 :            : 
     787                 :            : /* Update hairpin_info for dev's tx hairpin queue */
     788                 :            : static int
     789                 :          0 : cpfl_txq_hairpin_info_update(struct rte_eth_dev *dev, uint16_t rx_port)
     790                 :            : {
     791                 :          0 :         struct cpfl_vport *cpfl_tx_vport = dev->data->dev_private;
     792                 :          0 :         struct rte_eth_dev *peer_dev = &rte_eth_devices[rx_port];
     793                 :          0 :         struct cpfl_vport *cpfl_rx_vport = peer_dev->data->dev_private;
     794                 :            :         struct cpfl_txq_hairpin_info *hairpin_info;
     795                 :            :         struct cpfl_tx_queue *cpfl_txq;
     796                 :            :         int i;
     797                 :            : 
     798         [ #  # ]:          0 :         for (i = cpfl_tx_vport->nb_data_txq; i < dev->data->nb_tx_queues; i++) {
     799                 :          0 :                 cpfl_txq = dev->data->tx_queues[i];
     800                 :            :                 hairpin_info = &cpfl_txq->hairpin_info;
     801         [ #  # ]:          0 :                 if (hairpin_info->peer_rxp != rx_port) {
     802                 :          0 :                         PMD_DRV_LOG(ERR, "port %d is not the peer port", rx_port);
     803                 :          0 :                         return -EINVAL;
     804                 :            :                 }
     805                 :          0 :                 hairpin_info->peer_rxq_id =
     806                 :          0 :                         cpfl_hw_qid_get(cpfl_rx_vport->p2p_q_chunks_info->rx_start_qid,
     807                 :          0 :                                         hairpin_info->peer_rxq_id - cpfl_rx_vport->nb_data_rxq);
     808                 :            :         }
     809                 :            : 
     810                 :            :         return 0;
     811                 :            : }
     812                 :            : 
     813                 :            : /* Bind Rx hairpin queue's memory zone to peer Tx hairpin queue's memory zone */
     814                 :            : static void
     815                 :          0 : cpfl_rxq_hairpin_mz_bind(struct rte_eth_dev *dev)
     816                 :            : {
     817                 :          0 :         struct cpfl_vport *cpfl_rx_vport = dev->data->dev_private;
     818                 :            :         struct idpf_vport *vport = &cpfl_rx_vport->base;
     819                 :          0 :         struct idpf_adapter *adapter = vport->adapter;
     820                 :            :         struct idpf_hw *hw = &adapter->hw;
     821                 :            :         struct cpfl_rx_queue *cpfl_rxq;
     822                 :            :         struct cpfl_tx_queue *cpfl_txq;
     823                 :            :         struct rte_eth_dev *peer_dev;
     824                 :            :         const struct rte_memzone *mz;
     825                 :            :         uint16_t peer_tx_port;
     826                 :            :         uint16_t peer_tx_qid;
     827                 :            :         int i;
     828                 :            : 
     829         [ #  # ]:          0 :         for (i = cpfl_rx_vport->nb_data_rxq; i < dev->data->nb_rx_queues; i++) {
     830                 :          0 :                 cpfl_rxq = dev->data->rx_queues[i];
     831                 :          0 :                 peer_tx_port = cpfl_rxq->hairpin_info.peer_txp;
     832                 :          0 :                 peer_tx_qid = cpfl_rxq->hairpin_info.peer_txq_id;
     833                 :          0 :                 peer_dev = &rte_eth_devices[peer_tx_port];
     834                 :          0 :                 cpfl_txq = peer_dev->data->tx_queues[peer_tx_qid];
     835                 :            : 
     836                 :            :                 /* bind rx queue */
     837                 :          0 :                 mz = cpfl_txq->base.mz;
     838                 :          0 :                 cpfl_rxq->base.rx_ring_phys_addr = mz->iova;
     839                 :          0 :                 cpfl_rxq->base.rx_ring = mz->addr;
     840                 :          0 :                 cpfl_rxq->base.mz = mz;
     841                 :            : 
     842                 :            :                 /* bind rx buffer queue */
     843                 :          0 :                 mz = cpfl_txq->base.complq->mz;
     844                 :          0 :                 cpfl_rxq->base.bufq1->rx_ring_phys_addr = mz->iova;
     845                 :          0 :                 cpfl_rxq->base.bufq1->rx_ring = mz->addr;
     846                 :          0 :                 cpfl_rxq->base.bufq1->mz = mz;
     847                 :          0 :                 cpfl_rxq->base.bufq1->qrx_tail = hw->hw_addr +
     848                 :          0 :                         cpfl_hw_qtail_get(cpfl_rx_vport->p2p_q_chunks_info->rx_buf_qtail_start,
     849                 :          0 :                                         0, cpfl_rx_vport->p2p_q_chunks_info->rx_buf_qtail_spacing);
     850                 :            :         }
     851                 :          0 : }
     852                 :            : 
     853                 :            : static int
     854                 :          0 : cpfl_rss_lut_config(struct cpfl_vport *cpfl_vport, uint16_t nb_q)
     855                 :            : {
     856                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     857                 :          0 :         uint16_t lut_size = vport->rss_lut_size;
     858                 :            :         uint16_t i;
     859                 :            :         int ret;
     860                 :            : 
     861         [ #  # ]:          0 :         for (i = 0; i < lut_size; i++)
     862                 :          0 :                 vport->rss_lut[i] = i % nb_q;
     863                 :            : 
     864                 :          0 :         ret = idpf_vc_rss_lut_set(vport);
     865         [ #  # ]:          0 :         if (ret)
     866                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to configure RSS lut");
     867                 :            : 
     868                 :          0 :         return ret;
     869                 :            : }
     870                 :            : 
     871                 :            : static int
     872                 :          0 : cpfl_start_queues(struct rte_eth_dev *dev)
     873                 :            : {
     874                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
     875                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
     876                 :            :         struct cpfl_rx_queue *cpfl_rxq;
     877                 :            :         struct cpfl_tx_queue *cpfl_txq;
     878                 :            :         int update_flag = 0;
     879                 :            :         int err = 0;
     880                 :            :         int i;
     881                 :            : 
     882                 :            :         /* For normal data queues, configure, init and enale Txq.
     883                 :            :          * For non-manual bind hairpin queues, configure Txq.
     884                 :            :          */
     885         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     886                 :          0 :                 cpfl_txq = dev->data->tx_queues[i];
     887   [ #  #  #  # ]:          0 :                 if (cpfl_txq == NULL || cpfl_txq->base.tx_deferred_start)
     888                 :          0 :                         continue;
     889         [ #  # ]:          0 :                 if (!cpfl_txq->hairpin_info.hairpin_q) {
     890                 :          0 :                         err = cpfl_tx_queue_start(dev, i);
     891         [ #  # ]:          0 :                         if (err != 0) {
     892                 :          0 :                                 PMD_DRV_LOG(ERR, "Fail to start Tx queue %u", i);
     893                 :          0 :                                 return err;
     894                 :            :                         }
     895         [ #  # ]:          0 :                 } else if (!cpfl_vport->p2p_manual_bind) {
     896         [ #  # ]:          0 :                         if (update_flag == 0) {
     897                 :          0 :                                 err = cpfl_txq_hairpin_info_update(dev,
     898                 :          0 :                                                                    cpfl_txq->hairpin_info.peer_rxp);
     899         [ #  # ]:          0 :                                 if (err != 0) {
     900                 :          0 :                                         PMD_DRV_LOG(ERR, "Fail to update Tx hairpin queue info");
     901                 :          0 :                                         return err;
     902                 :            :                                 }
     903                 :            :                                 update_flag = 1;
     904                 :            :                         }
     905                 :          0 :                         err = cpfl_hairpin_txq_config(vport, cpfl_txq);
     906         [ #  # ]:          0 :                         if (err != 0) {
     907                 :          0 :                                 PMD_DRV_LOG(ERR, "Fail to configure hairpin Tx queue %u", i);
     908                 :          0 :                                 return err;
     909                 :            :                         }
     910                 :            :                 }
     911                 :            :         }
     912                 :            : 
     913                 :            :         /* For non-manual bind hairpin queues, configure Tx completion queue first.*/
     914   [ #  #  #  # ]:          0 :         if (!cpfl_vport->p2p_manual_bind && cpfl_vport->p2p_tx_complq != NULL) {
     915                 :          0 :                 err = cpfl_hairpin_tx_complq_config(cpfl_vport);
     916         [ #  # ]:          0 :                 if (err != 0) {
     917                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to config Tx completion queue");
     918                 :          0 :                         return err;
     919                 :            :                 }
     920                 :            :         }
     921                 :            : 
     922                 :            :         /* For non-manual bind hairpin queues, configure Rx buffer queue.*/
     923   [ #  #  #  # ]:          0 :         if (!cpfl_vport->p2p_manual_bind && cpfl_vport->p2p_rx_bufq != NULL) {
     924                 :          0 :                 cpfl_rxq_hairpin_mz_bind(dev);
     925                 :          0 :                 err = cpfl_hairpin_rx_bufq_config(cpfl_vport);
     926         [ #  # ]:          0 :                 if (err != 0) {
     927                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to config Rx buffer queue");
     928                 :          0 :                         return err;
     929                 :            :                 }
     930                 :            :         }
     931                 :            : 
     932                 :            :         /* For normal data queues, configure, init and enale Rxq.
     933                 :            :          * For non-manual bind hairpin queues, configure Rxq, and then init Rxq.
     934                 :            :          */
     935         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     936                 :          0 :                 cpfl_rxq = dev->data->rx_queues[i];
     937   [ #  #  #  # ]:          0 :                 if (cpfl_rxq == NULL || cpfl_rxq->base.rx_deferred_start)
     938                 :          0 :                         continue;
     939         [ #  # ]:          0 :                 if (!cpfl_rxq->hairpin_info.hairpin_q) {
     940                 :          0 :                         err = cpfl_rx_queue_start(dev, i);
     941         [ #  # ]:          0 :                         if (err != 0) {
     942                 :          0 :                                 PMD_DRV_LOG(ERR, "Fail to start Rx queue %u", i);
     943                 :          0 :                                 return err;
     944                 :            :                         }
     945         [ #  # ]:          0 :                 } else if (!cpfl_vport->p2p_manual_bind) {
     946                 :          0 :                         err = cpfl_hairpin_rxq_config(vport, cpfl_rxq);
     947         [ #  # ]:          0 :                         if (err != 0) {
     948                 :          0 :                                 PMD_DRV_LOG(ERR, "Fail to configure hairpin Rx queue %u", i);
     949                 :          0 :                                 return err;
     950                 :            :                         }
     951                 :          0 :                         err = cpfl_rx_queue_init(dev, i);
     952         [ #  # ]:          0 :                         if (err != 0) {
     953                 :          0 :                                 PMD_DRV_LOG(ERR, "Fail to init hairpin Rx queue %u", i);
     954                 :          0 :                                 return err;
     955                 :            :                         }
     956                 :            :                 }
     957                 :            :         }
     958                 :            : 
     959                 :            :         /* For non-manual bind hairpin queues, enable Tx queue and Rx queue,
     960                 :            :          * then enable Tx completion queue and Rx buffer queue.
     961                 :            :          */
     962         [ #  # ]:          0 :         for (i = cpfl_vport->nb_data_txq; i < dev->data->nb_tx_queues; i++) {
     963                 :          0 :                 cpfl_txq = dev->data->tx_queues[i];
     964   [ #  #  #  # ]:          0 :                 if (cpfl_txq->hairpin_info.hairpin_q && !cpfl_vport->p2p_manual_bind) {
     965                 :          0 :                         err = cpfl_switch_hairpin_rxtx_queue(cpfl_vport,
     966                 :          0 :                                                              i - cpfl_vport->nb_data_txq,
     967                 :            :                                                              false, true);
     968         [ #  # ]:          0 :                         if (err)
     969                 :          0 :                                 PMD_DRV_LOG(ERR, "Failed to switch hairpin TX queue %u on",
     970                 :            :                                             i);
     971                 :            :                 }
     972                 :            :         }
     973                 :            : 
     974         [ #  # ]:          0 :         for (i = cpfl_vport->nb_data_rxq; i < dev->data->nb_rx_queues; i++) {
     975                 :          0 :                 cpfl_rxq = dev->data->rx_queues[i];
     976   [ #  #  #  # ]:          0 :                 if (cpfl_rxq->hairpin_info.hairpin_q && !cpfl_vport->p2p_manual_bind) {
     977                 :          0 :                         err = cpfl_switch_hairpin_rxtx_queue(cpfl_vport,
     978                 :          0 :                                                              i - cpfl_vport->nb_data_rxq,
     979                 :            :                                                              true, true);
     980         [ #  # ]:          0 :                         if (err)
     981                 :          0 :                                 PMD_DRV_LOG(ERR, "Failed to switch hairpin RX queue %u on",
     982                 :            :                                             i);
     983                 :            :                         else
     984                 :          0 :                                 cpfl_rxq->base.q_started = true;
     985                 :            :                 }
     986                 :            :         }
     987                 :            : 
     988         [ #  # ]:          0 :         if (!cpfl_vport->p2p_manual_bind &&
     989         [ #  # ]:          0 :             cpfl_vport->p2p_tx_complq != NULL &&
     990         [ #  # ]:          0 :             cpfl_vport->p2p_rx_bufq != NULL) {
     991                 :          0 :                 err = cpfl_switch_hairpin_complq(cpfl_vport, true);
     992         [ #  # ]:          0 :                 if (err != 0) {
     993                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to switch hairpin Tx complq");
     994                 :          0 :                         return err;
     995                 :            :                 }
     996                 :          0 :                 err = cpfl_switch_hairpin_bufq(cpfl_vport, true);
     997         [ #  # ]:          0 :                 if (err != 0) {
     998                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to switch hairpin Rx bufq");
     999                 :          0 :                         return err;
    1000                 :            :                 }
    1001                 :            :         }
    1002                 :            : 
    1003                 :            :         /* re-configure RSS lut if there's hairpin queue */
    1004         [ #  # ]:          0 :         if (cpfl_vport->nb_p2p_rxq > 0)
    1005                 :          0 :                 err = cpfl_rss_lut_config(cpfl_vport, cpfl_vport->nb_data_rxq);
    1006                 :            : 
    1007                 :            :         return err;
    1008                 :            : }
    1009                 :            : 
    1010                 :            : static int
    1011                 :          0 : cpfl_dev_start(struct rte_eth_dev *dev)
    1012                 :            : {
    1013                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    1014                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
    1015                 :          0 :         struct idpf_adapter *base = vport->adapter;
    1016                 :          0 :         struct cpfl_adapter_ext *adapter = CPFL_ADAPTER_TO_EXT(base);
    1017                 :          0 :         uint16_t num_allocated_vectors = base->caps.num_allocated_vectors;
    1018                 :            :         uint16_t req_vecs_num;
    1019                 :            :         int ret;
    1020                 :            : 
    1021                 :            :         req_vecs_num = CPFL_DFLT_Q_VEC_NUM;
    1022         [ #  # ]:          0 :         if (req_vecs_num + adapter->used_vecs_num > num_allocated_vectors) {
    1023                 :          0 :                 PMD_DRV_LOG(ERR, "The accumulated request vectors' number should be less than %d",
    1024                 :            :                             num_allocated_vectors);
    1025                 :            :                 ret = -EINVAL;
    1026                 :          0 :                 goto err_vec;
    1027                 :            :         }
    1028                 :            : 
    1029                 :          0 :         ret = idpf_vc_vectors_alloc(vport, req_vecs_num);
    1030         [ #  # ]:          0 :         if (ret != 0) {
    1031                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate interrupt vectors");
    1032                 :          0 :                 goto err_vec;
    1033                 :            :         }
    1034                 :          0 :         adapter->used_vecs_num += req_vecs_num;
    1035                 :            : 
    1036                 :          0 :         ret = cpfl_config_rx_queues_irqs(dev);
    1037         [ #  # ]:          0 :         if (ret != 0) {
    1038                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to configure irqs");
    1039                 :          0 :                 goto err_irq;
    1040                 :            :         }
    1041                 :            : 
    1042                 :          0 :         ret = cpfl_start_queues(dev);
    1043         [ #  # ]:          0 :         if (ret != 0) {
    1044                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to start queues");
    1045                 :          0 :                 goto err_startq;
    1046                 :            :         }
    1047                 :            : 
    1048                 :          0 :         cpfl_set_rx_function(dev);
    1049                 :          0 :         cpfl_set_tx_function(dev);
    1050                 :            : 
    1051                 :          0 :         ret = idpf_vc_vport_ena_dis(vport, true);
    1052         [ #  # ]:          0 :         if (ret != 0) {
    1053                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to enable vport");
    1054                 :          0 :                 goto err_vport;
    1055                 :            :         }
    1056                 :            : 
    1057         [ #  # ]:          0 :         if (cpfl_dev_stats_reset(dev))
    1058                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to reset stats");
    1059                 :            : 
    1060                 :            :         return 0;
    1061                 :            : 
    1062                 :            : err_vport:
    1063                 :          0 :         cpfl_stop_queues(dev);
    1064                 :          0 : err_startq:
    1065                 :          0 :         idpf_vport_irq_unmap_config(vport, dev->data->nb_rx_queues);
    1066                 :          0 : err_irq:
    1067                 :          0 :         idpf_vc_vectors_dealloc(vport);
    1068                 :            : err_vec:
    1069                 :            :         return ret;
    1070                 :            : }
    1071                 :            : 
    1072                 :            : static int
    1073                 :          0 : cpfl_dev_stop(struct rte_eth_dev *dev)
    1074                 :            : {
    1075                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    1076                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
    1077                 :            : 
    1078         [ #  # ]:          0 :         if (dev->data->dev_started == 0)
    1079                 :            :                 return 0;
    1080                 :            : 
    1081                 :          0 :         idpf_vc_vport_ena_dis(vport, false);
    1082                 :            : 
    1083                 :          0 :         cpfl_stop_queues(dev);
    1084                 :            : 
    1085                 :          0 :         idpf_vport_irq_unmap_config(vport, dev->data->nb_rx_queues);
    1086                 :            : 
    1087                 :          0 :         idpf_vc_vectors_dealloc(vport);
    1088                 :            : 
    1089                 :          0 :         return 0;
    1090                 :            : }
    1091                 :            : 
    1092                 :            : static void
    1093                 :          0 : cpfl_flow_free(struct cpfl_vport *vport)
    1094                 :            : {
    1095                 :            :         struct rte_flow *p_flow;
    1096                 :            : 
    1097         [ #  # ]:          0 :         while ((p_flow = TAILQ_FIRST(&vport->itf.flow_list))) {
    1098         [ #  # ]:          0 :                 TAILQ_REMOVE(&vport->itf.flow_list, p_flow, next);
    1099         [ #  # ]:          0 :                 if (p_flow->engine->free)
    1100                 :          0 :                         p_flow->engine->free(p_flow);
    1101                 :          0 :                 rte_free(p_flow);
    1102                 :            :         }
    1103                 :          0 : }
    1104                 :            : 
    1105                 :            : static int
    1106                 :          0 : cpfl_p2p_queue_grps_del(struct idpf_vport *vport)
    1107                 :            : {
    1108                 :            :         struct virtchnl2_queue_group_id qg_ids;
    1109                 :            :         int ret = 0;
    1110                 :            : 
    1111                 :            :         memset(&qg_ids, 0, sizeof(qg_ids));
    1112                 :          0 :         qg_ids.queue_group_id = CPFL_P2P_QUEUE_GRP_ID;
    1113                 :          0 :         qg_ids.queue_group_type = VIRTCHNL2_QUEUE_GROUP_P2P;
    1114                 :          0 :         ret = idpf_vc_queue_grps_del(vport, CPFL_P2P_NB_QUEUE_GRPS, &qg_ids);
    1115         [ #  # ]:          0 :         if (ret)
    1116                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to delete p2p queue groups");
    1117                 :          0 :         return ret;
    1118                 :            : }
    1119                 :            : 
    1120                 :            : static int
    1121                 :          0 : cpfl_dev_close(struct rte_eth_dev *dev)
    1122                 :            : {
    1123                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    1124                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
    1125                 :          0 :         struct cpfl_adapter_ext *adapter = CPFL_ADAPTER_TO_EXT(vport->adapter);
    1126                 :            : 
    1127                 :          0 :         cpfl_dev_stop(dev);
    1128         [ #  # ]:          0 :         if (cpfl_vport->p2p_mp) {
    1129                 :          0 :                 rte_mempool_free(cpfl_vport->p2p_mp);
    1130                 :          0 :                 cpfl_vport->p2p_mp = NULL;
    1131                 :            :         }
    1132                 :            : 
    1133   [ #  #  #  # ]:          0 :         if (!adapter->base.is_rx_singleq && !adapter->base.is_tx_singleq)
    1134                 :          0 :                 cpfl_p2p_queue_grps_del(vport);
    1135                 :            : 
    1136                 :          0 :         cpfl_flow_free(cpfl_vport);
    1137                 :          0 :         idpf_vport_deinit(vport);
    1138                 :          0 :         rte_free(cpfl_vport->p2p_q_chunks_info);
    1139                 :            : 
    1140                 :          0 :         adapter->cur_vports &= ~RTE_BIT32(vport->devarg_id);
    1141                 :          0 :         adapter->cur_vport_nb--;
    1142                 :          0 :         dev->data->dev_private = NULL;
    1143                 :          0 :         adapter->vports[vport->sw_idx] = NULL;
    1144                 :            :         idpf_free_dma_mem(NULL, &cpfl_vport->itf.flow_dma);
    1145                 :          0 :         rte_free(cpfl_vport);
    1146                 :            : 
    1147                 :          0 :         return 0;
    1148                 :            : }
    1149                 :            : 
    1150                 :            : static int
    1151                 :          0 : cpfl_dev_flow_ops_get(struct rte_eth_dev *dev,
    1152                 :            :                       const struct rte_flow_ops **ops)
    1153                 :            : {
    1154                 :            :         struct cpfl_itf *itf;
    1155                 :            : 
    1156         [ #  # ]:          0 :         if (!dev)
    1157                 :            :                 return -EINVAL;
    1158                 :            : 
    1159                 :          0 :         itf = CPFL_DEV_TO_ITF(dev);
    1160                 :            : 
    1161                 :            :         /* only vport support rte_flow */
    1162         [ #  # ]:          0 :         if (itf->type != CPFL_ITF_TYPE_VPORT)
    1163                 :            :                 return -ENOTSUP;
    1164                 :            : #ifdef RTE_HAS_JANSSON
    1165                 :          0 :         *ops = &cpfl_flow_ops;
    1166                 :            : #else
    1167                 :            :         *ops = NULL;
    1168                 :            :         PMD_DRV_LOG(NOTICE, "not support rte_flow, please install json-c library.");
    1169                 :            : #endif
    1170                 :          0 :         return 0;
    1171                 :            : }
    1172                 :            : 
    1173                 :            : static int
    1174                 :          0 : cpfl_hairpin_get_peer_ports(struct rte_eth_dev *dev, uint16_t *peer_ports,
    1175                 :            :                             size_t len, uint32_t tx)
    1176                 :            : {
    1177                 :          0 :         struct cpfl_vport *cpfl_vport =
    1178                 :          0 :                 (struct cpfl_vport *)dev->data->dev_private;
    1179                 :            :         struct ci_tx_queue *txq;
    1180                 :            :         struct idpf_rx_queue *rxq;
    1181                 :            :         struct cpfl_tx_queue *cpfl_txq;
    1182                 :            :         struct cpfl_rx_queue *cpfl_rxq;
    1183                 :            :         uint16_t i;
    1184                 :            :         uint16_t j = 0;
    1185                 :            : 
    1186         [ #  # ]:          0 :         if (len <= 0)
    1187                 :            :                 return -EINVAL;
    1188                 :            : 
    1189         [ #  # ]:          0 :         if (cpfl_vport->p2p_q_chunks_info == NULL)
    1190                 :            :                 return -ENOTSUP;
    1191                 :            : 
    1192         [ #  # ]:          0 :         if (tx > 0) {
    1193         [ #  # ]:          0 :                 for (i = cpfl_vport->nb_data_txq, j = 0; i < dev->data->nb_tx_queues; i++, j++) {
    1194                 :          0 :                         txq = dev->data->tx_queues[i];
    1195   [ #  #  #  # ]:          0 :                         if (txq == NULL || j >= len)
    1196                 :            :                                 return -EINVAL;
    1197                 :            :                         cpfl_txq = (struct cpfl_tx_queue *)txq;
    1198                 :          0 :                         peer_ports[j] = cpfl_txq->hairpin_info.peer_rxp;
    1199                 :            :                 }
    1200                 :            :         } else if (tx == 0) {
    1201         [ #  # ]:          0 :                 for (i = cpfl_vport->nb_data_rxq, j = 0; i < dev->data->nb_rx_queues; i++, j++) {
    1202                 :          0 :                         rxq = dev->data->rx_queues[i];
    1203   [ #  #  #  # ]:          0 :                         if (rxq == NULL || j >= len)
    1204                 :            :                                 return -EINVAL;
    1205                 :            :                         cpfl_rxq = (struct cpfl_rx_queue *)rxq;
    1206                 :          0 :                         peer_ports[j] = cpfl_rxq->hairpin_info.peer_txp;
    1207                 :            :                 }
    1208                 :            :         }
    1209                 :            : 
    1210                 :          0 :         return j;
    1211                 :            : }
    1212                 :            : 
    1213                 :            : static int
    1214                 :          0 : cpfl_hairpin_bind(struct rte_eth_dev *dev, uint16_t rx_port)
    1215                 :            : {
    1216                 :          0 :         struct cpfl_vport *cpfl_tx_vport = dev->data->dev_private;
    1217                 :          0 :         struct idpf_vport *tx_vport = &cpfl_tx_vport->base;
    1218                 :            :         struct cpfl_vport *cpfl_rx_vport;
    1219                 :            :         struct cpfl_tx_queue *cpfl_txq;
    1220                 :            :         struct cpfl_rx_queue *cpfl_rxq;
    1221                 :            :         struct rte_eth_dev *peer_dev;
    1222                 :            :         struct idpf_vport *rx_vport;
    1223                 :            :         int err = 0;
    1224                 :            :         int i;
    1225                 :            : 
    1226                 :          0 :         err = cpfl_txq_hairpin_info_update(dev, rx_port);
    1227         [ #  # ]:          0 :         if (err != 0) {
    1228                 :          0 :                 PMD_DRV_LOG(ERR, "Fail to update Tx hairpin queue info.");
    1229                 :          0 :                 return err;
    1230                 :            :         }
    1231                 :            : 
    1232                 :            :         /* configure hairpin queues */
    1233         [ #  # ]:          0 :         for (i = cpfl_tx_vport->nb_data_txq; i < dev->data->nb_tx_queues; i++) {
    1234                 :          0 :                 cpfl_txq = dev->data->tx_queues[i];
    1235                 :          0 :                 err = cpfl_hairpin_txq_config(tx_vport, cpfl_txq);
    1236         [ #  # ]:          0 :                 if (err != 0) {
    1237                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to configure hairpin Tx queue %u", i);
    1238                 :          0 :                         return err;
    1239                 :            :                 }
    1240                 :            :         }
    1241                 :            : 
    1242                 :          0 :         err = cpfl_hairpin_tx_complq_config(cpfl_tx_vport);
    1243         [ #  # ]:          0 :         if (err != 0) {
    1244                 :          0 :                 PMD_DRV_LOG(ERR, "Fail to config Tx completion queue");
    1245                 :          0 :                 return err;
    1246                 :            :         }
    1247                 :            : 
    1248                 :          0 :         peer_dev = &rte_eth_devices[rx_port];
    1249                 :          0 :         cpfl_rx_vport = (struct cpfl_vport *)peer_dev->data->dev_private;
    1250                 :          0 :         rx_vport = &cpfl_rx_vport->base;
    1251                 :          0 :         cpfl_rxq_hairpin_mz_bind(peer_dev);
    1252                 :            : 
    1253                 :          0 :         err = cpfl_hairpin_rx_bufq_config(cpfl_rx_vport);
    1254         [ #  # ]:          0 :         if (err != 0) {
    1255                 :          0 :                 PMD_DRV_LOG(ERR, "Fail to config Rx buffer queue");
    1256                 :          0 :                 return err;
    1257                 :            :         }
    1258                 :            : 
    1259         [ #  # ]:          0 :         for (i = cpfl_rx_vport->nb_data_rxq; i < peer_dev->data->nb_rx_queues; i++) {
    1260                 :          0 :                 cpfl_rxq = peer_dev->data->rx_queues[i];
    1261                 :          0 :                 err = cpfl_hairpin_rxq_config(rx_vport, cpfl_rxq);
    1262         [ #  # ]:          0 :                 if (err != 0) {
    1263                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to configure hairpin Rx queue %u", i);
    1264                 :          0 :                         return err;
    1265                 :            :                 }
    1266                 :          0 :                 err = cpfl_rx_queue_init(peer_dev, i);
    1267         [ #  # ]:          0 :                 if (err != 0) {
    1268                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to init hairpin Rx queue %u", i);
    1269                 :          0 :                         return err;
    1270                 :            :                 }
    1271                 :            :         }
    1272                 :            : 
    1273                 :            :         /* enable hairpin queues */
    1274         [ #  # ]:          0 :         for (i = cpfl_tx_vport->nb_data_txq; i < dev->data->nb_tx_queues; i++) {
    1275                 :            :                 cpfl_txq = dev->data->tx_queues[i];
    1276                 :          0 :                 err = cpfl_switch_hairpin_rxtx_queue(cpfl_tx_vport,
    1277                 :          0 :                                                      i - cpfl_tx_vport->nb_data_txq,
    1278                 :            :                                                      false, true);
    1279         [ #  # ]:          0 :                 if (err != 0) {
    1280                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to switch hairpin TX queue %u on",
    1281                 :            :                                     i);
    1282                 :          0 :                         return err;
    1283                 :            :                 }
    1284                 :            :         }
    1285                 :            : 
    1286                 :          0 :         err = cpfl_switch_hairpin_complq(cpfl_tx_vport, true);
    1287         [ #  # ]:          0 :         if (err != 0) {
    1288                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to switch hairpin Tx complq");
    1289                 :          0 :                 return err;
    1290                 :            :         }
    1291                 :            : 
    1292         [ #  # ]:          0 :         for (i = cpfl_rx_vport->nb_data_rxq; i < peer_dev->data->nb_rx_queues; i++) {
    1293                 :          0 :                 cpfl_rxq = peer_dev->data->rx_queues[i];
    1294                 :          0 :                 err = cpfl_switch_hairpin_rxtx_queue(cpfl_rx_vport,
    1295                 :          0 :                                                      i - cpfl_rx_vport->nb_data_rxq,
    1296                 :            :                                                      true, true);
    1297         [ #  # ]:          0 :                 if (err != 0) {
    1298                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to switch hairpin RX queue %u on",
    1299                 :            :                                     i);
    1300                 :            :                 }
    1301                 :          0 :                 cpfl_rxq->base.q_started = true;
    1302                 :            :         }
    1303                 :            : 
    1304                 :          0 :         err = cpfl_switch_hairpin_bufq(cpfl_rx_vport, true);
    1305         [ #  # ]:          0 :         if (err != 0) {
    1306                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to switch hairpin Rx buffer queue");
    1307                 :          0 :                 return err;
    1308                 :            :         }
    1309                 :            : 
    1310                 :            :         return 0;
    1311                 :            : }
    1312                 :            : 
    1313                 :            : static int
    1314                 :          0 : cpfl_hairpin_unbind(struct rte_eth_dev *dev, uint16_t rx_port)
    1315                 :            : {
    1316                 :          0 :         struct cpfl_vport *cpfl_tx_vport = dev->data->dev_private;
    1317                 :          0 :         struct rte_eth_dev *peer_dev = &rte_eth_devices[rx_port];
    1318                 :          0 :         struct cpfl_vport *cpfl_rx_vport = peer_dev->data->dev_private;
    1319                 :            :         struct cpfl_rx_queue *cpfl_rxq;
    1320                 :            :         int i;
    1321                 :            : 
    1322                 :            :         /* disable hairpin queues */
    1323         [ #  # ]:          0 :         for (i = cpfl_tx_vport->nb_data_txq; i < dev->data->nb_tx_queues; i++) {
    1324                 :          0 :                 cpfl_switch_hairpin_rxtx_queue(cpfl_tx_vport,
    1325                 :          0 :                                                i - cpfl_tx_vport->nb_data_txq,
    1326                 :            :                                                false, false);
    1327                 :            :         }
    1328                 :            : 
    1329                 :          0 :         cpfl_switch_hairpin_complq(cpfl_tx_vport, false);
    1330                 :            : 
    1331         [ #  # ]:          0 :         for (i = cpfl_rx_vport->nb_data_rxq; i < peer_dev->data->nb_rx_queues; i++) {
    1332                 :          0 :                 cpfl_rxq = peer_dev->data->rx_queues[i];
    1333                 :          0 :                 cpfl_switch_hairpin_rxtx_queue(cpfl_rx_vport,
    1334                 :          0 :                                                i - cpfl_rx_vport->nb_data_rxq,
    1335                 :            :                                                true, false);
    1336                 :          0 :                 cpfl_rxq->base.q_started = false;
    1337                 :            :         }
    1338                 :            : 
    1339                 :          0 :         cpfl_switch_hairpin_bufq(cpfl_rx_vport, false);
    1340                 :            : 
    1341                 :          0 :         return 0;
    1342                 :            : }
    1343                 :            : 
    1344                 :            : static int
    1345                 :          0 : cpfl_timesync_enable(struct rte_eth_dev *dev)
    1346                 :            : {
    1347                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    1348                 :            :         struct idpf_vport *vport = &cpfl_vport->base;
    1349                 :          0 :         struct idpf_adapter *adapter = vport->adapter;
    1350                 :            :         struct timespec sys_ts;
    1351                 :            :         uint64_t ns;
    1352                 :            :         int ret;
    1353                 :            : 
    1354   [ #  #  #  # ]:          0 :         if (dev->data->dev_started && !(dev->data->dev_conf.rxmode.offloads &
    1355                 :            :             RTE_ETH_RX_OFFLOAD_TIMESTAMP)) {
    1356                 :          0 :                 PMD_DRV_LOG(ERR, "Rx timestamp offload not configured");
    1357                 :          0 :                 return -1;
    1358                 :            :         }
    1359                 :            : 
    1360                 :            :         /* PTP state is shared by all vports of the adapter. */
    1361         [ #  # ]:          0 :         if (adapter->ptp != NULL)
    1362                 :            :                 return 0;
    1363                 :            : 
    1364                 :          0 :         adapter->ptp = rte_zmalloc(NULL, sizeof(struct idpf_ptp), 0);
    1365         [ #  # ]:          0 :         if (adapter->ptp == NULL) {
    1366                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for PTP");
    1367                 :          0 :                 return -ENOMEM;
    1368                 :            :         }
    1369                 :            : 
    1370                 :          0 :         ret = idpf_ptp_get_caps(adapter);
    1371         [ #  # ]:          0 :         if (ret) {
    1372                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to get PTP capabilities, err=%d", ret);
    1373                 :          0 :                 goto fail_ptp;
    1374                 :            :         }
    1375                 :            : 
    1376                 :            :         /*
    1377                 :            :          * Write the default increment time value if the clock adjustments
    1378                 :            :          * are enabled.
    1379                 :            :          */
    1380         [ #  # ]:          0 :         if (adapter->ptp->adj_dev_clk_time_access != IDPF_PTP_NONE) {
    1381                 :          0 :                 ret = idpf_ptp_adj_dev_clk_fine(adapter, adapter->ptp->base_incval);
    1382         [ #  # ]:          0 :                 if (ret) {
    1383                 :          0 :                         PMD_DRV_LOG(ERR, "PTP set incval failed, err=%d", ret);
    1384                 :          0 :                         goto fail_ptp;
    1385                 :            :                 }
    1386                 :            :         }
    1387                 :            : 
    1388                 :            :         /* Do not initialize the PTP if the device clock time cannot be read. */
    1389         [ #  # ]:          0 :         if (adapter->ptp->get_dev_clk_time_access == IDPF_PTP_NONE) {
    1390                 :          0 :                 PMD_DRV_LOG(ERR, "Getting device clock time is not supported");
    1391                 :            :                 ret = -EIO;
    1392                 :          0 :                 goto fail_ptp;
    1393                 :            :         }
    1394                 :            : 
    1395                 :            :         /* Set the device clock time to system time. */
    1396         [ #  # ]:          0 :         if (adapter->ptp->set_dev_clk_time_access != IDPF_PTP_NONE) {
    1397                 :          0 :                 clock_gettime(CLOCK_REALTIME, &sys_ts);
    1398                 :            :                 ns = rte_timespec_to_ns(&sys_ts);
    1399                 :          0 :                 ret = idpf_ptp_set_dev_clk_time(adapter, ns);
    1400         [ #  # ]:          0 :                 if (ret) {
    1401                 :          0 :                         PMD_DRV_LOG(ERR, "PTP set clock time failed, err=%d", ret);
    1402                 :          0 :                         goto fail_ptp;
    1403                 :            :                 }
    1404                 :            :         }
    1405                 :            : 
    1406                 :          0 :         adapter->ptp->cmd.shtime_enable_mask = PF_GLTSYN_CMD_SYNC_SHTIME_EN_M;
    1407                 :          0 :         adapter->ptp->cmd.exec_cmd_mask = PF_GLTSYN_CMD_SYNC_EXEC_CMD_M;
    1408                 :            : 
    1409                 :          0 :         return 0;
    1410                 :            : 
    1411                 :          0 : fail_ptp:
    1412                 :          0 :         rte_free(adapter->ptp);
    1413                 :          0 :         adapter->ptp = NULL;
    1414                 :          0 :         return ret;
    1415                 :            : }
    1416                 :            : 
    1417                 :            : static int
    1418                 :          0 : cpfl_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
    1419                 :            : {
    1420                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    1421                 :          0 :         struct idpf_adapter *adapter = cpfl_vport->base.adapter;
    1422                 :            :         uint64_t time;
    1423                 :            :         int ret;
    1424                 :            : 
    1425                 :          0 :         ret = idpf_ptp_read_src_clk_reg(adapter, &time);
    1426         [ #  # ]:          0 :         if (ret)
    1427                 :          0 :                 PMD_DRV_LOG(ERR, "PTP read time failed, err %d", ret);
    1428                 :            :         else
    1429         [ #  # ]:          0 :                 *ts = rte_ns_to_timespec(time);
    1430                 :            : 
    1431                 :          0 :         return ret;
    1432                 :            : }
    1433                 :            : 
    1434                 :            : static int
    1435                 :          0 : cpfl_timesync_disable(struct rte_eth_dev *dev)
    1436                 :            : {
    1437                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    1438                 :          0 :         struct idpf_adapter *adapter = cpfl_vport->base.adapter;
    1439                 :            : 
    1440         [ #  # ]:          0 :         if (adapter->ptp != NULL) {
    1441                 :          0 :                 rte_free(adapter->ptp);
    1442                 :          0 :                 adapter->ptp = NULL;
    1443                 :            :         }
    1444                 :            : 
    1445                 :          0 :         return 0;
    1446                 :            : }
    1447                 :            : 
    1448                 :            : static const struct eth_dev_ops cpfl_eth_dev_ops = {
    1449                 :            :         .dev_configure                  = cpfl_dev_configure,
    1450                 :            :         .dev_close                      = cpfl_dev_close,
    1451                 :            :         .rx_queue_setup                 = cpfl_rx_queue_setup,
    1452                 :            :         .tx_queue_setup                 = cpfl_tx_queue_setup,
    1453                 :            :         .dev_infos_get                  = cpfl_dev_info_get,
    1454                 :            :         .dev_start                      = cpfl_dev_start,
    1455                 :            :         .dev_stop                       = cpfl_dev_stop,
    1456                 :            :         .link_update                    = cpfl_dev_link_update,
    1457                 :            :         .rx_queue_start                 = cpfl_rx_queue_start,
    1458                 :            :         .tx_queue_start                 = cpfl_tx_queue_start,
    1459                 :            :         .rx_queue_stop                  = cpfl_rx_queue_stop,
    1460                 :            :         .tx_queue_stop                  = cpfl_tx_queue_stop,
    1461                 :            :         .rx_queue_release               = cpfl_dev_rx_queue_release,
    1462                 :            :         .tx_queue_release               = cpfl_dev_tx_queue_release,
    1463                 :            :         .mtu_set                        = cpfl_dev_mtu_set,
    1464                 :            :         .dev_supported_ptypes_get       = cpfl_dev_supported_ptypes_get,
    1465                 :            :         .stats_get                      = cpfl_dev_stats_get,
    1466                 :            :         .stats_reset                    = cpfl_dev_stats_reset,
    1467                 :            :         .reta_update                    = cpfl_rss_reta_update,
    1468                 :            :         .reta_query                     = cpfl_rss_reta_query,
    1469                 :            :         .rss_hash_update                = cpfl_rss_hash_update,
    1470                 :            :         .rss_hash_conf_get              = cpfl_rss_hash_conf_get,
    1471                 :            :         .xstats_get                     = cpfl_dev_xstats_get,
    1472                 :            :         .xstats_get_names               = cpfl_dev_xstats_get_names,
    1473                 :            :         .xstats_reset                   = cpfl_dev_xstats_reset,
    1474                 :            :         .flow_ops_get                   = cpfl_dev_flow_ops_get,
    1475                 :            :         .hairpin_cap_get                = cpfl_hairpin_cap_get,
    1476                 :            :         .rx_hairpin_queue_setup         = cpfl_rx_hairpin_queue_setup,
    1477                 :            :         .tx_hairpin_queue_setup         = cpfl_tx_hairpin_queue_setup,
    1478                 :            :         .hairpin_get_peer_ports         = cpfl_hairpin_get_peer_ports,
    1479                 :            :         .hairpin_bind                   = cpfl_hairpin_bind,
    1480                 :            :         .hairpin_unbind                 = cpfl_hairpin_unbind,
    1481                 :            :         .timesync_enable                = cpfl_timesync_enable,
    1482                 :            :         .timesync_read_time             = cpfl_timesync_read_time,
    1483                 :            :         .timesync_disable               = cpfl_timesync_disable,
    1484                 :            : };
    1485                 :            : 
    1486                 :            : static int
    1487                 :            : insert_value(struct cpfl_devargs *devargs, uint16_t id)
    1488                 :            : {
    1489                 :            :         uint16_t i;
    1490                 :            : 
    1491                 :            :         /* ignore duplicate */
    1492   [ #  #  #  # ]:          0 :         for (i = 0; i < devargs->req_vport_nb; i++) {
    1493   [ #  #  #  # ]:          0 :                 if (devargs->req_vports[i] == id)
    1494                 :            :                         return 0;
    1495                 :            :         }
    1496                 :            : 
    1497                 :          0 :         devargs->req_vports[devargs->req_vport_nb] = id;
    1498                 :          0 :         devargs->req_vport_nb++;
    1499                 :            : 
    1500                 :          0 :         return 0;
    1501                 :            : }
    1502                 :            : 
    1503                 :            : static const char *
    1504                 :          0 : parse_range(const char *value, struct cpfl_devargs *devargs)
    1505                 :            : {
    1506                 :            :         uint16_t lo, hi, i;
    1507                 :          0 :         int n = 0;
    1508                 :            :         int result;
    1509                 :            :         const char *pos = value;
    1510                 :            : 
    1511                 :          0 :         result = sscanf(value, "%hu%n-%hu%n", &lo, &n, &hi, &n);
    1512         [ #  # ]:          0 :         if (result == 1) {
    1513                 :          0 :                 if (insert_value(devargs, lo) != 0)
    1514                 :            :                         return NULL;
    1515         [ #  # ]:          0 :         } else if (result == 2) {
    1516         [ #  # ]:          0 :                 if (lo > hi)
    1517                 :            :                         return NULL;
    1518         [ #  # ]:          0 :                 for (i = lo; i <= hi; i++) {
    1519                 :            :                         if (insert_value(devargs, i) != 0)
    1520                 :            :                                 return NULL;
    1521                 :            :                 }
    1522                 :            :         } else {
    1523                 :            :                 return NULL;
    1524                 :            :         }
    1525                 :            : 
    1526                 :          0 :         return pos + n;
    1527                 :            : }
    1528                 :            : 
    1529                 :            : static int
    1530                 :          0 : parse_vport(const char *key, const char *value, void *args)
    1531                 :            : {
    1532                 :            :         struct cpfl_devargs *devargs = args;
    1533                 :            :         const char *pos = value;
    1534                 :            : 
    1535                 :          0 :         devargs->req_vport_nb = 0;
    1536                 :            : 
    1537         [ #  # ]:          0 :         if (*pos == '[')
    1538                 :          0 :                 pos++;
    1539                 :            : 
    1540                 :            :         while (1) {
    1541                 :          0 :                 pos = parse_range(pos, devargs);
    1542         [ #  # ]:          0 :                 if (pos == NULL) {
    1543                 :          0 :                         PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", ",
    1544                 :            :                                      value, key);
    1545                 :          0 :                         return -EINVAL;
    1546                 :            :                 }
    1547         [ #  # ]:          0 :                 if (*pos != ',')
    1548                 :            :                         break;
    1549                 :          0 :                 pos++;
    1550                 :            :         }
    1551                 :            : 
    1552   [ #  #  #  # ]:          0 :         if (*value == '[' && *pos != ']') {
    1553                 :          0 :                 PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", ",
    1554                 :            :                              value, key);
    1555                 :          0 :                 return -EINVAL;
    1556                 :            :         }
    1557                 :            : 
    1558                 :            :         return 0;
    1559                 :            : }
    1560                 :            : 
    1561                 :            : static int
    1562                 :          0 : parse_bool(const char *key, const char *value, void *args)
    1563                 :            : {
    1564                 :            :         bool *i = args;
    1565                 :            :         char *end;
    1566                 :            :         int num;
    1567                 :            : 
    1568                 :          0 :         errno = 0;
    1569                 :            : 
    1570                 :          0 :         num = strtoul(value, &end, 10);
    1571                 :            : 
    1572   [ #  #  #  # ]:          0 :         if (errno == ERANGE || (num != 0 && num != 1)) {
    1573                 :          0 :                 PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", value must be 0 or 1",
    1574                 :            :                         value, key);
    1575                 :          0 :                 return -EINVAL;
    1576                 :            :         }
    1577                 :            : 
    1578                 :          0 :         *i = (num == 1);
    1579                 :          0 :         return 0;
    1580                 :            : }
    1581                 :            : 
    1582                 :            : static int
    1583                 :            : enlist(uint16_t *list, uint16_t *len_list, const uint16_t max_list, uint16_t val)
    1584                 :            : {
    1585                 :            :         uint16_t i;
    1586                 :            : 
    1587   [ #  #  #  # ]:          0 :         for (i = 0; i < *len_list; i++) {
    1588   [ #  #  #  # ]:          0 :                 if (list[i] == val)
    1589                 :            :                         return 0;
    1590                 :            :         }
    1591   [ #  #  #  # ]:          0 :         if (*len_list >= max_list)
    1592                 :            :                 return -1;
    1593                 :          0 :         list[(*len_list)++] = val;
    1594                 :            :         return 0;
    1595                 :            : }
    1596                 :            : 
    1597                 :            : static const char *
    1598                 :          0 : process_range(const char *str, uint16_t *list, uint16_t *len_list,
    1599                 :            :         const uint16_t max_list)
    1600                 :            : {
    1601                 :            :         uint16_t lo, hi, val;
    1602                 :          0 :         int result, n = 0;
    1603                 :            :         const char *pos = str;
    1604                 :            : 
    1605                 :          0 :         result = sscanf(str, "%hu%n-%hu%n", &lo, &n, &hi, &n);
    1606         [ #  # ]:          0 :         if (result == 1) {
    1607                 :          0 :                 if (enlist(list, len_list, max_list, lo) != 0)
    1608                 :            :                         return NULL;
    1609         [ #  # ]:          0 :         } else if (result == 2) {
    1610         [ #  # ]:          0 :                 if (lo > hi)
    1611                 :            :                         return NULL;
    1612         [ #  # ]:          0 :                 for (val = lo; val <= hi; val++) {
    1613                 :            :                         if (enlist(list, len_list, max_list, val) != 0)
    1614                 :            :                                 return NULL;
    1615                 :            :                 }
    1616                 :            :         } else {
    1617                 :            :                 return NULL;
    1618                 :            :         }
    1619                 :          0 :         return pos + n;
    1620                 :            : }
    1621                 :            : 
    1622                 :            : static const char *
    1623                 :          0 : process_list(const char *str, uint16_t *list, uint16_t *len_list, const uint16_t max_list)
    1624                 :            : {
    1625                 :            :         const char *pos = str;
    1626                 :            : 
    1627         [ #  # ]:          0 :         if (*pos == '[')
    1628                 :          0 :                 pos++;
    1629                 :            :         while (1) {
    1630                 :          0 :                 pos = process_range(pos, list, len_list, max_list);
    1631         [ #  # ]:          0 :                 if (pos == NULL)
    1632                 :            :                         return NULL;
    1633         [ #  # ]:          0 :                 if (*pos != ',') /* end of list */
    1634                 :            :                         break;
    1635                 :          0 :                 pos++;
    1636                 :            :         }
    1637   [ #  #  #  # ]:          0 :         if (*str == '[' && *pos != ']')
    1638                 :            :                 return NULL;
    1639         [ #  # ]:          0 :         if (*pos == ']')
    1640                 :          0 :                 pos++;
    1641                 :            :         return pos;
    1642                 :            : }
    1643                 :            : 
    1644                 :            : static int
    1645                 :          0 : parse_repr(const char *key __rte_unused, const char *value, void *args)
    1646                 :            : {
    1647                 :            :         struct cpfl_devargs *devargs = args;
    1648                 :            :         struct rte_eth_devargs *eth_da;
    1649                 :            :         const char *str = value;
    1650                 :            : 
    1651         [ #  # ]:          0 :         if (devargs->repr_args_num == CPFL_REPR_ARG_NUM_MAX)
    1652                 :            :                 return -EINVAL;
    1653                 :            : 
    1654                 :          0 :         eth_da = &devargs->repr_args[devargs->repr_args_num];
    1655                 :            : 
    1656         [ #  # ]:          0 :         if (str[0] == 'c') {
    1657                 :          0 :                 str += 1;
    1658                 :          0 :                 str = process_list(str, eth_da->mh_controllers,
    1659                 :            :                                 &eth_da->nb_mh_controllers,
    1660                 :            :                                 RTE_DIM(eth_da->mh_controllers));
    1661         [ #  # ]:          0 :                 if (str == NULL)
    1662                 :          0 :                         goto done;
    1663                 :            :         }
    1664   [ #  #  #  # ]:          0 :         if (str[0] == 'p' && str[1] == 'f') {
    1665                 :          0 :                 eth_da->type = RTE_ETH_REPRESENTOR_PF;
    1666                 :          0 :                 str += 2;
    1667                 :          0 :                 str = process_list(str, eth_da->ports,
    1668                 :            :                                 &eth_da->nb_ports, RTE_DIM(eth_da->ports));
    1669   [ #  #  #  # ]:          0 :                 if (str == NULL || str[0] == '\0')
    1670                 :          0 :                         goto done;
    1671         [ #  # ]:          0 :         } else if (eth_da->nb_mh_controllers > 0) {
    1672                 :            :                 /* 'c' must followed by 'pf'. */
    1673                 :            :                 str = NULL;
    1674                 :          0 :                 goto done;
    1675                 :            :         }
    1676   [ #  #  #  # ]:          0 :         if (str[0] == 'v' && str[1] == 'f') {
    1677                 :          0 :                 eth_da->type = RTE_ETH_REPRESENTOR_VF;
    1678                 :          0 :                 str += 2;
    1679   [ #  #  #  # ]:          0 :         } else if (str[0] == 's' && str[1] == 'f') {
    1680                 :          0 :                 eth_da->type = RTE_ETH_REPRESENTOR_SF;
    1681                 :          0 :                 str += 2;
    1682                 :            :         } else {
    1683                 :            :                 /* 'pf' must followed by 'vf' or 'sf'. */
    1684         [ #  # ]:          0 :                 if (eth_da->type == RTE_ETH_REPRESENTOR_PF) {
    1685                 :            :                         str = NULL;
    1686                 :          0 :                         goto done;
    1687                 :            :                 }
    1688                 :          0 :                 eth_da->type = RTE_ETH_REPRESENTOR_VF;
    1689                 :            :         }
    1690                 :          0 :         str = process_list(str, eth_da->representor_ports,
    1691                 :            :                 &eth_da->nb_representor_ports,
    1692                 :            :                 RTE_DIM(eth_da->representor_ports));
    1693                 :          0 : done:
    1694         [ #  # ]:          0 :         if (str == NULL) {
    1695                 :          0 :                 PMD_DRV_LOG(ERR, "wrong representor format: %s", value);
    1696                 :          0 :                 return -1;
    1697                 :            :         }
    1698                 :            : 
    1699                 :          0 :         devargs->repr_args_num++;
    1700                 :            : 
    1701                 :          0 :         return 0;
    1702                 :            : }
    1703                 :            : 
    1704                 :            : #ifdef RTE_HAS_JANSSON
    1705                 :            : static int
    1706                 :          0 : parse_file(const char *key, const char *value, void *args)
    1707                 :            : {
    1708                 :            :         char *name = args;
    1709                 :            : 
    1710         [ #  # ]:          0 :         if (strlen(value) > CPFL_FLOW_FILE_LEN - 1) {
    1711                 :          0 :                 PMD_DRV_LOG(ERR, "file path(%s) is too long.", value);
    1712                 :          0 :                 return -1;
    1713                 :            :         }
    1714                 :            : 
    1715                 :          0 :         PMD_DRV_LOG(DEBUG, "value:\"%s\" for key:\"%s\"", value, key);
    1716                 :            :         strlcpy(name, value, CPFL_FLOW_FILE_LEN);
    1717                 :            : 
    1718                 :          0 :         return 0;
    1719                 :            : }
    1720                 :            : #endif
    1721                 :            : 
    1722                 :            : static int
    1723                 :          0 : cpfl_parse_devargs(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adapter,
    1724                 :            :                    bool first, struct cpfl_devargs *cpfl_args)
    1725                 :            : {
    1726                 :          0 :         struct rte_devargs *devargs = pci_dev->device.devargs;
    1727                 :            :         struct rte_kvargs *kvlist;
    1728                 :            :         int ret;
    1729                 :            : 
    1730         [ #  # ]:          0 :         if (devargs == NULL)
    1731                 :            :                 return 0;
    1732                 :            : 
    1733         [ #  # ]:          0 :         kvlist = rte_kvargs_parse(devargs->args,
    1734                 :            :                         first ? cpfl_valid_args_first : cpfl_valid_args_again);
    1735         [ #  # ]:          0 :         if (kvlist == NULL) {
    1736                 :          0 :                 PMD_INIT_LOG(ERR, "invalid kvargs key");
    1737                 :          0 :                 return -EINVAL;
    1738                 :            :         }
    1739                 :            : 
    1740         [ #  # ]:          0 :         if (rte_kvargs_count(kvlist, CPFL_VPORT) > 1) {
    1741                 :          0 :                 PMD_INIT_LOG(ERR, "devarg vport is duplicated.");
    1742                 :            :                 ret = -EINVAL;
    1743                 :          0 :                 goto fail;
    1744                 :            :         }
    1745                 :            : 
    1746                 :          0 :         ret = rte_kvargs_process(kvlist, CPFL_REPRESENTOR, &parse_repr, cpfl_args);
    1747                 :            : 
    1748         [ #  # ]:          0 :         if (ret != 0)
    1749                 :          0 :                 goto fail;
    1750                 :            : 
    1751         [ #  # ]:          0 :         if (!first)
    1752                 :          0 :                 goto finish;
    1753                 :            : 
    1754                 :          0 :         ret = rte_kvargs_process(kvlist, CPFL_VPORT, &parse_vport,
    1755                 :            :                                  cpfl_args);
    1756         [ #  # ]:          0 :         if (ret != 0)
    1757                 :          0 :                 goto fail;
    1758                 :            : 
    1759                 :          0 :         ret = rte_kvargs_process(kvlist, CPFL_TX_SINGLE_Q, &parse_bool,
    1760                 :          0 :                                  &adapter->base.is_tx_singleq);
    1761         [ #  # ]:          0 :         if (ret != 0)
    1762                 :          0 :                 goto fail;
    1763                 :            : 
    1764                 :          0 :         ret = rte_kvargs_process(kvlist, CPFL_RX_SINGLE_Q, &parse_bool,
    1765                 :          0 :                                  &adapter->base.is_rx_singleq);
    1766         [ #  # ]:          0 :         if (ret != 0)
    1767                 :          0 :                 goto fail;
    1768                 :            : #ifdef RTE_HAS_JANSSON
    1769         [ #  # ]:          0 :         if (rte_kvargs_get(kvlist, CPFL_FLOW_PARSER)) {
    1770                 :          0 :                 ret = rte_kvargs_process(kvlist, CPFL_FLOW_PARSER,
    1771                 :          0 :                                          &parse_file, cpfl_args->flow_parser);
    1772         [ #  # ]:          0 :                 if (ret) {
    1773                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to parser flow_parser, ret: %d", ret);
    1774                 :          0 :                         goto fail;
    1775                 :            :                 }
    1776                 :            :         } else {
    1777                 :          0 :                 cpfl_args->flow_parser[0] = '\0';
    1778                 :            :         }
    1779                 :            : #endif
    1780                 :          0 : finish:
    1781                 :          0 : fail:
    1782                 :          0 :         rte_kvargs_free(kvlist);
    1783                 :          0 :         return ret;
    1784                 :            : }
    1785                 :            : 
    1786                 :            : static struct cpfl_vport *
    1787                 :            : cpfl_find_vport(struct cpfl_adapter_ext *adapter, uint32_t vport_id)
    1788                 :            : {
    1789                 :            :         struct cpfl_vport *vport = NULL;
    1790                 :            :         int i;
    1791                 :            : 
    1792         [ #  # ]:          0 :         for (i = 0; i < adapter->cur_vport_nb; i++) {
    1793                 :          0 :                 vport = adapter->vports[i];
    1794         [ #  # ]:          0 :                 if (vport == NULL)
    1795                 :          0 :                         continue;
    1796         [ #  # ]:          0 :                 if (vport->base.vport_id != vport_id)
    1797                 :          0 :                         continue;
    1798                 :            :                 else
    1799                 :            :                         return vport;
    1800                 :            :         }
    1801                 :            : 
    1802                 :            :         return NULL;
    1803                 :            : }
    1804                 :            : 
    1805                 :            : static void
    1806                 :          0 : cpfl_handle_vchnl_event_msg(struct cpfl_adapter_ext *adapter, uint8_t *msg, uint16_t msglen)
    1807                 :            : {
    1808                 :            :         struct virtchnl2_event *vc_event = (struct virtchnl2_event *)msg;
    1809                 :            :         struct cpfl_vport *vport;
    1810                 :            :         struct rte_eth_dev_data *data;
    1811                 :            :         struct rte_eth_dev *dev;
    1812                 :            : 
    1813         [ #  # ]:          0 :         if (msglen < sizeof(struct virtchnl2_event)) {
    1814                 :          0 :                 PMD_DRV_LOG(ERR, "Error event");
    1815                 :          0 :                 return;
    1816                 :            :         }
    1817                 :            : 
    1818                 :            :         /* ignore if it is ctrl vport */
    1819         [ #  # ]:          0 :         if (!idpf_is_vf_device(&adapter->base.hw) &&
    1820         [ #  # ]:          0 :                         adapter->ctrl_vport.base.vport_id == vc_event->vport_id)
    1821                 :            :                 return;
    1822                 :            : 
    1823                 :          0 :         vport = cpfl_find_vport(adapter, vc_event->vport_id);
    1824         [ #  # ]:          0 :         if (!vport) {
    1825                 :          0 :                 PMD_DRV_LOG(ERR, "Can't find vport.");
    1826                 :          0 :                 return;
    1827                 :            :         }
    1828                 :            : 
    1829                 :          0 :         data = vport->itf.data;
    1830                 :          0 :         dev = &rte_eth_devices[data->port_id];
    1831                 :            : 
    1832         [ #  # ]:          0 :         switch (vc_event->event) {
    1833                 :          0 :         case VIRTCHNL2_EVENT_LINK_CHANGE:
    1834                 :          0 :                 PMD_DRV_LOG(DEBUG, "VIRTCHNL2_EVENT_LINK_CHANGE");
    1835                 :          0 :                 vport->base.link_up = !!(vc_event->link_status);
    1836                 :          0 :                 vport->base.link_speed = vc_event->link_speed;
    1837                 :          0 :                 cpfl_dev_link_update(dev, 0);
    1838                 :          0 :                 break;
    1839                 :          0 :         default:
    1840                 :          0 :                 PMD_DRV_LOG(ERR, " unknown event received %u", vc_event->event);
    1841                 :          0 :                 break;
    1842                 :            :         }
    1843                 :            : }
    1844                 :            : 
    1845                 :            : int
    1846                 :          0 : cpfl_vport_info_create(struct cpfl_adapter_ext *adapter,
    1847                 :            :                        struct cpfl_vport_id *vport_identity,
    1848                 :            :                        struct cpchnl2_event_vport_created *vport_created)
    1849                 :            : {
    1850                 :          0 :         struct cpfl_vport_info *info = NULL;
    1851                 :            :         int ret;
    1852                 :            : 
    1853                 :          0 :         rte_spinlock_lock(&adapter->vport_map_lock);
    1854                 :          0 :         ret = rte_hash_lookup_data(adapter->vport_map_hash, vport_identity, (void **)&info);
    1855         [ #  # ]:          0 :         if (ret >= 0) {
    1856                 :          0 :                 PMD_DRV_LOG(WARNING, "vport already exist, overwrite info anyway");
    1857                 :            :                 /* overwrite info */
    1858         [ #  # ]:          0 :                 if (info)
    1859                 :          0 :                         info->vport = *vport_created;
    1860                 :          0 :                 goto fini;
    1861                 :            :         }
    1862                 :            : 
    1863                 :          0 :         info = rte_zmalloc(NULL, sizeof(*info), 0);
    1864         [ #  # ]:          0 :         if (info == NULL) {
    1865                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc memory for vport map info");
    1866                 :            :                 ret = -ENOMEM;
    1867                 :          0 :                 goto err;
    1868                 :            :         }
    1869                 :            : 
    1870                 :          0 :         info->vport = *vport_created;
    1871                 :            : 
    1872                 :          0 :         ret = rte_hash_add_key_data(adapter->vport_map_hash, vport_identity, info);
    1873         [ #  # ]:          0 :         if (ret < 0) {
    1874                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to add vport map into hash");
    1875                 :          0 :                 rte_free(info);
    1876                 :          0 :                 goto err;
    1877                 :            :         }
    1878                 :            : 
    1879                 :          0 : fini:
    1880                 :            :         rte_spinlock_unlock(&adapter->vport_map_lock);
    1881                 :          0 :         return 0;
    1882                 :          0 : err:
    1883                 :            :         rte_spinlock_unlock(&adapter->vport_map_lock);
    1884                 :          0 :         return ret;
    1885                 :            : }
    1886                 :            : 
    1887                 :            : static int
    1888                 :          0 : cpfl_vport_info_destroy(struct cpfl_adapter_ext *adapter, struct cpfl_vport_id *vport_identity)
    1889                 :            : {
    1890                 :            :         struct cpfl_vport_info *info;
    1891                 :            :         int ret;
    1892                 :            : 
    1893                 :          0 :         rte_spinlock_lock(&adapter->vport_map_lock);
    1894                 :          0 :         ret = rte_hash_lookup_data(adapter->vport_map_hash, vport_identity, (void **)&info);
    1895         [ #  # ]:          0 :         if (ret < 0) {
    1896                 :          0 :                 PMD_DRV_LOG(ERR, "vport id doesn't exist");
    1897                 :          0 :                 goto err;
    1898                 :            :         }
    1899                 :            : 
    1900                 :          0 :         rte_hash_del_key(adapter->vport_map_hash, vport_identity);
    1901                 :            :         rte_spinlock_unlock(&adapter->vport_map_lock);
    1902                 :          0 :         rte_free(info);
    1903                 :            : 
    1904                 :          0 :         return 0;
    1905                 :            : 
    1906                 :            : err:
    1907                 :            :         rte_spinlock_unlock(&adapter->vport_map_lock);
    1908                 :          0 :         return ret;
    1909                 :            : }
    1910                 :            : 
    1911                 :            : static void
    1912                 :          0 : cpfl_handle_cpchnl_event_msg(struct cpfl_adapter_ext *adapter, uint8_t *msg, uint16_t msglen)
    1913                 :            : {
    1914                 :            :         struct cpchnl2_event_info *cpchnl2_event = (struct cpchnl2_event_info *)msg;
    1915                 :            :         struct cpchnl2_event_vport_created *vport_created;
    1916                 :          0 :         struct cpfl_vport_id vport_identity = { 0 };
    1917                 :            : 
    1918         [ #  # ]:          0 :         if (msglen < sizeof(struct cpchnl2_event_info)) {
    1919                 :          0 :                 PMD_DRV_LOG(ERR, "Error event");
    1920                 :          0 :                 return;
    1921                 :            :         }
    1922                 :            : 
    1923      [ #  #  # ]:          0 :         switch (cpchnl2_event->header.type) {
    1924                 :          0 :         case CPCHNL2_EVENT_VPORT_CREATED:
    1925                 :          0 :                 vport_identity.vport_id = cpchnl2_event->data.vport_created.vport.vport_id;
    1926                 :          0 :                 vport_created = &cpchnl2_event->data.vport_created;
    1927                 :          0 :                 vport_identity.func_type = vport_created->info.func_type;
    1928                 :          0 :                 vport_identity.pf_id = vport_created->info.pf_id;
    1929                 :          0 :                 vport_identity.vf_id = vport_created->info.vf_id;
    1930         [ #  # ]:          0 :                 if (cpfl_vport_info_create(adapter, &vport_identity, vport_created))
    1931                 :          0 :                         PMD_DRV_LOG(WARNING, "Failed to handle CPCHNL2_EVENT_VPORT_CREATED");
    1932                 :            :                 break;
    1933                 :          0 :         case CPCHNL2_EVENT_VPORT_DESTROYED:
    1934                 :          0 :                 vport_identity.vport_id = cpchnl2_event->data.vport_destroyed.vport.vport_id;
    1935                 :          0 :                 vport_identity.func_type = cpchnl2_event->data.vport_destroyed.func.func_type;
    1936                 :          0 :                 vport_identity.pf_id = cpchnl2_event->data.vport_destroyed.func.pf_id;
    1937                 :          0 :                 vport_identity.vf_id = cpchnl2_event->data.vport_destroyed.func.vf_id;
    1938         [ #  # ]:          0 :                 if (cpfl_vport_info_destroy(adapter, &vport_identity))
    1939                 :          0 :                         PMD_DRV_LOG(WARNING, "Failed to handle CPCHNL2_EVENT_VPORT_DESTROY");
    1940                 :            :                 break;
    1941                 :          0 :         default:
    1942                 :          0 :                 PMD_DRV_LOG(ERR, " unknown event received %u", cpchnl2_event->header.type);
    1943                 :          0 :                 break;
    1944                 :            :         }
    1945                 :            : }
    1946                 :            : 
    1947                 :            : static void
    1948                 :          0 : cpfl_handle_virtchnl_msg(struct cpfl_adapter_ext *adapter)
    1949                 :            : {
    1950                 :            :         struct idpf_adapter *base = &adapter->base;
    1951                 :          0 :         struct idpf_dma_mem *dma_mem = NULL;
    1952                 :          0 :         struct idpf_hw *hw = &base->hw;
    1953                 :            :         struct idpf_ctlq_msg ctlq_msg;
    1954                 :            :         enum idpf_mbx_opc mbx_op;
    1955                 :          0 :         uint16_t pending = 1;
    1956                 :            :         uint32_t vc_op;
    1957                 :            :         int ret;
    1958                 :            : 
    1959         [ #  # ]:          0 :         while (pending) {
    1960                 :          0 :                 ret = idpf_vc_ctlq_recv(hw->arq, &pending, &ctlq_msg);
    1961         [ #  # ]:          0 :                 if (ret) {
    1962                 :          0 :                         PMD_DRV_LOG(INFO, "Failed to read msg from virtual channel, ret: %d", ret);
    1963                 :          0 :                         return;
    1964                 :            :                 }
    1965                 :            : 
    1966         [ #  # ]:          0 :                 memcpy(base->mbx_resp, ctlq_msg.ctx.indirect.payload->va,
    1967                 :            :                            IDPF_DFLT_MBX_BUF_SIZE);
    1968                 :            : 
    1969                 :          0 :                 mbx_op = rte_le_to_cpu_16(ctlq_msg.opcode);
    1970                 :          0 :                 vc_op = rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_opcode);
    1971                 :          0 :                 base->cmd_retval = rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_retval);
    1972                 :            : 
    1973         [ #  # ]:          0 :                 switch (mbx_op) {
    1974                 :          0 :                 case idpf_mbq_opc_send_msg_to_peer_pf:
    1975                 :            :                 case idpf_mbq_opc_send_msg_to_peer_drv:
    1976         [ #  # ]:          0 :                         if (vc_op == VIRTCHNL2_OP_EVENT) {
    1977                 :          0 :                                 cpfl_handle_vchnl_event_msg(adapter, adapter->base.mbx_resp,
    1978                 :          0 :                                                             ctlq_msg.data_len);
    1979         [ #  # ]:          0 :                         } else if (vc_op == CPCHNL2_OP_EVENT) {
    1980                 :          0 :                                 cpfl_handle_cpchnl_event_msg(adapter, adapter->base.mbx_resp,
    1981                 :          0 :                                                              ctlq_msg.data_len);
    1982                 :            :                         } else {
    1983         [ #  # ]:          0 :                                 if (vc_op == base->pend_cmd)
    1984                 :            :                                         notify_cmd(base, base->cmd_retval);
    1985                 :            :                                 else
    1986                 :          0 :                                         PMD_DRV_LOG(ERR, "command mismatch, expect %u, get %u",
    1987                 :            :                                                     base->pend_cmd, vc_op);
    1988                 :            : 
    1989                 :          0 :                                 PMD_DRV_LOG(DEBUG, " Virtual channel response is received,"
    1990                 :            :                                             "opcode = %d", vc_op);
    1991                 :            :                         }
    1992                 :          0 :                         goto post_buf;
    1993                 :          0 :                 default:
    1994                 :          0 :                         PMD_DRV_LOG(DEBUG, "Request %u is not supported yet", mbx_op);
    1995                 :            :                 }
    1996                 :            :         }
    1997                 :            : 
    1998                 :          0 : post_buf:
    1999         [ #  # ]:          0 :         if (ctlq_msg.data_len)
    2000                 :          0 :                 dma_mem = ctlq_msg.ctx.indirect.payload;
    2001                 :            :         else
    2002                 :          0 :                 pending = 0;
    2003                 :            : 
    2004                 :          0 :         ret = idpf_vc_ctlq_post_rx_buffs(hw, hw->arq, &pending, &dma_mem);
    2005   [ #  #  #  # ]:          0 :         if (ret && dma_mem)
    2006                 :            :                 idpf_free_dma_mem(hw, dma_mem);
    2007                 :            : }
    2008                 :            : 
    2009                 :            : static void
    2010                 :          0 : cpfl_dev_alarm_handler(void *param)
    2011                 :            : {
    2012                 :            :         struct cpfl_adapter_ext *adapter = param;
    2013                 :            : 
    2014                 :          0 :         cpfl_handle_virtchnl_msg(adapter);
    2015                 :            : 
    2016                 :          0 :         rte_eal_alarm_set(CPFL_ALARM_INTERVAL, cpfl_dev_alarm_handler, adapter);
    2017                 :          0 : }
    2018                 :            : 
    2019                 :            : static
    2020                 :          0 : int vcpf_save_vport_info_response(struct cpfl_vport *cpfl_vport,
    2021                 :            :                 struct cpchnl2_get_vport_info_response *response)
    2022                 :            : {
    2023                 :            :         struct cpchnl2_vport_info *info;
    2024                 :            :         struct vcpf_vport_info *vport_info;
    2025                 :            :         struct cpchnl2_queue_group_info *qgp;
    2026                 :            :         struct cpchnl2_queue_chunk *q_chnk;
    2027                 :            :         u16 num_queue_groups;
    2028                 :            :         u16 num_chunks;
    2029                 :            :         u32 q_type;
    2030                 :            : 
    2031                 :            :         info = &response->info;
    2032                 :            :         vport_info = &cpfl_vport->vport_info;
    2033                 :          0 :         vport_info->vport_index = info->vport_index;
    2034                 :          0 :         vport_info->vsi_id = info->vsi_id;
    2035                 :            : 
    2036                 :          0 :         num_queue_groups = response->queue_groups.num_queue_groups;
    2037         [ #  # ]:          0 :         for (u16 i = 0; i < num_queue_groups; i++) {
    2038                 :          0 :                 qgp = &response->queue_groups.groups[i];
    2039                 :          0 :                 num_chunks = qgp->chunks.num_chunks;
    2040                 :            :                 /* rx q and tx q are stored in first 2 chunks */
    2041         [ #  # ]:          0 :                 for (u16 j = 0; j < (num_chunks - 2); j++) {
    2042                 :            :                         q_chnk = &qgp->chunks.chunks[j];
    2043                 :          0 :                         q_type = q_chnk->type;
    2044         [ #  # ]:          0 :                         if (q_type == VIRTCHNL2_QUEUE_TYPE_TX) {
    2045                 :          0 :                                 vport_info->abs_start_txq_id = q_chnk->start_queue_id;
    2046                 :          0 :                                 vport_info->num_tx_q = q_chnk->num_queues;
    2047         [ #  # ]:          0 :                         } else if (q_type == VIRTCHNL2_QUEUE_TYPE_RX) {
    2048                 :          0 :                                 vport_info->abs_start_rxq_id = q_chnk->start_queue_id;
    2049                 :          0 :                                 vport_info->num_rx_q = q_chnk->num_queues;
    2050                 :            :                         }
    2051                 :            :                 }
    2052                 :            :         }
    2053                 :          0 :         return 0;
    2054                 :            : }
    2055                 :            : 
    2056                 :            : static int
    2057                 :          0 : cpfl_stop_cfgqs(struct cpfl_adapter_ext *adapter)
    2058                 :            : {
    2059                 :            :         int i, ret;
    2060                 :            : 
    2061         [ #  # ]:          0 :         for (i = 0; i < adapter->num_tx_cfgq; i++) {
    2062         [ #  # ]:          0 :                 if (idpf_is_vf_device(&adapter->base.hw))
    2063                 :          0 :                         ret = idpf_vc_ena_dis_one_queue_vcpf(&adapter->base,
    2064                 :          0 :                                         adapter->cfgq_info[0].id,
    2065                 :            :                                         VIRTCHNL2_QUEUE_TYPE_CONFIG_TX, false);
    2066                 :            :                 else
    2067                 :          0 :                         ret = idpf_vc_queue_switch(&adapter->ctrl_vport.base, i, false, false,
    2068                 :            :                                                                 VIRTCHNL2_QUEUE_TYPE_CONFIG_TX);
    2069                 :            : 
    2070         [ #  # ]:          0 :                 if (ret) {
    2071                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to disable Tx config queue.");
    2072                 :          0 :                         return ret;
    2073                 :            :                 }
    2074                 :            :         }
    2075                 :            : 
    2076         [ #  # ]:          0 :         for (i = 0; i < adapter->num_rx_cfgq; i++) {
    2077         [ #  # ]:          0 :                 if (idpf_is_vf_device(&adapter->base.hw))
    2078                 :          0 :                         ret = idpf_vc_ena_dis_one_queue_vcpf(&adapter->base,
    2079                 :          0 :                                         adapter->cfgq_info[1].id,
    2080                 :            :                                         VIRTCHNL2_QUEUE_TYPE_CONFIG_RX, false);
    2081                 :            :                 else
    2082                 :          0 :                         ret = idpf_vc_queue_switch(&adapter->ctrl_vport.base, i, true, false,
    2083                 :            :                                                         VIRTCHNL2_QUEUE_TYPE_CONFIG_RX);
    2084                 :            : 
    2085         [ #  # ]:          0 :                 if (ret) {
    2086                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to disable Rx config queue.");
    2087                 :          0 :                         return ret;
    2088                 :            :                 }
    2089                 :            :         }
    2090                 :            : 
    2091                 :            :         return 0;
    2092                 :            : 
    2093                 :            : }
    2094                 :            : 
    2095                 :            : static int
    2096                 :          0 : cpfl_start_cfgqs(struct cpfl_adapter_ext *adapter)
    2097                 :            : {
    2098                 :            :         int i, ret;
    2099                 :            : 
    2100                 :          0 :         ret = cpfl_config_ctlq_tx(adapter);
    2101         [ #  # ]:          0 :         if (ret) {
    2102                 :          0 :                 PMD_DRV_LOG(ERR, "Fail to configure Tx config queue.");
    2103                 :          0 :                 return ret;
    2104                 :            :         }
    2105                 :            : 
    2106                 :          0 :         ret = cpfl_config_ctlq_rx(adapter);
    2107         [ #  # ]:          0 :         if (ret) {
    2108                 :          0 :                 PMD_DRV_LOG(ERR, "Fail to configure Rx config queue.");
    2109                 :          0 :                 return ret;
    2110                 :            :         }
    2111                 :            : 
    2112         [ #  # ]:          0 :         for (i = 0; i < adapter->num_tx_cfgq; i++) {
    2113         [ #  # ]:          0 :                 if (idpf_is_vf_device(&adapter->base.hw))
    2114                 :          0 :                         ret = idpf_vc_ena_dis_one_queue_vcpf(&adapter->base,
    2115                 :          0 :                                         adapter->cfgq_info[0].id,
    2116                 :            :                                         VIRTCHNL2_QUEUE_TYPE_CONFIG_TX, true);
    2117                 :            :                 else
    2118                 :          0 :                         ret = idpf_vc_queue_switch(&adapter->ctrl_vport.base, i, false, true,
    2119                 :            :                                                                 VIRTCHNL2_QUEUE_TYPE_CONFIG_TX);
    2120         [ #  # ]:          0 :                 if (ret) {
    2121                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to enable Tx config queue.");
    2122                 :          0 :                         return ret;
    2123                 :            :                 }
    2124                 :            :         }
    2125                 :            : 
    2126         [ #  # ]:          0 :         for (i = 0; i < adapter->num_rx_cfgq; i++) {
    2127         [ #  # ]:          0 :                 if (idpf_is_vf_device(&adapter->base.hw))
    2128                 :          0 :                         ret = idpf_vc_ena_dis_one_queue_vcpf(&adapter->base,
    2129                 :          0 :                                         adapter->cfgq_info[1].id,
    2130                 :            :                                         VIRTCHNL2_QUEUE_TYPE_CONFIG_RX, true);
    2131                 :            :                 else
    2132                 :          0 :                         ret = idpf_vc_queue_switch(&adapter->ctrl_vport.base, i, true, true,
    2133                 :            :                                                                 VIRTCHNL2_QUEUE_TYPE_CONFIG_RX);
    2134         [ #  # ]:          0 :                 if (ret) {
    2135                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to enable Rx config queue.");
    2136                 :          0 :                         return ret;
    2137                 :            :                 }
    2138                 :            :         }
    2139                 :            : 
    2140                 :            :         return 0;
    2141                 :            : }
    2142                 :            : 
    2143                 :            : static void
    2144                 :          0 : cpfl_remove_cfgqs(struct cpfl_adapter_ext *adapter)
    2145                 :            : {
    2146                 :          0 :         struct idpf_hw *hw = (struct idpf_hw *)(&adapter->base.hw);
    2147                 :            :         struct cpfl_ctlq_create_info *create_cfgq_info;
    2148                 :            :         int i;
    2149                 :            : 
    2150                 :          0 :         create_cfgq_info = adapter->cfgq_info;
    2151                 :            : 
    2152         [ #  # ]:          0 :         for (i = 0; i < adapter->num_cfgq; i++) {
    2153         [ #  # ]:          0 :                 if (adapter->ctlqp[i]) {
    2154                 :          0 :                         cpfl_vport_ctlq_remove(hw, adapter->ctlqp[i]);
    2155                 :          0 :                         adapter->ctlqp[i] = NULL;
    2156                 :            :                 }
    2157         [ #  # ]:          0 :                 if (create_cfgq_info[i].ring_mem.va)
    2158                 :            :                         idpf_free_dma_mem(&adapter->base.hw, &create_cfgq_info[i].ring_mem);
    2159         [ #  # ]:          0 :                 if (create_cfgq_info[i].buf_mem.va)
    2160                 :            :                         idpf_free_dma_mem(&adapter->base.hw, &create_cfgq_info[i].buf_mem);
    2161                 :            :         }
    2162         [ #  # ]:          0 :         if (adapter->ctlqp) {
    2163                 :          0 :                 rte_free(adapter->ctlqp);
    2164                 :          0 :                 adapter->ctlqp = NULL;
    2165                 :            :         }
    2166                 :          0 : }
    2167                 :            : 
    2168                 :            : static int
    2169                 :          0 : cpfl_add_cfgqs(struct cpfl_adapter_ext *adapter)
    2170                 :            : {
    2171                 :            :         struct idpf_ctlq_info *cfg_cq;
    2172                 :            :         int ret = 0;
    2173                 :            :         int i = 0;
    2174                 :            : 
    2175                 :          0 :         adapter->ctlqp = rte_zmalloc("ctlqp", adapter->num_cfgq *
    2176                 :            :                                 sizeof(struct idpf_ctlq_info *),
    2177                 :            :                                 RTE_CACHE_LINE_SIZE);
    2178                 :            : 
    2179         [ #  # ]:          0 :         if (!adapter->ctlqp) {
    2180                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for control queues");
    2181                 :          0 :                 return -ENOMEM;
    2182                 :            :         }
    2183                 :            : 
    2184         [ #  # ]:          0 :         for (i = 0; i < adapter->num_cfgq; i++) {
    2185                 :          0 :                 cfg_cq = NULL;
    2186                 :          0 :                 ret = cpfl_vport_ctlq_add((struct idpf_hw *)(&adapter->base.hw),
    2187                 :          0 :                                           &adapter->cfgq_info[i],
    2188                 :            :                                           &cfg_cq);
    2189   [ #  #  #  # ]:          0 :                 if (ret || !cfg_cq) {
    2190                 :          0 :                         PMD_DRV_LOG(ERR, "ctlq add failed for queue id: %d",
    2191                 :            :                                     adapter->cfgq_info[i].id);
    2192                 :          0 :                         cpfl_remove_cfgqs(adapter);
    2193                 :          0 :                         return ret;
    2194                 :            :                 }
    2195                 :          0 :                 PMD_DRV_LOG(INFO, "added cfgq to hw. queue id: %d",
    2196                 :            :                             adapter->cfgq_info[i].id);
    2197                 :          0 :                 adapter->ctlqp[i] = cfg_cq;
    2198                 :            :         }
    2199                 :            : 
    2200                 :            :         return ret;
    2201                 :            : }
    2202                 :            : 
    2203                 :            : static
    2204                 :          0 : int vcpf_save_chunk_in_cfgq(struct cpfl_adapter_ext *adapter)
    2205                 :            : {
    2206                 :          0 :         struct virtchnl2_add_queues *add_q =
    2207                 :            :                 (struct virtchnl2_add_queues *)adapter->addq_recv_info;
    2208                 :            :         struct vcpf_cfg_queue *cfgq;
    2209                 :            :         struct virtchnl2_queue_reg_chunk *q_chnk;
    2210                 :            :         u16 rx, tx, num_chunks, num_q, struct_size;
    2211                 :            :         u32 q_id, q_type;
    2212                 :            : 
    2213                 :            :         rx = 0; tx = 0;
    2214                 :            : 
    2215                 :          0 :         cfgq = rte_zmalloc("cfgq", adapter->num_cfgq * sizeof(struct vcpf_cfg_queue),
    2216                 :            :                                 RTE_CACHE_LINE_SIZE);
    2217         [ #  # ]:          0 :         if (!cfgq) {
    2218                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for cfgq");
    2219                 :          0 :                 return -ENOMEM;
    2220                 :            :         }
    2221                 :            : 
    2222                 :          0 :         struct_size = idpf_struct_size(add_q, chunks.chunks, (add_q->chunks.num_chunks - 1));
    2223                 :          0 :         adapter->cfgq_in.cfgq_add = rte_zmalloc("config_queues", struct_size, 0);
    2224         [ #  # ]:          0 :         if (!adapter->cfgq_in.cfgq_add) {
    2225                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for add_q");
    2226                 :          0 :                 return -ENOMEM;
    2227                 :            :         }
    2228                 :            :         memcpy(adapter->cfgq_in.cfgq_add, add_q, struct_size);
    2229                 :            : 
    2230                 :          0 :         num_chunks = add_q->chunks.num_chunks;
    2231         [ #  # ]:          0 :         for (u16 i = 0; i < num_chunks; i++) {
    2232                 :          0 :                 num_q = add_q->chunks.chunks[i].num_queues;
    2233                 :            :                 q_chnk = &add_q->chunks.chunks[i];
    2234         [ #  # ]:          0 :                 for (u16 j = 0; j < num_q; j++) {
    2235   [ #  #  #  # ]:          0 :                         if (rx > adapter->num_cfgq || tx > adapter->num_cfgq)
    2236                 :            :                                 break;
    2237                 :          0 :                         q_id = q_chnk->start_queue_id + j;
    2238                 :          0 :                         q_type = q_chnk->type;
    2239         [ #  # ]:          0 :                         if (q_type == VIRTCHNL2_QUEUE_TYPE_MBX_TX) {
    2240                 :          0 :                                 cfgq[0].qid = q_id;
    2241                 :          0 :                                 cfgq[0].qtail_reg_start = q_chnk->qtail_reg_start;
    2242                 :          0 :                                 cfgq[0].qtail_reg_spacing = q_chnk->qtail_reg_spacing;
    2243                 :          0 :                                 q_chnk->type = VIRTCHNL2_QUEUE_TYPE_CONFIG_TX;
    2244                 :          0 :                                 tx++;
    2245         [ #  # ]:          0 :                         } else if (q_type == VIRTCHNL2_QUEUE_TYPE_MBX_RX) {
    2246                 :          0 :                                 cfgq[1].qid = q_id;
    2247                 :          0 :                                 cfgq[1].qtail_reg_start = q_chnk->qtail_reg_start;
    2248                 :          0 :                                 cfgq[1].qtail_reg_spacing = q_chnk->qtail_reg_spacing;
    2249                 :          0 :                                 q_chnk->type = VIRTCHNL2_QUEUE_TYPE_CONFIG_RX;
    2250                 :          0 :                                 rx++;
    2251                 :            :                         }
    2252                 :            :                 }
    2253                 :            :         }
    2254                 :            : 
    2255                 :          0 :         adapter->cfgq_in.cfgq = cfgq;
    2256                 :          0 :         adapter->cfgq_in.num_cfgq = adapter->num_cfgq;
    2257                 :            : 
    2258                 :          0 :         return 0;
    2259                 :            : }
    2260                 :            : 
    2261                 :            : #define CPFL_CFGQ_RING_LEN              512
    2262                 :            : #define CPFL_CFGQ_DESCRIPTOR_SIZE       32
    2263                 :            : #define CPFL_CFGQ_BUFFER_SIZE           256
    2264                 :            : #define CPFL_CFGQ_RING_SIZE             512
    2265                 :            : 
    2266                 :            : static int
    2267                 :          0 : cpfl_cfgq_setup(struct cpfl_adapter_ext *adapter)
    2268                 :            : {
    2269                 :            :         struct cpfl_ctlq_create_info *create_cfgq_info;
    2270                 :            :         struct cpfl_vport *vport;
    2271                 :            :         struct vcpf_cfgq_info *cfgq_info = &adapter->cfgq_in;
    2272                 :            :         int i, err;
    2273                 :            :         uint32_t ring_size = CPFL_CFGQ_RING_SIZE * sizeof(struct idpf_ctlq_desc);
    2274                 :            :         uint32_t buf_size = CPFL_CFGQ_RING_SIZE * CPFL_CFGQ_BUFFER_SIZE;
    2275                 :            :         uint64_t tx_qtail_start;
    2276                 :            :         uint64_t rx_qtail_start;
    2277                 :            :         uint32_t tx_qtail_spacing;
    2278                 :            :         uint32_t rx_qtail_spacing;
    2279                 :            : 
    2280                 :            :         vport = &adapter->ctrl_vport;
    2281                 :            : 
    2282                 :          0 :         tx_qtail_start = vport->base.chunks_info.tx_qtail_start;
    2283                 :          0 :         tx_qtail_spacing = vport->base.chunks_info.tx_qtail_spacing;
    2284                 :          0 :         rx_qtail_start = vport->base.chunks_info.rx_qtail_start;
    2285                 :          0 :         rx_qtail_spacing = vport->base.chunks_info.rx_qtail_spacing;
    2286                 :            : 
    2287                 :          0 :         adapter->cfgq_info = rte_zmalloc("cfgq_info", adapter->num_cfgq *
    2288                 :            :                                 sizeof(struct cpfl_ctlq_create_info),
    2289                 :            :                                 RTE_CACHE_LINE_SIZE);
    2290                 :            : 
    2291         [ #  # ]:          0 :         if (!adapter->cfgq_info) {
    2292                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for cfgq_info");
    2293                 :          0 :                 return -ENOMEM;
    2294                 :            :         }
    2295                 :            : 
    2296                 :            :         create_cfgq_info = adapter->cfgq_info;
    2297                 :            : 
    2298         [ #  # ]:          0 :         for (i = 0; i < adapter->num_cfgq; i++) {
    2299         [ #  # ]:          0 :                 if (i % 2 == 0) {
    2300                 :            :                 /* Setup Tx config queue */
    2301         [ #  # ]:          0 :                         if (idpf_is_vf_device(&adapter->base.hw))
    2302                 :          0 :                                 create_cfgq_info[i].id = cfgq_info->cfgq[i].qid;
    2303                 :            :                         else
    2304                 :          0 :                                 create_cfgq_info[i].id = vport->base.chunks_info.tx_start_qid +
    2305                 :          0 :                                                                 i / 2;
    2306                 :            : 
    2307                 :          0 :                         create_cfgq_info[i].type = IDPF_CTLQ_TYPE_CONFIG_TX;
    2308                 :          0 :                         create_cfgq_info[i].len = CPFL_CFGQ_RING_SIZE;
    2309                 :          0 :                         create_cfgq_info[i].buf_size = CPFL_CFGQ_BUFFER_SIZE;
    2310                 :          0 :                         memset(&create_cfgq_info[i].reg, 0, sizeof(struct idpf_ctlq_reg));
    2311         [ #  # ]:          0 :                         if (idpf_is_vf_device(&adapter->base.hw))
    2312                 :          0 :                                 create_cfgq_info[i].reg.tail = cfgq_info->cfgq[i].qtail_reg_start;
    2313                 :            :                         else
    2314                 :          0 :                                 create_cfgq_info[i].reg.tail = tx_qtail_start +
    2315                 :          0 :                                                                 i / 2 * tx_qtail_spacing;
    2316                 :            : 
    2317                 :            :                 } else {
    2318                 :            :                 /* Setup Rx config queue */
    2319         [ #  # ]:          0 :                         if (idpf_is_vf_device(&adapter->base.hw))
    2320                 :          0 :                                 create_cfgq_info[i].id = cfgq_info->cfgq[i].qid;
    2321                 :            :                         else
    2322                 :          0 :                                 create_cfgq_info[i].id = vport->base.chunks_info.rx_start_qid +
    2323                 :          0 :                                                                 i / 2;
    2324                 :            : 
    2325                 :          0 :                         create_cfgq_info[i].type = IDPF_CTLQ_TYPE_CONFIG_RX;
    2326                 :          0 :                         create_cfgq_info[i].len = CPFL_CFGQ_RING_SIZE;
    2327                 :          0 :                         create_cfgq_info[i].buf_size = CPFL_CFGQ_BUFFER_SIZE;
    2328                 :          0 :                         memset(&create_cfgq_info[i].reg, 0, sizeof(struct idpf_ctlq_reg));
    2329         [ #  # ]:          0 :                         if (idpf_is_vf_device(&adapter->base.hw))
    2330                 :          0 :                                 create_cfgq_info[i].reg.tail = cfgq_info->cfgq[i].qtail_reg_start;
    2331                 :            :                         else
    2332                 :          0 :                                 create_cfgq_info[i].reg.tail = rx_qtail_start +
    2333                 :          0 :                                                                 i / 2 * rx_qtail_spacing;
    2334                 :            : 
    2335                 :            : 
    2336         [ #  # ]:          0 :                         if (!idpf_alloc_dma_mem(&adapter->base.hw, &create_cfgq_info[i].buf_mem,
    2337                 :            :                                                 buf_size)) {
    2338                 :            :                                 err = -ENOMEM;
    2339                 :          0 :                                 goto free_mem;
    2340                 :            :                         }
    2341                 :            :                 }
    2342         [ #  # ]:          0 :                 if (!idpf_alloc_dma_mem(&adapter->base.hw, &create_cfgq_info[i].ring_mem,
    2343                 :            :                                 ring_size)) {
    2344                 :            :                         err = -ENOMEM;
    2345                 :          0 :                         goto free_mem;
    2346                 :            :                 }
    2347                 :            :         }
    2348                 :            : 
    2349                 :            :         return 0;
    2350                 :            : free_mem:
    2351         [ #  # ]:          0 :         for (i = 0; i < adapter->num_cfgq; i++) {
    2352         [ #  # ]:          0 :                 if (create_cfgq_info[i].ring_mem.va)
    2353                 :            :                         idpf_free_dma_mem(&adapter->base.hw, &create_cfgq_info[i].ring_mem);
    2354         [ #  # ]:          0 :                 if (create_cfgq_info[i].buf_mem.va)
    2355                 :            :                         idpf_free_dma_mem(&adapter->base.hw, &create_cfgq_info[i].buf_mem);
    2356                 :            :         }
    2357         [ #  # ]:          0 :         if (adapter->cfgq_info) {
    2358                 :          0 :                 rte_free(adapter->cfgq_info);
    2359                 :          0 :                 adapter->cfgq_info = NULL;
    2360                 :            :         }
    2361                 :            :         return err;
    2362                 :            : }
    2363                 :            : 
    2364                 :            : static int
    2365                 :          0 : cpfl_init_ctrl_vport(struct cpfl_adapter_ext *adapter)
    2366                 :            : {
    2367                 :            :         struct cpfl_vport *vport = &adapter->ctrl_vport;
    2368                 :            :         struct virtchnl2_create_vport *vport_info =
    2369                 :            :                 (struct virtchnl2_create_vport *)adapter->ctrl_vport_recv_info;
    2370                 :            :         int i;
    2371                 :            : 
    2372                 :          0 :         vport->itf.adapter = adapter;
    2373                 :          0 :         vport->base.adapter = &adapter->base;
    2374                 :          0 :         vport->base.vport_id = vport_info->vport_id;
    2375                 :            : 
    2376         [ #  # ]:          0 :         for (i = 0; i < vport_info->chunks.num_chunks; i++) {
    2377         [ #  # ]:          0 :                 if (vport_info->chunks.chunks[i].type == VIRTCHNL2_QUEUE_TYPE_TX) {
    2378                 :          0 :                         vport->base.chunks_info.tx_start_qid =
    2379                 :          0 :                                 vport_info->chunks.chunks[i].start_queue_id;
    2380                 :          0 :                         vport->base.chunks_info.tx_qtail_start =
    2381                 :          0 :                         vport_info->chunks.chunks[i].qtail_reg_start;
    2382                 :          0 :                         vport->base.chunks_info.tx_qtail_spacing =
    2383                 :          0 :                         vport_info->chunks.chunks[i].qtail_reg_spacing;
    2384         [ #  # ]:          0 :                 } else if (vport_info->chunks.chunks[i].type == VIRTCHNL2_QUEUE_TYPE_RX) {
    2385                 :          0 :                         vport->base.chunks_info.rx_start_qid =
    2386                 :          0 :                                 vport_info->chunks.chunks[i].start_queue_id;
    2387                 :          0 :                         vport->base.chunks_info.rx_qtail_start =
    2388                 :          0 :                         vport_info->chunks.chunks[i].qtail_reg_start;
    2389                 :          0 :                         vport->base.chunks_info.rx_qtail_spacing =
    2390                 :          0 :                         vport_info->chunks.chunks[i].qtail_reg_spacing;
    2391                 :            :                 } else {
    2392                 :          0 :                         PMD_INIT_LOG(ERR, "Unsupported chunk type");
    2393                 :          0 :                         return -EINVAL;
    2394                 :            :                 }
    2395                 :            :         }
    2396                 :            : 
    2397                 :            :         return 0;
    2398                 :            : }
    2399                 :            : 
    2400                 :            : static void
    2401                 :          0 : cpfl_ctrl_path_close(struct cpfl_adapter_ext *adapter)
    2402                 :            : {
    2403                 :          0 :         cpfl_stop_cfgqs(adapter);
    2404                 :          0 :         cpfl_remove_cfgqs(adapter);
    2405         [ #  # ]:          0 :         if (!idpf_is_vf_device(&adapter->base.hw))
    2406                 :          0 :                 idpf_vc_vport_destroy(&adapter->ctrl_vport.base);
    2407                 :            :         else
    2408                 :          0 :                 vcpf_del_queues(adapter);
    2409                 :          0 : }
    2410                 :            : 
    2411                 :            : static int
    2412                 :          0 : cpfl_ctrl_path_open(struct cpfl_adapter_ext *adapter)
    2413                 :            : {
    2414                 :            :         int ret;
    2415                 :            : 
    2416         [ #  # ]:          0 :         if (!idpf_is_vf_device(&adapter->base.hw)) {
    2417                 :          0 :                 ret = cpfl_vc_create_ctrl_vport(adapter);
    2418         [ #  # ]:          0 :                 if (ret) {
    2419                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to create control vport");
    2420                 :          0 :                         return ret;
    2421                 :            :                 }
    2422                 :            : 
    2423                 :          0 :                 ret = cpfl_init_ctrl_vport(adapter);
    2424         [ #  # ]:          0 :                 if (ret) {
    2425                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to init control vport");
    2426                 :          0 :                         goto err_init_ctrl_vport;
    2427                 :            :                 }
    2428                 :            :         } else {
    2429                 :          0 :                 ret = vcpf_add_queues(adapter);
    2430         [ #  # ]:          0 :                 if (ret) {
    2431                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to add queues");
    2432                 :          0 :                         return ret;
    2433                 :            :                 }
    2434                 :            : 
    2435                 :          0 :                 ret = vcpf_save_chunk_in_cfgq(adapter);
    2436         [ #  # ]:          0 :                 if (ret) {
    2437                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to save config queue chunk");
    2438                 :          0 :                         return ret;
    2439                 :            :                 }
    2440                 :            :         }
    2441                 :            : 
    2442                 :          0 :         ret = cpfl_cfgq_setup(adapter);
    2443         [ #  # ]:          0 :         if (ret) {
    2444                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to setup control queues");
    2445         [ #  # ]:          0 :                 if (!idpf_is_vf_device(&adapter->base.hw))
    2446                 :          0 :                         goto err_cfgq_setup;
    2447                 :            :                 else
    2448                 :          0 :                         goto err_del_cfg;
    2449                 :            :         }
    2450                 :            : 
    2451                 :          0 :         ret = cpfl_add_cfgqs(adapter);
    2452         [ #  # ]:          0 :         if (ret) {
    2453                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to add control queues");
    2454                 :          0 :                 goto err_add_cfgq;
    2455                 :            :         }
    2456                 :            : 
    2457                 :          0 :         ret = cpfl_start_cfgqs(adapter);
    2458         [ #  # ]:          0 :         if (ret) {
    2459                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to start control queues");
    2460                 :          0 :                 goto err_start_cfgqs;
    2461                 :            :         }
    2462                 :            : 
    2463                 :            :         return 0;
    2464                 :            : 
    2465                 :            : err_start_cfgqs:
    2466                 :          0 :         cpfl_stop_cfgqs(adapter);
    2467                 :          0 : err_add_cfgq:
    2468                 :          0 :         cpfl_remove_cfgqs(adapter);
    2469                 :          0 : err_cfgq_setup:
    2470                 :          0 : err_init_ctrl_vport:
    2471         [ #  # ]:          0 :         if (!idpf_is_vf_device(&adapter->base.hw))
    2472                 :          0 :                 idpf_vc_vport_destroy(&adapter->ctrl_vport.base);
    2473                 :          0 : err_del_cfg:
    2474                 :          0 :         vcpf_del_queues(adapter);
    2475                 :            : 
    2476                 :          0 :         return ret;
    2477                 :            : 
    2478                 :            : }
    2479                 :            : 
    2480                 :            : static struct virtchnl2_get_capabilities req_caps = {
    2481                 :            :         .csum_caps =
    2482                 :            :         VIRTCHNL2_CAP_TX_CSUM_L3_IPV4          |
    2483                 :            :         VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP      |
    2484                 :            :         VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP      |
    2485                 :            :         VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP     |
    2486                 :            :         VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP      |
    2487                 :            :         VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP      |
    2488                 :            :         VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP     |
    2489                 :            :         VIRTCHNL2_CAP_TX_CSUM_GENERIC          |
    2490                 :            :         VIRTCHNL2_CAP_RX_CSUM_L3_IPV4          |
    2491                 :            :         VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP      |
    2492                 :            :         VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP      |
    2493                 :            :         VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP     |
    2494                 :            :         VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP      |
    2495                 :            :         VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP      |
    2496                 :            :         VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP     |
    2497                 :            :         VIRTCHNL2_CAP_RX_CSUM_GENERIC,
    2498                 :            : 
    2499                 :            :         .rss_caps =
    2500                 :            :         VIRTCHNL2_CAP_RSS_IPV4_TCP             |
    2501                 :            :         VIRTCHNL2_CAP_RSS_IPV4_UDP             |
    2502                 :            :         VIRTCHNL2_CAP_RSS_IPV4_SCTP            |
    2503                 :            :         VIRTCHNL2_CAP_RSS_IPV4_OTHER           |
    2504                 :            :         VIRTCHNL2_CAP_RSS_IPV6_TCP             |
    2505                 :            :         VIRTCHNL2_CAP_RSS_IPV6_UDP             |
    2506                 :            :         VIRTCHNL2_CAP_RSS_IPV6_SCTP            |
    2507                 :            :         VIRTCHNL2_CAP_RSS_IPV6_OTHER           |
    2508                 :            :         VIRTCHNL2_CAP_RSS_IPV4_AH              |
    2509                 :            :         VIRTCHNL2_CAP_RSS_IPV4_ESP             |
    2510                 :            :         VIRTCHNL2_CAP_RSS_IPV4_AH_ESP          |
    2511                 :            :         VIRTCHNL2_CAP_RSS_IPV6_AH              |
    2512                 :            :         VIRTCHNL2_CAP_RSS_IPV6_ESP             |
    2513                 :            :         VIRTCHNL2_CAP_RSS_IPV6_AH_ESP,
    2514                 :            : 
    2515                 :            :         .other_caps = VIRTCHNL2_CAP_WB_ON_ITR
    2516                 :            : };
    2517                 :            : 
    2518                 :            : static int
    2519                 :          0 : cpfl_vport_map_init(struct cpfl_adapter_ext *adapter)
    2520                 :            : {
    2521                 :            :         char hname[32];
    2522                 :            : 
    2523                 :          0 :         snprintf(hname, 32, "%s-vport", adapter->name);
    2524                 :            : 
    2525                 :            :         rte_spinlock_init(&adapter->vport_map_lock);
    2526                 :            : 
    2527                 :            : #define CPFL_VPORT_MAP_HASH_ENTRY_NUM 2048
    2528                 :            : 
    2529                 :          0 :         struct rte_hash_parameters params = {
    2530                 :            :                 .name = adapter->name,
    2531                 :            :                 .entries = CPFL_VPORT_MAP_HASH_ENTRY_NUM,
    2532                 :            :                 .key_len = sizeof(struct cpfl_vport_id),
    2533                 :            :                 .hash_func = rte_hash_crc,
    2534                 :            :                 .socket_id = SOCKET_ID_ANY,
    2535                 :            :         };
    2536                 :            : 
    2537                 :          0 :         adapter->vport_map_hash = rte_hash_create(&params);
    2538                 :            : 
    2539         [ #  # ]:          0 :         if (adapter->vport_map_hash == NULL) {
    2540                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to create vport map hash");
    2541                 :          0 :                 return -EINVAL;
    2542                 :            :         }
    2543                 :            : 
    2544                 :            :         return 0;
    2545                 :            : }
    2546                 :            : 
    2547                 :            : static void
    2548                 :          0 : cpfl_vport_map_uninit(struct cpfl_adapter_ext *adapter)
    2549                 :            : {
    2550                 :          0 :         const void *key = NULL;
    2551                 :            :         struct cpfl_vport_map_info *info;
    2552                 :          0 :         uint32_t iter = 0;
    2553                 :            : 
    2554         [ #  # ]:          0 :         while (rte_hash_iterate(adapter->vport_map_hash, &key, (void **)&info, &iter) >= 0)
    2555                 :          0 :                 rte_free(info);
    2556                 :            : 
    2557                 :          0 :         rte_hash_free(adapter->vport_map_hash);
    2558                 :          0 : }
    2559                 :            : 
    2560                 :            : static int
    2561                 :          0 : cpfl_repr_allowlist_init(struct cpfl_adapter_ext *adapter)
    2562                 :            : {
    2563                 :            :         char hname[32];
    2564                 :            : 
    2565                 :          0 :         snprintf(hname, 32, "%s-repr_al", adapter->name);
    2566                 :            : 
    2567                 :            :         rte_spinlock_init(&adapter->repr_lock);
    2568                 :            : 
    2569                 :            : #define CPFL_REPR_HASH_ENTRY_NUM 2048
    2570                 :            : 
    2571                 :          0 :         struct rte_hash_parameters params = {
    2572                 :            :                 .name = hname,
    2573                 :            :                 .entries = CPFL_REPR_HASH_ENTRY_NUM,
    2574                 :            :                 .key_len = sizeof(struct cpfl_repr_id),
    2575                 :            :                 .hash_func = rte_hash_crc,
    2576                 :            :                 .socket_id = SOCKET_ID_ANY,
    2577                 :            :         };
    2578                 :            : 
    2579                 :          0 :         adapter->repr_allowlist_hash = rte_hash_create(&params);
    2580                 :            : 
    2581         [ #  # ]:          0 :         if (adapter->repr_allowlist_hash == NULL) {
    2582                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to create repr allowlist hash");
    2583                 :          0 :                 return -EINVAL;
    2584                 :            :         }
    2585                 :            : 
    2586                 :            :         return 0;
    2587                 :            : }
    2588                 :            : 
    2589                 :            : static void
    2590                 :            : cpfl_repr_allowlist_uninit(struct cpfl_adapter_ext *adapter)
    2591                 :            : {
    2592                 :          0 :         rte_hash_free(adapter->repr_allowlist_hash);
    2593                 :          0 : }
    2594                 :            : 
    2595                 :            : static uint8_t
    2596                 :          0 : get_running_host_id(void)
    2597                 :            : {
    2598                 :            :         struct utsname unamedata;
    2599                 :            :         uint8_t host_id = CPFL_INVALID_HOST_ID;
    2600                 :            : 
    2601         [ #  # ]:          0 :         if (uname(&unamedata) != 0)
    2602                 :          0 :                 PMD_INIT_LOG(ERR, "Cannot fetch node_name for host");
    2603         [ #  # ]:          0 :         else if (strstr(unamedata.nodename, "ipu-imc"))
    2604                 :          0 :                 PMD_INIT_LOG(ERR, "CPFL PMD cannot be running on IMC.");
    2605         [ #  # ]:          0 :         else if (strstr(unamedata.nodename, "ipu-acc"))
    2606                 :            :                 host_id = CPFL_HOST_ID_ACC;
    2607                 :            :         else
    2608                 :            :                 host_id = CPFL_HOST_ID_HOST;
    2609                 :            : 
    2610                 :          0 :         return host_id;
    2611                 :            : }
    2612                 :            : 
    2613                 :            : static uint8_t
    2614                 :            : set_config_queue_details(struct cpfl_adapter_ext *adapter, struct rte_pci_addr *pci_addr)
    2615                 :            : {
    2616         [ #  # ]:          0 :         if (pci_addr->function == CPFL_FID) {
    2617                 :          0 :                 adapter->num_cfgq = CPFL_CFGQ_NUM;
    2618                 :          0 :                 adapter->num_rx_cfgq = CPFL_RX_CFGQ_NUM;
    2619                 :          0 :                 adapter->num_tx_cfgq = CPFL_TX_CFGQ_NUM;
    2620         [ #  # ]:          0 :         } else if (pci_addr->function == VCPF_FID) {
    2621                 :          0 :                 adapter->num_cfgq = VCPF_CFGQ_NUM;
    2622                 :          0 :                 adapter->num_rx_cfgq = VCPF_RX_CFGQ_NUM;
    2623                 :          0 :                 adapter->num_tx_cfgq = VCPF_TX_CFGQ_NUM;
    2624                 :            :         }
    2625                 :            : 
    2626                 :            :         return 0;
    2627                 :            : }
    2628                 :            : 
    2629                 :            : static int
    2630                 :          0 : cpfl_adapter_ext_init(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adapter,
    2631                 :            :                       struct cpfl_devargs *devargs)
    2632                 :            : {
    2633                 :          0 :         struct idpf_adapter *base = &adapter->base;
    2634                 :            :         struct idpf_hw *hw = &base->hw;
    2635                 :            :         struct rte_pci_addr *pci_addr = &pci_dev->addr;
    2636                 :            :         int ret = 0;
    2637                 :            : 
    2638                 :            : #ifndef RTE_HAS_JANSSON
    2639                 :            :         RTE_SET_USED(devargs);
    2640                 :            : #endif
    2641                 :            : 
    2642                 :          0 :         hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
    2643                 :          0 :         hw->hw_addr_len = pci_dev->mem_resource[0].len;
    2644                 :          0 :         hw->back = base;
    2645                 :          0 :         hw->vendor_id = pci_dev->id.vendor_id;
    2646                 :          0 :         hw->device_id = pci_dev->id.device_id;
    2647                 :          0 :         hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
    2648                 :          0 :         adapter->host_id = get_running_host_id();
    2649                 :            : 
    2650                 :          0 :         strlcpy(adapter->name, pci_dev->device.name, sizeof(adapter->name));
    2651                 :            : 
    2652                 :          0 :         memcpy(&base->caps, &req_caps, sizeof(struct virtchnl2_get_capabilities));
    2653                 :            : 
    2654                 :          0 :         ret = idpf_adapter_init(base);
    2655         [ #  # ]:          0 :         if (ret != 0) {
    2656                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init adapter");
    2657                 :          0 :                 goto err_adapter_init;
    2658                 :            :         }
    2659                 :            : 
    2660                 :          0 :         ret = cpfl_vport_map_init(adapter);
    2661         [ #  # ]:          0 :         if (ret) {
    2662                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init vport map");
    2663                 :          0 :                 goto err_vport_map_init;
    2664                 :            :         }
    2665                 :            : 
    2666                 :          0 :         ret = cpfl_repr_allowlist_init(adapter);
    2667         [ #  # ]:          0 :         if (ret) {
    2668                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init representor allowlist");
    2669                 :          0 :                 goto err_repr_allowlist_init;
    2670                 :            :         }
    2671                 :            : 
    2672                 :          0 :         rte_eal_alarm_set(CPFL_ALARM_INTERVAL, cpfl_dev_alarm_handler, adapter);
    2673                 :            : 
    2674                 :          0 :         adapter->max_vport_nb = adapter->base.caps.max_vports > CPFL_MAX_VPORT_NUM ?
    2675                 :          0 :                                 CPFL_MAX_VPORT_NUM : adapter->base.caps.max_vports;
    2676                 :            : 
    2677                 :          0 :         adapter->vports = rte_zmalloc("vports",
    2678                 :          0 :                                       adapter->max_vport_nb *
    2679                 :            :                                       sizeof(*adapter->vports),
    2680                 :            :                                       0);
    2681         [ #  # ]:          0 :         if (adapter->vports == NULL) {
    2682                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to allocate vports memory");
    2683                 :            :                 ret = -ENOMEM;
    2684                 :          0 :                 goto err_vports_alloc;
    2685                 :            :         }
    2686                 :            : 
    2687                 :            :         /* set the number of config queues to be requested */
    2688                 :            :         ret = set_config_queue_details(adapter, pci_addr);
    2689                 :            :         if (ret) {
    2690                 :            :                 PMD_INIT_LOG(ERR, "Failed to set the config queue details");
    2691                 :            :                 return -1;
    2692                 :            :         }
    2693                 :            : 
    2694         [ #  # ]:          0 :         if (pci_addr->function == VCPF_FID || pci_addr->function == CPFL_FID) {
    2695                 :          0 :                 ret = cpfl_ctrl_path_open(adapter);
    2696         [ #  # ]:          0 :                 if (ret) {
    2697                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to setup control path");
    2698         [ #  # ]:          0 :                         if (pci_addr->function == CPFL_FID)
    2699                 :          0 :                                 goto err_create_ctrl_vport;
    2700                 :            :                         else
    2701                 :            :                                 return ret;
    2702                 :            :                 }
    2703                 :            : 
    2704                 :            :         }
    2705                 :            : 
    2706                 :            : #ifdef RTE_HAS_JANSSON
    2707                 :          0 :         ret = cpfl_flow_init(adapter, devargs);
    2708         [ #  # ]:          0 :         if (ret) {
    2709                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init flow module");
    2710                 :          0 :                 goto err_flow_init;
    2711                 :            :         }
    2712                 :            : #endif
    2713                 :          0 :         adapter->cur_vports = 0;
    2714                 :          0 :         adapter->cur_vport_nb = 0;
    2715                 :            : 
    2716                 :          0 :         adapter->used_vecs_num = 0;
    2717                 :            : 
    2718                 :          0 :         return ret;
    2719                 :            : 
    2720                 :            : #ifdef RTE_HAS_JANSSON
    2721                 :            : err_flow_init:
    2722                 :          0 :         cpfl_ctrl_path_close(adapter);
    2723                 :            : #endif
    2724                 :          0 : err_create_ctrl_vport:
    2725                 :          0 :         rte_free(adapter->vports);
    2726                 :          0 : err_vports_alloc:
    2727                 :          0 :         rte_eal_alarm_cancel(cpfl_dev_alarm_handler, adapter);
    2728                 :            :         cpfl_repr_allowlist_uninit(adapter);
    2729                 :          0 : err_repr_allowlist_init:
    2730                 :          0 :         cpfl_vport_map_uninit(adapter);
    2731                 :          0 : err_vport_map_init:
    2732                 :          0 :         idpf_adapter_deinit(base);
    2733                 :            : err_adapter_init:
    2734                 :            :         return ret;
    2735                 :            : }
    2736                 :            : 
    2737                 :            : static uint16_t
    2738                 :            : cpfl_vport_idx_alloc(struct cpfl_adapter_ext *adapter)
    2739                 :            : {
    2740                 :            :         uint16_t vport_idx;
    2741                 :            :         uint16_t i;
    2742                 :            : 
    2743         [ #  # ]:          0 :         for (i = 0; i < adapter->max_vport_nb; i++) {
    2744         [ #  # ]:          0 :                 if (adapter->vports[i] == NULL)
    2745                 :            :                         break;
    2746                 :            :         }
    2747                 :            : 
    2748         [ #  # ]:          0 :         if (i == adapter->max_vport_nb)
    2749                 :            :                 vport_idx = CPFL_INVALID_VPORT_IDX;
    2750                 :            :         else
    2751                 :            :                 vport_idx = i;
    2752                 :            : 
    2753                 :            :         return vport_idx;
    2754                 :            : }
    2755                 :            : 
    2756                 :            : static int
    2757                 :          0 : cpfl_p2p_q_grps_add(struct idpf_vport *vport,
    2758                 :            :                     struct virtchnl2_add_queue_groups *p2p_queue_grps_info,
    2759                 :            :                     uint8_t *p2p_q_vc_out_info)
    2760                 :            : {
    2761                 :            :         int ret;
    2762                 :            : 
    2763                 :          0 :         p2p_queue_grps_info->vport_id = vport->vport_id;
    2764                 :          0 :         p2p_queue_grps_info->num_queue_groups = CPFL_P2P_NB_QUEUE_GRPS;
    2765                 :          0 :         p2p_queue_grps_info->groups[0].num_rx_q = CPFL_MAX_P2P_NB_QUEUES;
    2766                 :          0 :         p2p_queue_grps_info->groups[0].num_rx_bufq = CPFL_P2P_NB_RX_BUFQ;
    2767                 :          0 :         p2p_queue_grps_info->groups[0].num_tx_q = CPFL_MAX_P2P_NB_QUEUES;
    2768                 :          0 :         p2p_queue_grps_info->groups[0].num_tx_complq = CPFL_P2P_NB_TX_COMPLQ;
    2769                 :          0 :         p2p_queue_grps_info->groups[0].qg_id.queue_group_id = CPFL_P2P_QUEUE_GRP_ID;
    2770                 :          0 :         p2p_queue_grps_info->groups[0].qg_id.queue_group_type = VIRTCHNL2_QUEUE_GROUP_P2P;
    2771                 :          0 :         p2p_queue_grps_info->groups[0].rx_q_grp_info.rss_lut_size = 0;
    2772                 :          0 :         p2p_queue_grps_info->groups[0].tx_q_grp_info.tx_tc = 0;
    2773                 :          0 :         p2p_queue_grps_info->groups[0].tx_q_grp_info.priority = 0;
    2774                 :          0 :         p2p_queue_grps_info->groups[0].tx_q_grp_info.is_sp = 0;
    2775                 :          0 :         p2p_queue_grps_info->groups[0].tx_q_grp_info.pir_weight = 0;
    2776                 :            : 
    2777                 :          0 :         ret = idpf_vc_queue_grps_add(vport, p2p_queue_grps_info, p2p_q_vc_out_info);
    2778         [ #  # ]:          0 :         if (ret != 0) {
    2779                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to add p2p queue groups.");
    2780                 :          0 :                 return ret;
    2781                 :            :         }
    2782                 :            : 
    2783                 :            :         return ret;
    2784                 :            : }
    2785                 :            : 
    2786                 :            : static int
    2787                 :          0 : cpfl_p2p_queue_info_init(struct cpfl_vport *cpfl_vport,
    2788                 :            :                          struct virtchnl2_add_queue_groups *p2p_q_vc_out_info)
    2789                 :            : {
    2790                 :          0 :         struct p2p_queue_chunks_info *p2p_q_chunks_info = cpfl_vport->p2p_q_chunks_info;
    2791                 :            :         struct virtchnl2_queue_reg_chunks *vc_chunks_out;
    2792                 :            :         int i, type;
    2793                 :            : 
    2794         [ #  # ]:          0 :         if (p2p_q_vc_out_info->groups[0].qg_id.queue_group_type !=
    2795                 :            :             VIRTCHNL2_QUEUE_GROUP_P2P) {
    2796                 :          0 :                 PMD_DRV_LOG(ERR, "Add queue group response mismatch.");
    2797                 :          0 :                 return -EINVAL;
    2798                 :            :         }
    2799                 :            : 
    2800                 :            :         vc_chunks_out = &p2p_q_vc_out_info->groups[0].chunks;
    2801                 :            : 
    2802         [ #  # ]:          0 :         for (i = 0; i < vc_chunks_out->num_chunks; i++) {
    2803                 :          0 :                 type = vc_chunks_out->chunks[i].type;
    2804   [ #  #  #  #  :          0 :                 switch (type) {
                      # ]
    2805                 :          0 :                 case VIRTCHNL2_QUEUE_TYPE_TX:
    2806                 :          0 :                         p2p_q_chunks_info->tx_start_qid =
    2807                 :          0 :                                 vc_chunks_out->chunks[i].start_queue_id;
    2808                 :          0 :                         p2p_q_chunks_info->tx_qtail_start =
    2809                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_start;
    2810                 :          0 :                         p2p_q_chunks_info->tx_qtail_spacing =
    2811                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_spacing;
    2812                 :          0 :                         break;
    2813                 :          0 :                 case VIRTCHNL2_QUEUE_TYPE_RX:
    2814                 :          0 :                         p2p_q_chunks_info->rx_start_qid =
    2815                 :          0 :                                 vc_chunks_out->chunks[i].start_queue_id;
    2816                 :          0 :                         p2p_q_chunks_info->rx_qtail_start =
    2817                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_start;
    2818                 :          0 :                         p2p_q_chunks_info->rx_qtail_spacing =
    2819                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_spacing;
    2820                 :          0 :                         break;
    2821                 :          0 :                 case VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION:
    2822                 :          0 :                         p2p_q_chunks_info->tx_compl_start_qid =
    2823                 :          0 :                                 vc_chunks_out->chunks[i].start_queue_id;
    2824                 :          0 :                         p2p_q_chunks_info->tx_compl_qtail_start =
    2825                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_start;
    2826                 :          0 :                         p2p_q_chunks_info->tx_compl_qtail_spacing =
    2827                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_spacing;
    2828                 :          0 :                         break;
    2829                 :          0 :                 case VIRTCHNL2_QUEUE_TYPE_RX_BUFFER:
    2830                 :          0 :                         p2p_q_chunks_info->rx_buf_start_qid =
    2831                 :          0 :                                 vc_chunks_out->chunks[i].start_queue_id;
    2832                 :          0 :                         p2p_q_chunks_info->rx_buf_qtail_start =
    2833                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_start;
    2834                 :          0 :                         p2p_q_chunks_info->rx_buf_qtail_spacing =
    2835                 :          0 :                                 vc_chunks_out->chunks[i].qtail_reg_spacing;
    2836                 :          0 :                         break;
    2837                 :          0 :                 default:
    2838                 :          0 :                         PMD_DRV_LOG(ERR, "Unsupported queue type");
    2839                 :          0 :                         break;
    2840                 :            :                 }
    2841                 :            :         }
    2842                 :            : 
    2843                 :            :         return 0;
    2844                 :            : }
    2845                 :            : 
    2846                 :            : int
    2847                 :          0 : cpfl_alloc_dma_mem_batch(struct idpf_dma_mem *orig_dma, struct idpf_dma_mem *dma, uint32_t size,
    2848                 :            :                          int batch_size)
    2849                 :            : {
    2850                 :            :         int i;
    2851                 :            : 
    2852         [ #  # ]:          0 :         if (!idpf_alloc_dma_mem(NULL, orig_dma, (uint64_t)size * (1 + batch_size))) {
    2853                 :          0 :                 PMD_INIT_LOG(ERR, "Could not alloc dma memory");
    2854                 :          0 :                 return -ENOMEM;
    2855                 :            :         }
    2856                 :            : 
    2857         [ #  # ]:          0 :         for (i = 0; i < batch_size; i++) {
    2858                 :          0 :                 dma[i].va = (void *)((char *)orig_dma->va + size * (i + 1));
    2859                 :          0 :                 dma[i].pa = orig_dma->pa + size * (i + 1);
    2860                 :          0 :                 dma[i].size = size;
    2861                 :          0 :                 dma[i].zone = NULL;
    2862                 :            :         }
    2863                 :            :         return 0;
    2864                 :            : }
    2865                 :            : 
    2866                 :            : static int
    2867                 :          0 : cpfl_dev_vport_init(struct rte_eth_dev *dev, void *init_params)
    2868                 :            : {
    2869                 :          0 :         struct cpfl_vport *cpfl_vport = dev->data->dev_private;
    2870                 :          0 :         struct idpf_vport *vport = &cpfl_vport->base;
    2871                 :            :         struct cpfl_vport_param *param = init_params;
    2872                 :          0 :         struct cpfl_adapter_ext *adapter = param->adapter;
    2873                 :            :         /* for sending create vport virtchnl msg prepare */
    2874                 :            :         struct virtchnl2_create_vport create_vport_info;
    2875                 :            :         struct virtchnl2_add_queue_groups p2p_queue_grps_info;
    2876                 :            :         struct cpchnl2_get_vport_info_response response;
    2877                 :          0 :         uint8_t p2p_q_vc_out_info[IDPF_DFLT_MBX_BUF_SIZE] = {0};
    2878                 :            :         struct cpfl_vport_id vi;
    2879                 :            :         struct cpchnl2_vport_id v_id;
    2880                 :            :         struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
    2881                 :            :         int ret = 0;
    2882                 :            : 
    2883                 :          0 :         dev->dev_ops = &cpfl_eth_dev_ops;
    2884                 :          0 :         vport->adapter = &adapter->base;
    2885                 :          0 :         vport->sw_idx = param->idx;
    2886                 :          0 :         vport->devarg_id = param->devarg_id;
    2887                 :            : 
    2888                 :            :         memset(&create_vport_info, 0, sizeof(create_vport_info));
    2889                 :          0 :         ret = idpf_vport_info_init(vport, &create_vport_info);
    2890         [ #  # ]:          0 :         if (ret != 0) {
    2891                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init vport req_info.");
    2892                 :          0 :                 goto err;
    2893                 :            :         }
    2894                 :            : 
    2895                 :          0 :         ret = idpf_vport_init(vport, &create_vport_info, dev->data);
    2896         [ #  # ]:          0 :         if (ret != 0) {
    2897                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init vports.");
    2898                 :          0 :                 goto err;
    2899                 :            :         }
    2900                 :            : 
    2901                 :          0 :         cpfl_vport->itf.type = CPFL_ITF_TYPE_VPORT;
    2902                 :          0 :         cpfl_vport->itf.adapter = adapter;
    2903                 :          0 :         cpfl_vport->itf.data = dev->data;
    2904                 :          0 :         TAILQ_INIT(&cpfl_vport->itf.flow_list);
    2905                 :          0 :         adapter->vports[param->idx] = cpfl_vport;
    2906                 :          0 :         adapter->cur_vports |= RTE_BIT32(param->devarg_id);
    2907                 :          0 :         adapter->cur_vport_nb++;
    2908                 :            : 
    2909                 :          0 :         dev->data->mac_addrs = rte_zmalloc(NULL, RTE_ETHER_ADDR_LEN, 0);
    2910         [ #  # ]:          0 :         if (dev->data->mac_addrs == NULL) {
    2911                 :          0 :                 PMD_INIT_LOG(ERR, "Cannot allocate mac_addr memory.");
    2912                 :            :                 ret = -ENOMEM;
    2913                 :          0 :                 goto err_mac_addrs;
    2914                 :            :         }
    2915                 :            : 
    2916                 :            :         rte_ether_addr_copy((struct rte_ether_addr *)vport->default_mac_addr,
    2917                 :            :                             &dev->data->mac_addrs[0]);
    2918                 :            : 
    2919                 :          0 :         memset(cpfl_vport->itf.dma, 0, sizeof(cpfl_vport->itf.dma));
    2920                 :          0 :         memset(cpfl_vport->itf.msg, 0, sizeof(cpfl_vport->itf.msg));
    2921                 :          0 :         ret = cpfl_alloc_dma_mem_batch(&cpfl_vport->itf.flow_dma,
    2922                 :            :                                        cpfl_vport->itf.dma,
    2923                 :            :                                        sizeof(union cpfl_rule_cfg_pkt_record),
    2924                 :            :                                        CPFL_FLOW_BATCH_SIZE);
    2925         [ #  # ]:          0 :         if (ret < 0)
    2926                 :          0 :                 goto err_mac_addrs;
    2927                 :            : 
    2928   [ #  #  #  # ]:          0 :         if (!adapter->base.is_rx_singleq && !adapter->base.is_tx_singleq) {
    2929                 :            :                 memset(&p2p_queue_grps_info, 0, sizeof(p2p_queue_grps_info));
    2930                 :          0 :                 ret = cpfl_p2p_q_grps_add(vport, &p2p_queue_grps_info, p2p_q_vc_out_info);
    2931         [ #  # ]:          0 :                 if (ret != 0) {
    2932                 :          0 :                         PMD_INIT_LOG(WARNING, "Failed to add p2p queue group.");
    2933                 :          0 :                         return 0;
    2934                 :            :                 }
    2935                 :          0 :                 cpfl_vport->p2p_q_chunks_info = rte_zmalloc(NULL,
    2936                 :            :                                                     sizeof(struct p2p_queue_chunks_info), 0);
    2937         [ #  # ]:          0 :                 if (cpfl_vport->p2p_q_chunks_info == NULL) {
    2938                 :          0 :                         PMD_INIT_LOG(WARNING, "Failed to allocate p2p queue info.");
    2939                 :          0 :                         cpfl_p2p_queue_grps_del(vport);
    2940                 :          0 :                         return 0;
    2941                 :            :                 }
    2942                 :          0 :                 ret = cpfl_p2p_queue_info_init(cpfl_vport,
    2943                 :            :                                        (struct virtchnl2_add_queue_groups *)p2p_q_vc_out_info);
    2944         [ #  # ]:          0 :                 if (ret != 0) {
    2945                 :          0 :                         PMD_INIT_LOG(WARNING, "Failed to init p2p queue info.");
    2946                 :          0 :                         rte_free(cpfl_vport->p2p_q_chunks_info);
    2947                 :          0 :                         cpfl_p2p_queue_grps_del(vport);
    2948                 :            :                 }
    2949                 :            :         }
    2950                 :            :         /* get the vport info */
    2951         [ #  # ]:          0 :         if (idpf_is_vf_device(&adapter->base.hw)) {
    2952                 :          0 :                 pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
    2953                 :          0 :                 vi.func_type = VCPF_CPCHNL2_FTYPE_LAN_VF;
    2954                 :          0 :                 vi.pf_id = CPFL_HOST0_CPF_ID;
    2955                 :          0 :                 vi.vf_id = VCPF_VF_ID_FROM_PCI(pci_dev->addr.devid,
    2956                 :            :                                                 pci_dev->addr.function);
    2957                 :            : 
    2958                 :          0 :                 v_id.vport_id = cpfl_vport->base.vport_info.info.vport_id;
    2959                 :          0 :                 v_id.vport_type = cpfl_vport->base.vport_info.info.vport_type;
    2960                 :            : 
    2961                 :          0 :                 ret = cpfl_cc_vport_info_get(adapter, &v_id, &vi, &response);
    2962         [ #  # ]:          0 :                 if (ret != 0) {
    2963                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to send vport info cpchnl message.");
    2964                 :          0 :                         return -1;
    2965                 :            :                 }
    2966                 :            : 
    2967                 :          0 :                 ret = vcpf_save_vport_info_response(cpfl_vport, &response);
    2968         [ #  # ]:          0 :                 if (ret != 0) {
    2969                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to save cpchnl response.");
    2970                 :          0 :                         return -1;
    2971                 :            :                 }
    2972                 :            :         }
    2973                 :            : 
    2974                 :            :         return 0;
    2975                 :            : 
    2976                 :          0 : err_mac_addrs:
    2977                 :          0 :         adapter->vports[param->idx] = NULL;  /* reset */
    2978                 :          0 :         idpf_vport_deinit(vport);
    2979                 :          0 :         adapter->cur_vports &= ~RTE_BIT32(param->devarg_id);
    2980                 :          0 :         adapter->cur_vport_nb--;
    2981                 :            : err:
    2982                 :            :         return ret;
    2983                 :            : }
    2984                 :            : 
    2985                 :            : static const struct rte_pci_id pci_id_cpfl_map[] = {
    2986                 :            :         { RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, CPFL_DEV_ID_MEV) },
    2987                 :            :         { RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, CPFL_DEV_ID_MMG) },
    2988                 :            :         { .vendor_id = 0, /* sentinel */ },
    2989                 :            : };
    2990                 :            : 
    2991                 :            : static const struct rte_pci_id pci_id_vcpf_map[] = {
    2992                 :            :         { RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, IXD_DEV_ID_VCPF) },
    2993                 :            :         { .vendor_id = 0, /* sentinel */ },
    2994                 :            : };
    2995                 :            : 
    2996                 :            : static struct cpfl_adapter_ext *
    2997                 :          0 : cpfl_find_adapter_ext(struct rte_pci_device *pci_dev)
    2998                 :            : {
    2999                 :            :         struct cpfl_adapter_ext *adapter;
    3000                 :            :         int found = 0;
    3001                 :            : 
    3002         [ #  # ]:          0 :         if (pci_dev == NULL)
    3003                 :            :                 return NULL;
    3004                 :            : 
    3005                 :            :         rte_spinlock_lock(&cpfl_adapter_lock);
    3006         [ #  # ]:          0 :         TAILQ_FOREACH(adapter, &cpfl_adapter_list, next) {
    3007         [ #  # ]:          0 :                 if (strncmp(adapter->name, pci_dev->device.name, PCI_PRI_STR_SIZE) == 0) {
    3008                 :            :                         found = 1;
    3009                 :            :                         break;
    3010                 :            :                 }
    3011                 :            :         }
    3012                 :            :         rte_spinlock_unlock(&cpfl_adapter_lock);
    3013                 :            : 
    3014         [ #  # ]:          0 :         if (found == 0)
    3015                 :          0 :                 return NULL;
    3016                 :            : 
    3017                 :            :         return adapter;
    3018                 :            : }
    3019                 :            : 
    3020                 :            : static void
    3021                 :          0 : cpfl_adapter_ext_deinit(struct cpfl_adapter_ext *adapter)
    3022                 :            : {
    3023                 :            : #ifdef RTE_HAS_JANSSON
    3024                 :          0 :         cpfl_flow_uninit(adapter);
    3025                 :            : #endif
    3026                 :          0 :         cpfl_ctrl_path_close(adapter);
    3027                 :          0 :         rte_eal_alarm_cancel(cpfl_dev_alarm_handler, adapter);
    3028                 :          0 :         cpfl_vport_map_uninit(adapter);
    3029                 :          0 :         idpf_adapter_deinit(&adapter->base);
    3030                 :            : 
    3031                 :          0 :         rte_free(adapter->vports);
    3032                 :          0 :         adapter->vports = NULL;
    3033                 :          0 : }
    3034                 :            : 
    3035                 :            : static int
    3036                 :          0 : cpfl_vport_devargs_process(struct cpfl_adapter_ext *adapter, struct cpfl_devargs *devargs)
    3037                 :            : {
    3038                 :            :         int i;
    3039                 :            : 
    3040                 :            :         /* refine vport number, at least 1 vport */
    3041         [ #  # ]:          0 :         if (devargs->req_vport_nb == 0) {
    3042                 :          0 :                 devargs->req_vport_nb = 1;
    3043                 :          0 :                 devargs->req_vports[0] = 0;
    3044                 :            :         }
    3045                 :            : 
    3046                 :            :         /* check parsed devargs */
    3047                 :          0 :         if (adapter->cur_vport_nb + devargs->req_vport_nb >
    3048         [ #  # ]:          0 :             adapter->max_vport_nb) {
    3049                 :          0 :                 PMD_INIT_LOG(ERR, "Total vport number can't be > %d",
    3050                 :            :                              adapter->max_vport_nb);
    3051                 :          0 :                 return -EINVAL;
    3052                 :            :         }
    3053                 :            : 
    3054         [ #  # ]:          0 :         for (i = 0; i < devargs->req_vport_nb; i++) {
    3055         [ #  # ]:          0 :                 if (devargs->req_vports[i] > adapter->max_vport_nb - 1) {
    3056                 :          0 :                         PMD_INIT_LOG(ERR, "Invalid vport id %d, it should be 0 ~ %d",
    3057                 :            :                                      devargs->req_vports[i], adapter->max_vport_nb - 1);
    3058                 :          0 :                         return -EINVAL;
    3059                 :            :                 }
    3060                 :            : 
    3061         [ #  # ]:          0 :                 if (adapter->cur_vports & RTE_BIT32(devargs->req_vports[i])) {
    3062                 :          0 :                         PMD_INIT_LOG(ERR, "Vport %d has been requested",
    3063                 :            :                                      devargs->req_vports[i]);
    3064                 :          0 :                         return -EINVAL;
    3065                 :            :                 }
    3066                 :            :         }
    3067                 :            : 
    3068                 :            :         return 0;
    3069                 :            : }
    3070                 :            : 
    3071                 :            : static int
    3072                 :          0 : cpfl_vport_create(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adapter,
    3073                 :            :                   struct cpfl_devargs *devargs)
    3074                 :            : {
    3075                 :            :         struct cpfl_vport_param vport_param;
    3076                 :            :         char name[RTE_ETH_NAME_MAX_LEN];
    3077                 :            :         int ret, i;
    3078                 :            : 
    3079         [ #  # ]:          0 :         for (i = 0; i < devargs->req_vport_nb; i++) {
    3080                 :          0 :                 vport_param.adapter = adapter;
    3081                 :          0 :                 vport_param.devarg_id = devargs->req_vports[i];
    3082                 :          0 :                 vport_param.idx = cpfl_vport_idx_alloc(adapter);
    3083         [ #  # ]:          0 :                 if (vport_param.idx == CPFL_INVALID_VPORT_IDX) {
    3084                 :          0 :                         PMD_INIT_LOG(ERR, "No space for vport %u", vport_param.devarg_id);
    3085                 :          0 :                         break;
    3086                 :            :                 }
    3087                 :          0 :                 snprintf(name, sizeof(name), "net_%s_vport_%d",
    3088                 :            :                          pci_dev->device.name,
    3089                 :            :                          devargs->req_vports[i]);
    3090                 :          0 :                 ret = rte_eth_dev_create(&pci_dev->device, name,
    3091                 :            :                                             sizeof(struct cpfl_vport),
    3092                 :            :                                             NULL, NULL, cpfl_dev_vport_init,
    3093                 :            :                                             &vport_param);
    3094         [ #  # ]:          0 :                 if (ret != 0)
    3095                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to create vport %d",
    3096                 :            :                                     vport_param.devarg_id);
    3097                 :            :         }
    3098                 :            : 
    3099                 :          0 :         return 0;
    3100                 :            : }
    3101                 :            : 
    3102                 :            : static int
    3103                 :          0 : cpfl_pci_probe_first(struct rte_pci_device *pci_dev)
    3104                 :            : {
    3105                 :            :         struct cpfl_adapter_ext *adapter;
    3106                 :            :         struct cpfl_devargs devargs;
    3107                 :            :         int retval;
    3108                 :            :         uint16_t port_id;
    3109                 :            : 
    3110                 :          0 :         adapter = rte_zmalloc("cpfl_adapter_ext",
    3111                 :            :                               sizeof(struct cpfl_adapter_ext), 0);
    3112         [ #  # ]:          0 :         if (adapter == NULL) {
    3113                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to allocate adapter.");
    3114                 :          0 :                 return -ENOMEM;
    3115                 :            :         }
    3116                 :            : 
    3117                 :            :         memset(&devargs, 0, sizeof(devargs));
    3118                 :            : 
    3119                 :          0 :         retval = cpfl_parse_devargs(pci_dev, adapter, true, &devargs);
    3120         [ #  # ]:          0 :         if (retval != 0) {
    3121                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to parse private devargs");
    3122                 :          0 :                 return retval;
    3123                 :            :         }
    3124                 :            : 
    3125                 :          0 :         retval = cpfl_adapter_ext_init(pci_dev, adapter, &devargs);
    3126         [ #  # ]:          0 :         if (retval != 0) {
    3127                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to init adapter.");
    3128                 :          0 :                 return retval;
    3129                 :            :         }
    3130                 :            : 
    3131                 :            :         rte_spinlock_lock(&cpfl_adapter_lock);
    3132                 :          0 :         TAILQ_INSERT_TAIL(&cpfl_adapter_list, adapter, next);
    3133                 :            :         rte_spinlock_unlock(&cpfl_adapter_lock);
    3134                 :            : 
    3135                 :          0 :         retval = cpfl_vport_devargs_process(adapter, &devargs);
    3136         [ #  # ]:          0 :         if (retval != 0) {
    3137                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to process vport devargs");
    3138                 :          0 :                 goto err;
    3139                 :            :         }
    3140                 :            : 
    3141                 :          0 :         retval = cpfl_vport_create(pci_dev, adapter, &devargs);
    3142         [ #  # ]:          0 :         if (retval != 0) {
    3143                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to create vports.");
    3144                 :          0 :                 goto err;
    3145                 :            :         }
    3146                 :            : 
    3147                 :          0 :         retval = cpfl_repr_devargs_process(adapter, &devargs);
    3148         [ #  # ]:          0 :         if (retval != 0) {
    3149                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to process repr devargs");
    3150                 :          0 :                 goto close_ethdev;
    3151                 :            :         }
    3152                 :            : 
    3153                 :          0 :         retval = cpfl_repr_create(pci_dev, adapter);
    3154         [ #  # ]:          0 :         if (retval != 0) {
    3155                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to create representors ");
    3156                 :          0 :                 goto close_ethdev;
    3157                 :            :         }
    3158                 :            : 
    3159                 :            : 
    3160                 :            :         return 0;
    3161                 :            : 
    3162                 :          0 : close_ethdev:
    3163                 :            :         /* Ethdev created can be found RTE_ETH_FOREACH_DEV_OF through rte_device */
    3164         [ #  # ]:          0 :         RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) {
    3165                 :          0 :                 rte_eth_dev_close(port_id);
    3166                 :            :         }
    3167                 :          0 : err:
    3168                 :            :         rte_spinlock_lock(&cpfl_adapter_lock);
    3169         [ #  # ]:          0 :         TAILQ_REMOVE(&cpfl_adapter_list, adapter, next);
    3170                 :            :         rte_spinlock_unlock(&cpfl_adapter_lock);
    3171                 :          0 :         cpfl_adapter_ext_deinit(adapter);
    3172                 :          0 :         rte_free(adapter);
    3173                 :          0 :         return retval;
    3174                 :            : }
    3175                 :            : 
    3176                 :            : static int
    3177                 :          0 : cpfl_pci_probe_again(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adapter)
    3178                 :            : {
    3179                 :            :         struct cpfl_devargs devargs;
    3180                 :            :         int ret;
    3181                 :            : 
    3182                 :            :         memset(&devargs, 0, sizeof(devargs));
    3183                 :          0 :         ret = cpfl_parse_devargs(pci_dev, adapter, false, &devargs);
    3184         [ #  # ]:          0 :         if (ret != 0) {
    3185                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to parse private devargs");
    3186                 :          0 :                 return ret;
    3187                 :            :         }
    3188                 :            : 
    3189                 :          0 :         ret = cpfl_repr_devargs_process(adapter, &devargs);
    3190         [ #  # ]:          0 :         if (ret != 0) {
    3191                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to process reprenstor devargs");
    3192                 :          0 :                 return ret;
    3193                 :            :         }
    3194                 :            : 
    3195                 :          0 :         ret = cpfl_repr_create(pci_dev, adapter);
    3196         [ #  # ]:          0 :         if (ret != 0) {
    3197                 :          0 :                 PMD_INIT_LOG(ERR, "Failed to create representors ");
    3198                 :          0 :                 return ret;
    3199                 :            :         }
    3200                 :            : 
    3201                 :            :         return 0;
    3202                 :            : }
    3203                 :            : 
    3204                 :            : static int
    3205                 :          0 : cpfl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
    3206                 :            :                struct rte_pci_device *pci_dev)
    3207                 :            : {
    3208                 :            :         struct cpfl_adapter_ext *adapter;
    3209                 :            : 
    3210         [ #  # ]:          0 :         if (!cpfl_adapter_list_init) {
    3211                 :            :                 rte_spinlock_init(&cpfl_adapter_lock);
    3212                 :          0 :                 TAILQ_INIT(&cpfl_adapter_list);
    3213                 :          0 :                 cpfl_adapter_list_init = true;
    3214                 :            :         }
    3215                 :            : 
    3216                 :          0 :         adapter = cpfl_find_adapter_ext(pci_dev);
    3217                 :            : 
    3218         [ #  # ]:          0 :         if (adapter == NULL)
    3219                 :          0 :                 return cpfl_pci_probe_first(pci_dev);
    3220                 :            :         else
    3221                 :          0 :                 return cpfl_pci_probe_again(pci_dev, adapter);
    3222                 :            : }
    3223                 :            : 
    3224                 :            : static int
    3225                 :          0 : cpfl_pci_remove(struct rte_pci_device *pci_dev)
    3226                 :            : {
    3227                 :          0 :         struct cpfl_adapter_ext *adapter = cpfl_find_adapter_ext(pci_dev);
    3228                 :            :         uint16_t port_id;
    3229                 :            : 
    3230                 :            :         /* Ethdev created can be found RTE_ETH_FOREACH_DEV_OF through rte_device */
    3231         [ #  # ]:          0 :         RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) {
    3232                 :          0 :                         rte_eth_dev_close(port_id);
    3233                 :            :         }
    3234                 :            : 
    3235                 :            :         rte_spinlock_lock(&cpfl_adapter_lock);
    3236         [ #  # ]:          0 :         TAILQ_REMOVE(&cpfl_adapter_list, adapter, next);
    3237                 :            :         rte_spinlock_unlock(&cpfl_adapter_lock);
    3238                 :          0 :         cpfl_adapter_ext_deinit(adapter);
    3239                 :          0 :         rte_free(adapter);
    3240                 :            : 
    3241                 :          0 :         return 0;
    3242                 :            : }
    3243                 :            : 
    3244                 :            : static struct rte_pci_driver rte_cpfl_pmd = {
    3245                 :            :         .id_table       = pci_id_cpfl_map,
    3246                 :            :         .drv_flags      = RTE_PCI_DRV_NEED_MAPPING |
    3247                 :            :                           RTE_PCI_DRV_PROBE_AGAIN,
    3248                 :            :         .probe          = cpfl_pci_probe,
    3249                 :            :         .remove         = cpfl_pci_remove,
    3250                 :            : };
    3251                 :            : 
    3252                 :            : static struct rte_pci_driver rte_vcpf_pmd = {
    3253                 :            :         .id_table       = pci_id_vcpf_map,
    3254                 :            :         .drv_flags      = RTE_PCI_DRV_NEED_MAPPING |
    3255                 :            :                           RTE_PCI_DRV_PROBE_AGAIN,
    3256                 :            :         .probe          = cpfl_pci_probe,
    3257                 :            :         .remove         = cpfl_pci_remove,
    3258                 :            : };
    3259                 :            : 
    3260                 :            : /**
    3261                 :            :  * Driver initialization routine.
    3262                 :            :  * Invoked once at EAL init time.
    3263                 :            :  * Register itself as the [Poll Mode] Driver of PCI devices.
    3264                 :            :  */
    3265                 :        302 : RTE_PMD_REGISTER_PCI(net_cpfl, rte_cpfl_pmd);
    3266                 :            : RTE_PMD_REGISTER_PCI_TABLE(net_cpfl, pci_id_cpfl_map);
    3267                 :            : RTE_PMD_REGISTER_KMOD_DEP(net_cpfl, "* igb_uio | vfio-pci");
    3268                 :        302 : RTE_PMD_REGISTER_PCI(net_vcpf, rte_vcpf_pmd);
    3269                 :            : RTE_PMD_REGISTER_PCI_TABLE(net_vcpf, pci_id_vcpf_map);
    3270                 :            : RTE_PMD_REGISTER_KMOD_DEP(net_vcpf, "vfio-pci");
    3271                 :            : RTE_PMD_REGISTER_PARAM_STRING(net_cpfl,
    3272                 :            :         CPFL_TX_SINGLE_Q "=<0|1> "
    3273                 :            :         CPFL_RX_SINGLE_Q "=<0|1> "
    3274                 :            :         CPFL_VPORT "=[vport0_begin[-vport0_end][,vport1_begin[-vport1_end]][,..]]");
    3275                 :            : 
    3276         [ -  + ]:        302 : RTE_LOG_REGISTER_SUFFIX(cpfl_logtype_init, init, NOTICE);
    3277         [ -  + ]:        302 : RTE_LOG_REGISTER_SUFFIX(cpfl_logtype_driver, driver, NOTICE);

Generated by: LCOV version 1.14