LCOV - code coverage report
Current view: top level - drivers/net/gve - gve_ethdev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 2 383 0.5 %
Date: 2024-01-22 16:26:08 Functions: 2 26 7.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 186 0.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2022 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "gve_ethdev.h"
       6                 :            : #include "base/gve_adminq.h"
       7                 :            : #include "base/gve_register.h"
       8                 :            : #include "base/gve_osdep.h"
       9                 :            : #include "gve_version.h"
      10                 :            : #include "rte_ether.h"
      11                 :            : 
      12                 :            : static void
      13                 :            : gve_write_version(uint8_t *driver_version_register)
      14                 :            : {
      15                 :          0 :         const char *c = gve_version_string();
      16         [ #  # ]:          0 :         while (*c) {
      17                 :          0 :                 writeb(*c, driver_version_register);
      18                 :          0 :                 c++;
      19                 :            :         }
      20                 :            :         writeb('\n', driver_version_register);
      21                 :            : }
      22                 :            : 
      23                 :            : static int
      24                 :          0 : gve_alloc_queue_page_list(struct gve_priv *priv, uint32_t id, uint32_t pages)
      25                 :            : {
      26                 :            :         char z_name[RTE_MEMZONE_NAMESIZE];
      27                 :            :         struct gve_queue_page_list *qpl;
      28                 :            :         const struct rte_memzone *mz;
      29                 :            :         dma_addr_t page_bus;
      30                 :            :         uint32_t i;
      31                 :            : 
      32                 :          0 :         if (priv->num_registered_pages + pages >
      33         [ #  # ]:          0 :             priv->max_registered_pages) {
      34                 :          0 :                 PMD_DRV_LOG(ERR, "Pages %" PRIu64 " > max registered pages %" PRIu64,
      35                 :            :                             priv->num_registered_pages + pages,
      36                 :            :                             priv->max_registered_pages);
      37                 :          0 :                 return -EINVAL;
      38                 :            :         }
      39                 :          0 :         qpl = &priv->qpl[id];
      40                 :          0 :         snprintf(z_name, sizeof(z_name), "gve_%s_qpl%d", priv->pci_dev->device.name, id);
      41                 :          0 :         mz = rte_memzone_reserve_aligned(z_name, pages * PAGE_SIZE,
      42                 :          0 :                                          rte_socket_id(),
      43                 :            :                                          RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
      44         [ #  # ]:          0 :         if (mz == NULL) {
      45                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc %s.", z_name);
      46                 :          0 :                 return -ENOMEM;
      47                 :            :         }
      48                 :          0 :         qpl->page_buses = rte_zmalloc("qpl page buses", pages * sizeof(dma_addr_t), 0);
      49         [ #  # ]:          0 :         if (qpl->page_buses == NULL) {
      50                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc qpl %u page buses", id);
      51                 :          0 :                 return -ENOMEM;
      52                 :            :         }
      53                 :          0 :         page_bus = mz->iova;
      54         [ #  # ]:          0 :         for (i = 0; i < pages; i++) {
      55                 :          0 :                 qpl->page_buses[i] = page_bus;
      56                 :          0 :                 page_bus += PAGE_SIZE;
      57                 :            :         }
      58                 :          0 :         qpl->id = id;
      59                 :          0 :         qpl->mz = mz;
      60                 :          0 :         qpl->num_entries = pages;
      61                 :            : 
      62                 :          0 :         priv->num_registered_pages += pages;
      63                 :            : 
      64                 :          0 :         return 0;
      65                 :            : }
      66                 :            : 
      67                 :            : static void
      68                 :          0 : gve_free_qpls(struct gve_priv *priv)
      69                 :            : {
      70                 :          0 :         uint16_t nb_txqs = priv->max_nb_txq;
      71                 :          0 :         uint16_t nb_rxqs = priv->max_nb_rxq;
      72                 :            :         uint32_t i;
      73                 :            : 
      74         [ #  # ]:          0 :         if (priv->queue_format != GVE_GQI_QPL_FORMAT)
      75                 :            :                 return;
      76                 :            : 
      77         [ #  # ]:          0 :         for (i = 0; i < nb_txqs + nb_rxqs; i++) {
      78         [ #  # ]:          0 :                 if (priv->qpl[i].mz != NULL)
      79                 :          0 :                         rte_memzone_free(priv->qpl[i].mz);
      80                 :          0 :                 rte_free(priv->qpl[i].page_buses);
      81                 :            :         }
      82                 :            : 
      83                 :          0 :         rte_free(priv->qpl);
      84                 :            : }
      85                 :            : 
      86                 :            : static int
      87                 :          0 : gve_dev_configure(struct rte_eth_dev *dev)
      88                 :            : {
      89                 :          0 :         struct gve_priv *priv = dev->data->dev_private;
      90                 :            : 
      91         [ #  # ]:          0 :         if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
      92                 :          0 :                 dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
      93                 :            : 
      94         [ #  # ]:          0 :         if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
      95                 :          0 :                 priv->enable_rsc = 1;
      96                 :            : 
      97                 :          0 :         return 0;
      98                 :            : }
      99                 :            : 
     100                 :            : static int
     101                 :          0 : gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
     102                 :            : {
     103         [ #  # ]:          0 :         struct gve_priv *priv = dev->data->dev_private;
     104                 :            :         struct rte_eth_link link;
     105                 :            :         int err;
     106                 :            : 
     107                 :            :         memset(&link, 0, sizeof(link));
     108                 :          0 :         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     109                 :          0 :         link.link_autoneg = RTE_ETH_LINK_AUTONEG;
     110                 :            : 
     111         [ #  # ]:          0 :         if (!dev->data->dev_started) {
     112                 :            :                 link.link_status = RTE_ETH_LINK_DOWN;
     113                 :            :                 link.link_speed = RTE_ETH_SPEED_NUM_NONE;
     114                 :            :         } else {
     115                 :          0 :                 link.link_status = RTE_ETH_LINK_UP;
     116                 :          0 :                 PMD_DRV_LOG(DEBUG, "Get link status from hw");
     117                 :          0 :                 err = gve_adminq_report_link_speed(priv);
     118         [ #  # ]:          0 :                 if (err) {
     119                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to get link speed.");
     120                 :          0 :                         priv->link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
     121                 :            :                 }
     122                 :          0 :                 link.link_speed = priv->link_speed;
     123                 :            :         }
     124                 :            : 
     125                 :          0 :         return rte_eth_linkstatus_set(dev, &link);
     126                 :            : }
     127                 :            : 
     128                 :            : static int
     129                 :          0 : gve_start_queues(struct rte_eth_dev *dev)
     130                 :            : {
     131                 :          0 :         struct gve_priv *priv = dev->data->dev_private;
     132                 :            :         uint16_t num_queues;
     133                 :            :         uint16_t i;
     134                 :            :         int ret;
     135                 :            : 
     136                 :          0 :         num_queues = dev->data->nb_tx_queues;
     137                 :          0 :         priv->txqs = (struct gve_tx_queue **)dev->data->tx_queues;
     138                 :          0 :         ret = gve_adminq_create_tx_queues(priv, num_queues);
     139         [ #  # ]:          0 :         if (ret != 0) {
     140                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to create %u tx queues.", num_queues);
     141                 :          0 :                 return ret;
     142                 :            :         }
     143         [ #  # ]:          0 :         for (i = 0; i < num_queues; i++)
     144         [ #  # ]:          0 :                 if (gve_tx_queue_start(dev, i) != 0) {
     145                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to start Tx queue %d", i);
     146                 :          0 :                         goto err_tx;
     147                 :            :                 }
     148                 :            : 
     149                 :          0 :         num_queues = dev->data->nb_rx_queues;
     150                 :          0 :         priv->rxqs = (struct gve_rx_queue **)dev->data->rx_queues;
     151                 :          0 :         ret = gve_adminq_create_rx_queues(priv, num_queues);
     152         [ #  # ]:          0 :         if (ret != 0) {
     153                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to create %u rx queues.", num_queues);
     154                 :          0 :                 goto err_tx;
     155                 :            :         }
     156         [ #  # ]:          0 :         for (i = 0; i < num_queues; i++) {
     157         [ #  # ]:          0 :                 if (gve_is_gqi(priv))
     158                 :          0 :                         ret = gve_rx_queue_start(dev, i);
     159                 :            :                 else
     160                 :          0 :                         ret = gve_rx_queue_start_dqo(dev, i);
     161         [ #  # ]:          0 :                 if (ret != 0) {
     162                 :          0 :                         PMD_DRV_LOG(ERR, "Fail to start Rx queue %d", i);
     163                 :          0 :                         goto err_rx;
     164                 :            :                 }
     165                 :            :         }
     166                 :            : 
     167                 :            :         return 0;
     168                 :            : 
     169                 :            : err_rx:
     170                 :          0 :         gve_stop_rx_queues(dev);
     171                 :          0 : err_tx:
     172                 :          0 :         gve_stop_tx_queues(dev);
     173                 :          0 :         return ret;
     174                 :            : }
     175                 :            : 
     176                 :            : static int
     177                 :          0 : gve_dev_start(struct rte_eth_dev *dev)
     178                 :            : {
     179                 :            :         int ret;
     180                 :            : 
     181                 :          0 :         ret = gve_start_queues(dev);
     182         [ #  # ]:          0 :         if (ret != 0) {
     183                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to start queues");
     184                 :          0 :                 return ret;
     185                 :            :         }
     186                 :            : 
     187                 :          0 :         dev->data->dev_started = 1;
     188                 :          0 :         gve_link_update(dev, 0);
     189                 :            : 
     190                 :          0 :         return 0;
     191                 :            : }
     192                 :            : 
     193                 :            : static int
     194                 :          0 : gve_dev_stop(struct rte_eth_dev *dev)
     195                 :            : {
     196                 :          0 :         dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
     197                 :            : 
     198                 :          0 :         gve_stop_tx_queues(dev);
     199                 :          0 :         gve_stop_rx_queues(dev);
     200                 :            : 
     201                 :          0 :         dev->data->dev_started = 0;
     202                 :            : 
     203                 :          0 :         return 0;
     204                 :            : }
     205                 :            : 
     206                 :            : static int
     207                 :          0 : gve_dev_close(struct rte_eth_dev *dev)
     208                 :            : {
     209                 :          0 :         struct gve_priv *priv = dev->data->dev_private;
     210                 :            :         int err = 0;
     211                 :            :         uint16_t i;
     212                 :            : 
     213         [ #  # ]:          0 :         if (dev->data->dev_started) {
     214                 :            :                 err = gve_dev_stop(dev);
     215                 :            :                 if (err != 0)
     216                 :            :                         PMD_DRV_LOG(ERR, "Failed to stop dev.");
     217                 :            :         }
     218                 :            : 
     219         [ #  # ]:          0 :         if (gve_is_gqi(priv)) {
     220         [ #  # ]:          0 :                 for (i = 0; i < dev->data->nb_tx_queues; i++)
     221                 :          0 :                         gve_tx_queue_release(dev, i);
     222                 :            : 
     223         [ #  # ]:          0 :                 for (i = 0; i < dev->data->nb_rx_queues; i++)
     224                 :          0 :                         gve_rx_queue_release(dev, i);
     225                 :            :         } else {
     226         [ #  # ]:          0 :                 for (i = 0; i < dev->data->nb_tx_queues; i++)
     227                 :          0 :                         gve_tx_queue_release_dqo(dev, i);
     228                 :            : 
     229         [ #  # ]:          0 :                 for (i = 0; i < dev->data->nb_rx_queues; i++)
     230                 :          0 :                         gve_rx_queue_release_dqo(dev, i);
     231                 :            :         }
     232                 :            : 
     233                 :          0 :         gve_free_qpls(priv);
     234                 :          0 :         rte_free(priv->adminq);
     235                 :            : 
     236                 :          0 :         dev->data->mac_addrs = NULL;
     237                 :            : 
     238                 :          0 :         return err;
     239                 :            : }
     240                 :            : 
     241                 :            : static int
     242                 :          0 : gve_verify_driver_compatibility(struct gve_priv *priv)
     243                 :            : {
     244                 :            :         const struct rte_memzone *driver_info_mem;
     245                 :            :         struct gve_driver_info *driver_info;
     246                 :            :         int err;
     247                 :            : 
     248                 :          0 :         driver_info_mem = rte_memzone_reserve_aligned("verify_driver_compatibility",
     249                 :            :                         sizeof(struct gve_driver_info),
     250                 :          0 :                         rte_socket_id(),
     251                 :            :                         RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
     252                 :            : 
     253         [ #  # ]:          0 :         if (driver_info_mem == NULL) {
     254                 :          0 :                 PMD_DRV_LOG(ERR,
     255                 :            :                     "Could not alloc memzone for driver compatibility");
     256                 :          0 :                 return -ENOMEM;
     257                 :            :         }
     258                 :          0 :         driver_info = (struct gve_driver_info *)driver_info_mem->addr;
     259                 :            : 
     260                 :          0 :         *driver_info = (struct gve_driver_info) {
     261                 :            :                 .os_type = 5, /* DPDK */
     262                 :            :                 .driver_major = GVE_VERSION_MAJOR,
     263                 :            :                 .driver_minor = GVE_VERSION_MINOR,
     264                 :            :                 .driver_sub = GVE_VERSION_SUB,
     265                 :            :                 .os_version_major = cpu_to_be32(DPDK_VERSION_MAJOR),
     266                 :            :                 .os_version_minor = cpu_to_be32(DPDK_VERSION_MINOR),
     267                 :            :                 .os_version_sub = cpu_to_be32(DPDK_VERSION_SUB),
     268                 :            :                 .driver_capability_flags = {
     269                 :            :                         cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS1),
     270                 :            :                         cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS2),
     271                 :            :                         cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS3),
     272                 :            :                         cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS4),
     273                 :            :                 },
     274                 :            :         };
     275                 :            : 
     276                 :          0 :         populate_driver_version_strings((char *)driver_info->os_version_str1,
     277                 :          0 :                         (char *)driver_info->os_version_str2);
     278                 :            : 
     279                 :          0 :         err = gve_adminq_verify_driver_compatibility(priv,
     280                 :            :                 sizeof(struct gve_driver_info),
     281                 :          0 :                 (dma_addr_t)driver_info_mem->iova);
     282                 :            :         /* It's ok if the device doesn't support this */
     283         [ #  # ]:          0 :         if (err == -EOPNOTSUPP)
     284                 :            :                 err = 0;
     285                 :            : 
     286                 :          0 :         rte_memzone_free(driver_info_mem);
     287                 :          0 :         return err;
     288                 :            : }
     289                 :            : 
     290                 :            : static int
     291                 :          0 : gve_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
     292                 :            : {
     293                 :          0 :         struct gve_priv *priv = dev->data->dev_private;
     294                 :            : 
     295                 :          0 :         dev_info->device = dev->device;
     296                 :          0 :         dev_info->max_mac_addrs = 1;
     297                 :          0 :         dev_info->max_rx_queues = priv->max_nb_rxq;
     298         [ #  # ]:          0 :         dev_info->max_tx_queues = priv->max_nb_txq;
     299         [ #  # ]:          0 :         if (gve_is_gqi(priv)) {
     300                 :          0 :                 dev_info->min_rx_bufsize = GVE_RX_MIN_BUF_SIZE_GQI;
     301                 :          0 :                 dev_info->max_rx_bufsize = GVE_RX_MAX_BUF_SIZE_GQI;
     302                 :            :         } else {
     303                 :          0 :                 dev_info->min_rx_bufsize = GVE_RX_MIN_BUF_SIZE_DQO;
     304                 :          0 :                 dev_info->max_rx_bufsize = GVE_RX_MAX_BUF_SIZE_DQO;
     305                 :            :         }
     306                 :            : 
     307                 :          0 :         dev_info->max_rx_pktlen = priv->max_mtu + RTE_ETHER_HDR_LEN;
     308                 :          0 :         dev_info->max_mtu = priv->max_mtu;
     309                 :          0 :         dev_info->min_mtu = RTE_ETHER_MIN_MTU;
     310                 :            : 
     311                 :          0 :         dev_info->rx_offload_capa = 0;
     312                 :          0 :         dev_info->tx_offload_capa =
     313                 :            :                 RTE_ETH_TX_OFFLOAD_MULTI_SEGS   |
     314                 :            :                 RTE_ETH_TX_OFFLOAD_UDP_CKSUM    |
     315                 :            :                 RTE_ETH_TX_OFFLOAD_TCP_CKSUM    |
     316                 :            :                 RTE_ETH_TX_OFFLOAD_SCTP_CKSUM   |
     317                 :            :                 RTE_ETH_TX_OFFLOAD_TCP_TSO;
     318                 :            : 
     319         [ #  # ]:          0 :         if (priv->queue_format == GVE_DQO_RDA_FORMAT)
     320                 :          0 :                 dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TCP_LRO;
     321                 :            : 
     322                 :          0 :         dev_info->default_rxconf = (struct rte_eth_rxconf) {
     323                 :            :                 .rx_free_thresh = GVE_DEFAULT_RX_FREE_THRESH,
     324                 :            :                 .rx_drop_en = 0,
     325                 :            :                 .offloads = 0,
     326                 :            :         };
     327                 :            : 
     328                 :          0 :         dev_info->default_txconf = (struct rte_eth_txconf) {
     329                 :            :                 .tx_free_thresh = GVE_DEFAULT_TX_FREE_THRESH,
     330                 :            :                 .tx_rs_thresh = GVE_DEFAULT_TX_RS_THRESH,
     331                 :            :                 .offloads = 0,
     332                 :            :         };
     333                 :            : 
     334                 :          0 :         dev_info->default_rxportconf.ring_size = priv->rx_desc_cnt;
     335         [ #  # ]:          0 :         dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
     336                 :            :                 .nb_max = gve_is_gqi(priv) ? priv->rx_desc_cnt : GVE_MAX_QUEUE_SIZE_DQO,
     337                 :            :                 .nb_min = priv->rx_desc_cnt,
     338                 :            :                 .nb_align = 1,
     339                 :            :         };
     340                 :            : 
     341                 :          0 :         dev_info->default_txportconf.ring_size = priv->tx_desc_cnt;
     342         [ #  # ]:          0 :         dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
     343                 :            :                 .nb_max = gve_is_gqi(priv) ? priv->tx_desc_cnt : GVE_MAX_QUEUE_SIZE_DQO,
     344                 :            :                 .nb_min = priv->tx_desc_cnt,
     345                 :            :                 .nb_align = 1,
     346                 :            :         };
     347                 :            : 
     348                 :          0 :         return 0;
     349                 :            : }
     350                 :            : 
     351                 :            : static int
     352                 :          0 : gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
     353                 :            : {
     354                 :            :         uint16_t i;
     355                 :            : 
     356         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     357                 :          0 :                 struct gve_tx_queue *txq = dev->data->tx_queues[i];
     358         [ #  # ]:          0 :                 if (txq == NULL)
     359                 :          0 :                         continue;
     360                 :            : 
     361                 :          0 :                 stats->opackets += txq->stats.packets;
     362                 :          0 :                 stats->obytes += txq->stats.bytes;
     363                 :          0 :                 stats->oerrors += txq->stats.errors;
     364                 :            :         }
     365                 :            : 
     366         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     367                 :          0 :                 struct gve_rx_queue *rxq = dev->data->rx_queues[i];
     368         [ #  # ]:          0 :                 if (rxq == NULL)
     369                 :          0 :                         continue;
     370                 :            : 
     371                 :          0 :                 stats->ipackets += rxq->stats.packets;
     372                 :          0 :                 stats->ibytes += rxq->stats.bytes;
     373                 :          0 :                 stats->ierrors += rxq->stats.errors;
     374                 :          0 :                 stats->rx_nombuf += rxq->stats.no_mbufs;
     375                 :            :         }
     376                 :            : 
     377                 :          0 :         return 0;
     378                 :            : }
     379                 :            : 
     380                 :            : static int
     381                 :          0 : gve_dev_stats_reset(struct rte_eth_dev *dev)
     382                 :            : {
     383                 :            :         uint16_t i;
     384                 :            : 
     385         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     386                 :          0 :                 struct gve_tx_queue *txq = dev->data->tx_queues[i];
     387         [ #  # ]:          0 :                 if (txq == NULL)
     388                 :          0 :                         continue;
     389                 :            : 
     390                 :          0 :                 memset(&txq->stats, 0, sizeof(txq->stats));
     391                 :            :         }
     392                 :            : 
     393         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     394                 :          0 :                 struct gve_rx_queue *rxq = dev->data->rx_queues[i];
     395         [ #  # ]:          0 :                 if (rxq == NULL)
     396                 :          0 :                         continue;
     397                 :            : 
     398                 :          0 :                 memset(&rxq->stats, 0, sizeof(rxq->stats));
     399                 :            :         }
     400                 :            : 
     401                 :          0 :         return 0;
     402                 :            : }
     403                 :            : 
     404                 :            : static int
     405                 :          0 : gve_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
     406                 :            : {
     407                 :          0 :         struct gve_priv *priv = dev->data->dev_private;
     408                 :            :         int err;
     409                 :            : 
     410   [ #  #  #  # ]:          0 :         if (mtu < RTE_ETHER_MIN_MTU || mtu > priv->max_mtu) {
     411                 :          0 :                 PMD_DRV_LOG(ERR, "MIN MTU is %u, MAX MTU is %u",
     412                 :            :                             RTE_ETHER_MIN_MTU, priv->max_mtu);
     413                 :          0 :                 return -EINVAL;
     414                 :            :         }
     415                 :            : 
     416                 :            :         /* mtu setting is forbidden if port is start */
     417         [ #  # ]:          0 :         if (dev->data->dev_started) {
     418                 :          0 :                 PMD_DRV_LOG(ERR, "Port must be stopped before configuration");
     419                 :          0 :                 return -EBUSY;
     420                 :            :         }
     421                 :            : 
     422                 :          0 :         err = gve_adminq_set_mtu(priv, mtu);
     423         [ #  # ]:          0 :         if (err) {
     424                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to set mtu as %u err = %d", mtu, err);
     425                 :          0 :                 return err;
     426                 :            :         }
     427                 :            : 
     428                 :            :         return 0;
     429                 :            : }
     430                 :            : 
     431                 :            : #define TX_QUEUE_STATS_OFFSET(x) offsetof(struct gve_tx_stats, x)
     432                 :            : #define RX_QUEUE_STATS_OFFSET(x) offsetof(struct gve_rx_stats, x)
     433                 :            : 
     434                 :            : static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
     435                 :            :         { "packets", TX_QUEUE_STATS_OFFSET(packets) },
     436                 :            :         { "bytes",   TX_QUEUE_STATS_OFFSET(bytes) },
     437                 :            :         { "errors",  TX_QUEUE_STATS_OFFSET(errors) },
     438                 :            : };
     439                 :            : 
     440                 :            : static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
     441                 :            :         { "packets",                RX_QUEUE_STATS_OFFSET(packets) },
     442                 :            :         { "bytes",                  RX_QUEUE_STATS_OFFSET(bytes) },
     443                 :            :         { "errors",                 RX_QUEUE_STATS_OFFSET(errors) },
     444                 :            :         { "mbuf_alloc_errors",      RX_QUEUE_STATS_OFFSET(no_mbufs) },
     445                 :            :         { "mbuf_alloc_errors_bulk", RX_QUEUE_STATS_OFFSET(no_mbufs_bulk) },
     446                 :            : };
     447                 :            : 
     448                 :            : static int
     449                 :          0 : gve_xstats_count(struct rte_eth_dev *dev)
     450                 :            : {
     451                 :            :         uint16_t i, count = 0;
     452                 :            : 
     453         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     454         [ #  # ]:          0 :                 if (dev->data->tx_queues[i])
     455                 :          0 :                         count += RTE_DIM(tx_xstats_name_offset);
     456                 :            :         }
     457                 :            : 
     458         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     459         [ #  # ]:          0 :                 if (dev->data->rx_queues[i])
     460                 :          0 :                         count += RTE_DIM(rx_xstats_name_offset);
     461                 :            :         }
     462                 :            : 
     463                 :          0 :         return count;
     464                 :            : }
     465                 :            : 
     466                 :            : static int
     467                 :          0 : gve_xstats_get(struct rte_eth_dev *dev,
     468                 :            :                         struct rte_eth_xstat *xstats,
     469                 :            :                         unsigned int size)
     470                 :            : {
     471                 :          0 :         uint16_t i, j, count = gve_xstats_count(dev);
     472                 :            :         const char *stats;
     473                 :            : 
     474   [ #  #  #  # ]:          0 :         if (xstats == NULL || size < count)
     475                 :          0 :                 return count;
     476                 :            : 
     477                 :            :         count = 0;
     478                 :            : 
     479         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     480                 :          0 :                 const struct gve_tx_queue *txq = dev->data->tx_queues[i];
     481         [ #  # ]:          0 :                 if (txq == NULL)
     482                 :          0 :                         continue;
     483                 :            : 
     484                 :          0 :                 stats = (const char *)&txq->stats;
     485         [ #  # ]:          0 :                 for (j = 0; j < RTE_DIM(tx_xstats_name_offset); j++, count++) {
     486                 :          0 :                         xstats[count].id = count;
     487                 :          0 :                         xstats[count].value = *(const uint64_t *)
     488                 :          0 :                                 (stats + tx_xstats_name_offset[j].offset);
     489                 :            :                 }
     490                 :            :         }
     491                 :            : 
     492         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     493                 :          0 :                 const struct gve_rx_queue *rxq = dev->data->rx_queues[i];
     494         [ #  # ]:          0 :                 if (rxq == NULL)
     495                 :          0 :                         continue;
     496                 :            : 
     497                 :          0 :                 stats = (const char *)&rxq->stats;
     498         [ #  # ]:          0 :                 for (j = 0; j < RTE_DIM(rx_xstats_name_offset); j++, count++) {
     499                 :          0 :                         xstats[count].id = count;
     500                 :          0 :                         xstats[count].value = *(const uint64_t *)
     501                 :          0 :                                 (stats + rx_xstats_name_offset[j].offset);
     502                 :            :                 }
     503                 :            :         }
     504                 :            : 
     505                 :          0 :         return count;
     506                 :            : }
     507                 :            : 
     508                 :            : static int
     509                 :          0 : gve_xstats_get_names(struct rte_eth_dev *dev,
     510                 :            :                         struct rte_eth_xstat_name *xstats_names,
     511                 :            :                         unsigned int size)
     512                 :            : {
     513                 :          0 :         uint16_t i, j, count = gve_xstats_count(dev);
     514                 :            : 
     515   [ #  #  #  # ]:          0 :         if (xstats_names == NULL || size < count)
     516                 :          0 :                 return count;
     517                 :            : 
     518                 :            :         count = 0;
     519                 :            : 
     520         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     521         [ #  # ]:          0 :                 if (dev->data->tx_queues[i] == NULL)
     522                 :          0 :                         continue;
     523                 :            : 
     524         [ #  # ]:          0 :                 for (j = 0; j < RTE_DIM(tx_xstats_name_offset); j++)
     525                 :          0 :                         snprintf(xstats_names[count++].name,
     526                 :            :                                  RTE_ETH_XSTATS_NAME_SIZE,
     527                 :          0 :                                  "tx_q%u_%s", i, tx_xstats_name_offset[j].name);
     528                 :            :         }
     529                 :            : 
     530         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     531         [ #  # ]:          0 :                 if (dev->data->rx_queues[i] == NULL)
     532                 :          0 :                         continue;
     533                 :            : 
     534         [ #  # ]:          0 :                 for (j = 0; j < RTE_DIM(rx_xstats_name_offset); j++)
     535                 :          0 :                         snprintf(xstats_names[count++].name,
     536                 :            :                                  RTE_ETH_XSTATS_NAME_SIZE,
     537                 :          0 :                                  "rx_q%u_%s", i, rx_xstats_name_offset[j].name);
     538                 :            :         }
     539                 :            : 
     540                 :          0 :         return count;
     541                 :            : }
     542                 :            : 
     543                 :            : static const struct eth_dev_ops gve_eth_dev_ops = {
     544                 :            :         .dev_configure        = gve_dev_configure,
     545                 :            :         .dev_start            = gve_dev_start,
     546                 :            :         .dev_stop             = gve_dev_stop,
     547                 :            :         .dev_close            = gve_dev_close,
     548                 :            :         .dev_infos_get        = gve_dev_info_get,
     549                 :            :         .rx_queue_setup       = gve_rx_queue_setup,
     550                 :            :         .tx_queue_setup       = gve_tx_queue_setup,
     551                 :            :         .rx_queue_release     = gve_rx_queue_release,
     552                 :            :         .tx_queue_release     = gve_tx_queue_release,
     553                 :            :         .rx_queue_start       = gve_rx_queue_start,
     554                 :            :         .tx_queue_start       = gve_tx_queue_start,
     555                 :            :         .rx_queue_stop        = gve_rx_queue_stop,
     556                 :            :         .tx_queue_stop        = gve_tx_queue_stop,
     557                 :            :         .link_update          = gve_link_update,
     558                 :            :         .stats_get            = gve_dev_stats_get,
     559                 :            :         .stats_reset          = gve_dev_stats_reset,
     560                 :            :         .mtu_set              = gve_dev_mtu_set,
     561                 :            :         .xstats_get           = gve_xstats_get,
     562                 :            :         .xstats_get_names     = gve_xstats_get_names,
     563                 :            : };
     564                 :            : 
     565                 :            : static const struct eth_dev_ops gve_eth_dev_ops_dqo = {
     566                 :            :         .dev_configure        = gve_dev_configure,
     567                 :            :         .dev_start            = gve_dev_start,
     568                 :            :         .dev_stop             = gve_dev_stop,
     569                 :            :         .dev_close            = gve_dev_close,
     570                 :            :         .dev_infos_get        = gve_dev_info_get,
     571                 :            :         .rx_queue_setup       = gve_rx_queue_setup_dqo,
     572                 :            :         .tx_queue_setup       = gve_tx_queue_setup_dqo,
     573                 :            :         .rx_queue_release     = gve_rx_queue_release_dqo,
     574                 :            :         .tx_queue_release     = gve_tx_queue_release_dqo,
     575                 :            :         .rx_queue_start       = gve_rx_queue_start_dqo,
     576                 :            :         .tx_queue_start       = gve_tx_queue_start_dqo,
     577                 :            :         .rx_queue_stop        = gve_rx_queue_stop_dqo,
     578                 :            :         .tx_queue_stop        = gve_tx_queue_stop_dqo,
     579                 :            :         .link_update          = gve_link_update,
     580                 :            :         .stats_get            = gve_dev_stats_get,
     581                 :            :         .stats_reset          = gve_dev_stats_reset,
     582                 :            :         .mtu_set              = gve_dev_mtu_set,
     583                 :            :         .xstats_get           = gve_xstats_get,
     584                 :            :         .xstats_get_names     = gve_xstats_get_names,
     585                 :            : };
     586                 :            : 
     587                 :            : static void
     588                 :            : gve_free_counter_array(struct gve_priv *priv)
     589                 :            : {
     590                 :          0 :         rte_memzone_free(priv->cnt_array_mz);
     591                 :          0 :         priv->cnt_array = NULL;
     592                 :            : }
     593                 :            : 
     594                 :            : static void
     595                 :            : gve_free_irq_db(struct gve_priv *priv)
     596                 :            : {
     597                 :          0 :         rte_memzone_free(priv->irq_dbs_mz);
     598                 :          0 :         priv->irq_dbs = NULL;
     599                 :          0 : }
     600                 :            : 
     601                 :            : static void
     602         [ #  # ]:          0 : gve_teardown_device_resources(struct gve_priv *priv)
     603                 :            : {
     604                 :            :         int err;
     605                 :            : 
     606                 :            :         /* Tell device its resources are being freed */
     607         [ #  # ]:          0 :         if (gve_get_device_resources_ok(priv)) {
     608                 :          0 :                 err = gve_adminq_deconfigure_device_resources(priv);
     609         [ #  # ]:          0 :                 if (err)
     610                 :          0 :                         PMD_DRV_LOG(ERR, "Could not deconfigure device resources: err=%d", err);
     611                 :            :         }
     612                 :            :         gve_free_counter_array(priv);
     613                 :            :         gve_free_irq_db(priv);
     614                 :            :         gve_clear_device_resources_ok(priv);
     615                 :          0 : }
     616                 :            : 
     617                 :            : static int
     618                 :          0 : pci_dev_msix_vec_count(struct rte_pci_device *pdev)
     619                 :            : {
     620                 :          0 :         off_t msix_pos = rte_pci_find_capability(pdev, RTE_PCI_CAP_ID_MSIX);
     621                 :            :         uint16_t control;
     622                 :            : 
     623   [ #  #  #  # ]:          0 :         if (msix_pos > 0 && rte_pci_read_config(pdev, &control, sizeof(control),
     624                 :            :                         msix_pos + RTE_PCI_MSIX_FLAGS) == sizeof(control))
     625                 :          0 :                 return (control & RTE_PCI_MSIX_FLAGS_QSIZE) + 1;
     626                 :            : 
     627                 :            :         return 0;
     628                 :            : }
     629                 :            : 
     630                 :            : static int
     631                 :          0 : gve_setup_device_resources(struct gve_priv *priv)
     632                 :            : {
     633                 :            :         char z_name[RTE_MEMZONE_NAMESIZE];
     634                 :            :         const struct rte_memzone *mz;
     635                 :            :         int err = 0;
     636                 :            : 
     637                 :          0 :         snprintf(z_name, sizeof(z_name), "gve_%s_cnt_arr", priv->pci_dev->device.name);
     638                 :          0 :         mz = rte_memzone_reserve_aligned(z_name,
     639                 :          0 :                                          priv->num_event_counters * sizeof(*priv->cnt_array),
     640                 :          0 :                                          rte_socket_id(), RTE_MEMZONE_IOVA_CONTIG,
     641                 :            :                                          PAGE_SIZE);
     642         [ #  # ]:          0 :         if (mz == NULL) {
     643                 :          0 :                 PMD_DRV_LOG(ERR, "Could not alloc memzone for count array");
     644                 :          0 :                 return -ENOMEM;
     645                 :            :         }
     646                 :          0 :         priv->cnt_array = (rte_be32_t *)mz->addr;
     647                 :          0 :         priv->cnt_array_mz = mz;
     648                 :            : 
     649                 :          0 :         snprintf(z_name, sizeof(z_name), "gve_%s_irqmz", priv->pci_dev->device.name);
     650                 :          0 :         mz = rte_memzone_reserve_aligned(z_name,
     651                 :          0 :                                          sizeof(*priv->irq_dbs) * (priv->num_ntfy_blks),
     652                 :          0 :                                          rte_socket_id(), RTE_MEMZONE_IOVA_CONTIG,
     653                 :            :                                          PAGE_SIZE);
     654         [ #  # ]:          0 :         if (mz == NULL) {
     655                 :          0 :                 PMD_DRV_LOG(ERR, "Could not alloc memzone for irq_dbs");
     656                 :            :                 err = -ENOMEM;
     657                 :          0 :                 goto free_cnt_array;
     658                 :            :         }
     659                 :          0 :         priv->irq_dbs = (struct gve_irq_db *)mz->addr;
     660                 :          0 :         priv->irq_dbs_mz = mz;
     661                 :            : 
     662                 :          0 :         err = gve_adminq_configure_device_resources(priv,
     663                 :          0 :                                                     priv->cnt_array_mz->iova,
     664                 :          0 :                                                     priv->num_event_counters,
     665                 :          0 :                                                     priv->irq_dbs_mz->iova,
     666                 :            :                                                     priv->num_ntfy_blks);
     667         [ #  # ]:          0 :         if (unlikely(err)) {
     668                 :          0 :                 PMD_DRV_LOG(ERR, "Could not config device resources: err=%d", err);
     669                 :          0 :                 goto free_irq_dbs;
     670                 :            :         }
     671                 :            :         return 0;
     672                 :            : 
     673                 :            : free_irq_dbs:
     674                 :            :         gve_free_irq_db(priv);
     675                 :          0 : free_cnt_array:
     676                 :            :         gve_free_counter_array(priv);
     677                 :            : 
     678                 :          0 :         return err;
     679                 :            : }
     680                 :            : 
     681                 :            : static int
     682                 :          0 : gve_init_priv(struct gve_priv *priv, bool skip_describe_device)
     683                 :            : {
     684                 :            :         uint16_t pages;
     685                 :            :         int num_ntfy;
     686                 :            :         uint32_t i;
     687                 :            :         int err;
     688                 :            : 
     689                 :            :         /* Set up the adminq */
     690                 :          0 :         err = gve_adminq_alloc(priv);
     691         [ #  # ]:          0 :         if (err) {
     692                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc admin queue: err=%d", err);
     693                 :          0 :                 return err;
     694                 :            :         }
     695                 :          0 :         err = gve_verify_driver_compatibility(priv);
     696         [ #  # ]:          0 :         if (err) {
     697                 :          0 :                 PMD_DRV_LOG(ERR, "Could not verify driver compatibility: err=%d", err);
     698                 :          0 :                 goto free_adminq;
     699                 :            :         }
     700                 :            : 
     701         [ #  # ]:          0 :         if (skip_describe_device)
     702                 :          0 :                 goto setup_device;
     703                 :            : 
     704                 :            :         /* Get the initial information we need from the device */
     705                 :          0 :         err = gve_adminq_describe_device(priv);
     706         [ #  # ]:          0 :         if (err) {
     707                 :          0 :                 PMD_DRV_LOG(ERR, "Could not get device information: err=%d", err);
     708                 :          0 :                 goto free_adminq;
     709                 :            :         }
     710                 :            : 
     711                 :          0 :         num_ntfy = pci_dev_msix_vec_count(priv->pci_dev);
     712         [ #  # ]:          0 :         if (num_ntfy <= 0) {
     713                 :          0 :                 PMD_DRV_LOG(ERR, "Could not count MSI-x vectors");
     714                 :            :                 err = -EIO;
     715                 :          0 :                 goto free_adminq;
     716         [ #  # ]:          0 :         } else if (num_ntfy < GVE_MIN_MSIX) {
     717                 :          0 :                 PMD_DRV_LOG(ERR, "GVE needs at least %d MSI-x vectors, but only has %d",
     718                 :            :                             GVE_MIN_MSIX, num_ntfy);
     719                 :            :                 err = -EINVAL;
     720                 :          0 :                 goto free_adminq;
     721                 :            :         }
     722                 :            : 
     723                 :          0 :         priv->num_registered_pages = 0;
     724                 :            : 
     725                 :            :         /* gvnic has one Notification Block per MSI-x vector, except for the
     726                 :            :          * management vector
     727                 :            :          */
     728                 :          0 :         priv->num_ntfy_blks = (num_ntfy - 1) & ~0x1;
     729                 :          0 :         priv->mgmt_msix_idx = priv->num_ntfy_blks;
     730                 :            : 
     731                 :          0 :         priv->max_nb_txq = RTE_MIN(priv->max_nb_txq, priv->num_ntfy_blks / 2);
     732                 :          0 :         priv->max_nb_rxq = RTE_MIN(priv->max_nb_rxq, priv->num_ntfy_blks / 2);
     733                 :            : 
     734         [ #  # ]:          0 :         if (priv->default_num_queues > 0) {
     735                 :          0 :                 priv->max_nb_txq = RTE_MIN(priv->default_num_queues, priv->max_nb_txq);
     736                 :          0 :                 priv->max_nb_rxq = RTE_MIN(priv->default_num_queues, priv->max_nb_rxq);
     737                 :            :         }
     738                 :            : 
     739                 :          0 :         PMD_DRV_LOG(INFO, "Max TX queues %d, Max RX queues %d",
     740                 :            :                     priv->max_nb_txq, priv->max_nb_rxq);
     741                 :            : 
     742                 :            :         /* In GQI_QPL queue format:
     743                 :            :          * Allocate queue page lists according to max queue number
     744                 :            :          * tx qpl id should start from 0 while rx qpl id should start
     745                 :            :          * from priv->max_nb_txq
     746                 :            :          */
     747         [ #  # ]:          0 :         if (priv->queue_format == GVE_GQI_QPL_FORMAT) {
     748                 :          0 :                 priv->qpl = rte_zmalloc("gve_qpl",
     749                 :          0 :                                         (priv->max_nb_txq + priv->max_nb_rxq) *
     750                 :            :                                         sizeof(struct gve_queue_page_list), 0);
     751         [ #  # ]:          0 :                 if (priv->qpl == NULL) {
     752                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to alloc qpl.");
     753                 :            :                         err = -ENOMEM;
     754                 :          0 :                         goto free_adminq;
     755                 :            :                 }
     756                 :            : 
     757         [ #  # ]:          0 :                 for (i = 0; i < priv->max_nb_txq + priv->max_nb_rxq; i++) {
     758         [ #  # ]:          0 :                         if (i < priv->max_nb_txq)
     759                 :          0 :                                 pages = priv->tx_pages_per_qpl;
     760                 :            :                         else
     761                 :          0 :                                 pages = priv->rx_data_slot_cnt;
     762                 :          0 :                         err = gve_alloc_queue_page_list(priv, i, pages);
     763         [ #  # ]:          0 :                         if (err != 0) {
     764                 :          0 :                                 PMD_DRV_LOG(ERR, "Failed to alloc qpl %u.", i);
     765                 :          0 :                                 goto err_qpl;
     766                 :            :                         }
     767                 :            :                 }
     768                 :            :         }
     769                 :            : 
     770                 :          0 : setup_device:
     771                 :          0 :         err = gve_setup_device_resources(priv);
     772         [ #  # ]:          0 :         if (!err)
     773                 :            :                 return 0;
     774                 :          0 : err_qpl:
     775                 :          0 :         gve_free_qpls(priv);
     776                 :          0 : free_adminq:
     777                 :          0 :         gve_adminq_free(priv);
     778                 :          0 :         return err;
     779                 :            : }
     780                 :            : 
     781                 :            : static void
     782                 :            : gve_teardown_priv_resources(struct gve_priv *priv)
     783                 :            : {
     784                 :          0 :         gve_teardown_device_resources(priv);
     785                 :          0 :         gve_adminq_free(priv);
     786                 :            : }
     787                 :            : 
     788                 :            : static int
     789                 :          0 : gve_dev_init(struct rte_eth_dev *eth_dev)
     790                 :            : {
     791                 :          0 :         struct gve_priv *priv = eth_dev->data->dev_private;
     792                 :            :         int max_tx_queues, max_rx_queues;
     793                 :            :         struct rte_pci_device *pci_dev;
     794                 :            :         struct gve_registers *reg_bar;
     795                 :            :         rte_be32_t *db_bar;
     796                 :            :         int err;
     797                 :            : 
     798         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     799                 :            :                 return 0;
     800                 :            : 
     801                 :          0 :         pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
     802                 :            : 
     803                 :          0 :         reg_bar = pci_dev->mem_resource[GVE_REG_BAR].addr;
     804         [ #  # ]:          0 :         if (!reg_bar) {
     805                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to map pci bar!");
     806                 :          0 :                 return -ENOMEM;
     807                 :            :         }
     808                 :            : 
     809                 :          0 :         db_bar = pci_dev->mem_resource[GVE_DB_BAR].addr;
     810         [ #  # ]:          0 :         if (!db_bar) {
     811                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to map doorbell bar!");
     812                 :          0 :                 return -ENOMEM;
     813                 :            :         }
     814                 :            : 
     815                 :            :         gve_write_version(&reg_bar->driver_version);
     816                 :            :         /* Get max queues to alloc etherdev */
     817                 :            :         max_tx_queues = ioread32be(&reg_bar->max_tx_queues);
     818                 :            :         max_rx_queues = ioread32be(&reg_bar->max_rx_queues);
     819                 :            : 
     820                 :          0 :         priv->reg_bar0 = reg_bar;
     821                 :          0 :         priv->db_bar2 = db_bar;
     822                 :          0 :         priv->pci_dev = pci_dev;
     823                 :          0 :         priv->state_flags = 0x0;
     824                 :            : 
     825                 :          0 :         priv->max_nb_txq = max_tx_queues;
     826                 :          0 :         priv->max_nb_rxq = max_rx_queues;
     827                 :            : 
     828                 :          0 :         err = gve_init_priv(priv, false);
     829         [ #  # ]:          0 :         if (err)
     830                 :            :                 return err;
     831                 :            : 
     832         [ #  # ]:          0 :         if (gve_is_gqi(priv)) {
     833                 :          0 :                 eth_dev->dev_ops = &gve_eth_dev_ops;
     834                 :          0 :                 gve_set_rx_function(eth_dev);
     835                 :          0 :                 gve_set_tx_function(eth_dev);
     836                 :            :         } else {
     837                 :          0 :                 eth_dev->dev_ops = &gve_eth_dev_ops_dqo;
     838                 :          0 :                 gve_set_rx_function_dqo(eth_dev);
     839                 :          0 :                 gve_set_tx_function_dqo(eth_dev);
     840                 :            :         }
     841                 :            : 
     842                 :          0 :         eth_dev->data->mac_addrs = &priv->dev_addr;
     843                 :            : 
     844                 :          0 :         return 0;
     845                 :            : }
     846                 :            : 
     847                 :            : static int
     848                 :          0 : gve_dev_uninit(struct rte_eth_dev *eth_dev)
     849                 :            : {
     850                 :          0 :         struct gve_priv *priv = eth_dev->data->dev_private;
     851                 :            : 
     852                 :            :         gve_teardown_priv_resources(priv);
     853                 :            : 
     854                 :          0 :         eth_dev->data->mac_addrs = NULL;
     855                 :            : 
     856                 :          0 :         return 0;
     857                 :            : }
     858                 :            : 
     859                 :            : static int
     860                 :          0 : gve_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
     861                 :            :               struct rte_pci_device *pci_dev)
     862                 :            : {
     863                 :          0 :         return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct gve_priv), gve_dev_init);
     864                 :            : }
     865                 :            : 
     866                 :            : static int
     867                 :          0 : gve_pci_remove(struct rte_pci_device *pci_dev)
     868                 :            : {
     869                 :          0 :         return rte_eth_dev_pci_generic_remove(pci_dev, gve_dev_uninit);
     870                 :            : }
     871                 :            : 
     872                 :            : static const struct rte_pci_id pci_id_gve_map[] = {
     873                 :            :         { RTE_PCI_DEVICE(GOOGLE_VENDOR_ID, GVE_DEV_ID) },
     874                 :            :         { .device_id = 0 },
     875                 :            : };
     876                 :            : 
     877                 :            : static struct rte_pci_driver rte_gve_pmd = {
     878                 :            :         .id_table = pci_id_gve_map,
     879                 :            :         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
     880                 :            :         .probe = gve_pci_probe,
     881                 :            :         .remove = gve_pci_remove,
     882                 :            : };
     883                 :            : 
     884                 :        235 : RTE_PMD_REGISTER_PCI(net_gve, rte_gve_pmd);
     885                 :            : RTE_PMD_REGISTER_PCI_TABLE(net_gve, pci_id_gve_map);
     886                 :            : RTE_PMD_REGISTER_KMOD_DEP(net_gve, "* igb_uio | vfio-pci");
     887         [ -  + ]:        235 : RTE_LOG_REGISTER_SUFFIX(gve_logtype_driver, driver, NOTICE);

Generated by: LCOV version 1.14