LCOV - code coverage report
Current view: top level - drivers/common/mlx5 - mlx5_common_pci.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 49 82 59.8 %
Date: 2025-03-01 20:23:48 Functions: 5 12 41.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 32 66 48.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2020 Mellanox Technologies Ltd
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdlib.h>
       6                 :            : 
       7                 :            : #include <rte_malloc.h>
       8                 :            : #include <rte_devargs.h>
       9                 :            : #include <rte_errno.h>
      10                 :            : #include <rte_class.h>
      11                 :            : #include <rte_pci.h>
      12                 :            : #include <bus_driver.h>
      13                 :            : #include <bus_pci_driver.h>
      14                 :            : 
      15                 :            : #include "mlx5_common_log.h"
      16                 :            : #include "mlx5_common_private.h"
      17                 :            : 
      18                 :            : static struct rte_pci_driver mlx5_common_pci_driver;
      19                 :            : 
      20                 :            : /* PCI ID table is build dynamically based on registered mlx5 drivers. */
      21                 :            : static struct rte_pci_id *mlx5_pci_id_table;
      22                 :            : 
      23                 :            : static int
      24                 :            : pci_id_table_size_get(const struct rte_pci_id *id_table)
      25                 :            : {
      26                 :            :         int table_size = 0;
      27                 :            : 
      28   [ +  +  +  + ]:      29736 :         for (; id_table->vendor_id != 0; id_table++)
      29                 :      28224 :                 table_size++;
      30                 :            :         return table_size;
      31                 :            : }
      32                 :            : 
      33                 :            : static bool
      34                 :            : pci_id_exists(const struct rte_pci_id *id, const struct rte_pci_id *table,
      35                 :            :               int next_idx)
      36                 :            : {
      37                 :       9324 :         int current_size = next_idx - 1;
      38                 :            :         int i;
      39                 :            : 
      40         [ +  + ]:     110376 :         for (i = 0; i < current_size; i++) {
      41         [ +  + ]:     105588 :                 if (id->device_id == table[i].device_id &&
      42                 :            :                     id->vendor_id == table[i].vendor_id &&
      43         [ -  + ]:       4536 :                     id->subsystem_vendor_id == table[i].subsystem_vendor_id &&
      44                 :            :                     id->subsystem_device_id == table[i].subsystem_device_id)
      45                 :            :                         return true;
      46                 :            :         }
      47                 :            :         return false;
      48                 :            : }
      49                 :            : 
      50                 :            : static void
      51                 :       1260 : pci_id_insert(struct rte_pci_id *new_table, int *next_idx,
      52                 :            :               const struct rte_pci_id *id_table)
      53                 :            : {
      54                 :            :         /* Traverse the id_table, check if entry exists in new_table;
      55                 :            :          * Add non duplicate entries to new table.
      56                 :            :          */
      57         [ +  + ]:      10584 :         for (; id_table->vendor_id != 0; id_table++) {
      58         [ +  + ]:      18648 :                 if (!pci_id_exists(id_table, new_table, *next_idx)) {
      59                 :            :                         /* New entry; add to the table. */
      60                 :       4788 :                         new_table[*next_idx] = *id_table;
      61                 :       4788 :                         (*next_idx)++;
      62                 :            :                 }
      63                 :            :         }
      64                 :       1260 : }
      65                 :            : 
      66                 :            : static int
      67                 :       1512 : pci_ids_table_update(const struct rte_pci_id *driver_id_table)
      68                 :            : {
      69                 :            :         const struct rte_pci_id *id_iter;
      70                 :            :         struct rte_pci_id *updated_table;
      71                 :            :         struct rte_pci_id *old_table;
      72                 :            :         int num_ids = 0;
      73                 :       1512 :         int i = 0;
      74                 :            : 
      75                 :       1512 :         old_table = mlx5_pci_id_table;
      76         [ +  + ]:       1512 :         if (old_table)
      77                 :            :                 num_ids = pci_id_table_size_get(old_table);
      78                 :       1512 :         num_ids += pci_id_table_size_get(driver_id_table);
      79                 :            :         /* Increase size by one for the termination entry of vendor_id = 0. */
      80                 :       1512 :         num_ids += 1;
      81                 :       1512 :         updated_table = calloc(num_ids, sizeof(*updated_table));
      82         [ +  - ]:       1512 :         if (!updated_table)
      83                 :            :                 return -ENOMEM;
      84         [ +  + ]:       1512 :         if (old_table == NULL) {
      85                 :            :                 /* Copy the first driver's ID table. */
      86         [ -  + ]:        252 :                 for (id_iter = driver_id_table; id_iter->vendor_id != 0;
      87                 :          0 :                      id_iter++, i++)
      88                 :          0 :                         updated_table[i] = *id_iter;
      89                 :            :         } else {
      90                 :            :                 /* First copy existing table entries. */
      91         [ +  + ]:      20160 :                 for (id_iter = old_table; id_iter->vendor_id != 0;
      92                 :      18900 :                      id_iter++, i++)
      93                 :      18900 :                         updated_table[i] = *id_iter;
      94                 :            :                 /* New id to be added at the end of current ID table. */
      95                 :       1260 :                 pci_id_insert(updated_table, &i, driver_id_table);
      96                 :            :         }
      97                 :            :         /* Terminate table with empty entry. */
      98                 :       1512 :         updated_table[i].vendor_id = 0;
      99                 :       1512 :         mlx5_common_pci_driver.id_table = updated_table;
     100                 :       1512 :         mlx5_pci_id_table = updated_table;
     101                 :       1512 :         free(old_table);
     102                 :       1512 :         return 0;
     103                 :            : }
     104                 :            : 
     105                 :            : bool
     106                 :          0 : mlx5_dev_is_pci(const struct rte_device *dev)
     107                 :            : {
     108                 :          0 :         return strcmp(dev->bus->name, "pci") == 0;
     109                 :            : }
     110                 :            : 
     111                 :            : bool
     112                 :          0 : mlx5_dev_is_vf_pci(const struct rte_pci_device *pci_dev)
     113                 :            : {
     114         [ #  # ]:          0 :         switch (pci_dev->id.device_id) {
     115                 :            :         case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
     116                 :            :         case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
     117                 :            :         case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
     118                 :            :         case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
     119                 :            :         case PCI_DEVICE_ID_MELLANOX_BLUEFIELDVF:
     120                 :            :         case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
     121                 :            :         case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
     122                 :            :                 return true;
     123                 :            :         default:
     124                 :            :                 break;
     125                 :            :         }
     126                 :          0 :         return false;
     127                 :            : }
     128                 :            : 
     129                 :            : bool
     130                 :          0 : mlx5_dev_pci_match(const struct mlx5_class_driver *drv,
     131                 :            :                    const struct rte_device *dev)
     132                 :            : {
     133                 :            :         const struct rte_pci_device *pci_dev;
     134                 :            :         const struct rte_pci_id *id_table;
     135                 :            : 
     136         [ #  # ]:          0 :         if (!mlx5_dev_is_pci(dev))
     137                 :            :                 return false;
     138                 :          0 :         pci_dev = RTE_DEV_TO_PCI_CONST(dev);
     139         [ #  # ]:          0 :         for (id_table = drv->id_table; id_table->vendor_id != 0;
     140                 :          0 :              id_table++) {
     141                 :            :                 /* Check if device's ids match the class driver's ids. */
     142   [ #  #  #  # ]:          0 :                 if (id_table->vendor_id != pci_dev->id.vendor_id &&
     143                 :            :                     id_table->vendor_id != RTE_PCI_ANY_ID)
     144                 :          0 :                         continue;
     145   [ #  #  #  # ]:          0 :                 if (id_table->device_id != pci_dev->id.device_id &&
     146                 :            :                     id_table->device_id != RTE_PCI_ANY_ID)
     147                 :          0 :                         continue;
     148                 :          0 :                 if (id_table->subsystem_vendor_id !=
     149   [ #  #  #  # ]:          0 :                     pci_dev->id.subsystem_vendor_id &&
     150                 :            :                     id_table->subsystem_vendor_id != RTE_PCI_ANY_ID)
     151                 :          0 :                         continue;
     152                 :          0 :                 if (id_table->subsystem_device_id !=
     153   [ #  #  #  # ]:          0 :                     pci_dev->id.subsystem_device_id &&
     154                 :            :                     id_table->subsystem_device_id != RTE_PCI_ANY_ID)
     155                 :          0 :                         continue;
     156   [ #  #  #  # ]:          0 :                 if (id_table->class_id != pci_dev->id.class_id &&
     157                 :            :                     id_table->class_id != RTE_CLASS_ANY_ID)
     158                 :          0 :                         continue;
     159                 :            :                 return true;
     160                 :            :         }
     161                 :            :         return false;
     162                 :            : }
     163                 :            : 
     164                 :            : static int
     165                 :          0 : mlx5_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
     166                 :            :                       struct rte_pci_device *pci_dev)
     167                 :            : {
     168                 :          0 :         return mlx5_common_dev_probe(&pci_dev->device);
     169                 :            : }
     170                 :            : 
     171                 :            : static int
     172                 :          0 : mlx5_common_pci_remove(struct rte_pci_device *pci_dev)
     173                 :            : {
     174                 :          0 :         return mlx5_common_dev_remove(&pci_dev->device);
     175                 :            : }
     176                 :            : 
     177                 :            : static int
     178                 :          0 : mlx5_common_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,
     179                 :            :                         uint64_t iova, size_t len)
     180                 :            : {
     181                 :          0 :         return mlx5_common_dev_dma_map(&pci_dev->device, addr, iova, len);
     182                 :            : }
     183                 :            : 
     184                 :            : static int
     185                 :          0 : mlx5_common_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,
     186                 :            :                           uint64_t iova, size_t len)
     187                 :            : {
     188                 :          0 :         return mlx5_common_dev_dma_unmap(&pci_dev->device, addr, iova, len);
     189                 :            : }
     190                 :            : 
     191                 :            : void
     192                 :       1260 : mlx5_common_driver_on_register_pci(struct mlx5_class_driver *driver)
     193                 :            : {
     194         [ +  - ]:       1260 :         if (driver->id_table != NULL) {
     195         [ +  - ]:       1260 :                 if (pci_ids_table_update(driver->id_table) != 0)
     196                 :            :                         return;
     197                 :            :         }
     198         [ +  + ]:       1260 :         if (driver->probe_again)
     199                 :        252 :                 mlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_PROBE_AGAIN;
     200         [ +  + ]:       1260 :         if (driver->intr_lsc)
     201                 :        252 :                 mlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_INTR_LSC;
     202         [ +  + ]:       1260 :         if (driver->intr_rmv)
     203                 :        252 :                 mlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_INTR_RMV;
     204                 :            : }
     205                 :            : 
     206                 :            : static struct rte_pci_driver mlx5_common_pci_driver = {
     207                 :            :         .driver = {
     208                 :            :                    .name = MLX5_PCI_DRIVER_NAME,
     209                 :            :         },
     210                 :            :         .probe = mlx5_common_pci_probe,
     211                 :            :         .remove = mlx5_common_pci_remove,
     212                 :            :         .dma_map = mlx5_common_pci_dma_map,
     213                 :            :         .dma_unmap = mlx5_common_pci_dma_unmap,
     214                 :            : };
     215                 :            : 
     216                 :        252 : void mlx5_common_pci_init(void)
     217                 :            : {
     218                 :        252 :         const struct rte_pci_id empty_table[] = {
     219                 :            :                 {
     220                 :            :                         .vendor_id = 0
     221                 :            :                 },
     222                 :            :         };
     223                 :            : 
     224                 :            :         /* All mlx5 PMDs constructor runs at same priority. So any of the PMD
     225                 :            :          * including this one can register the PCI table first. If any other
     226                 :            :          * PMD(s) have registered the PCI ID table, No need to register an empty
     227                 :            :          * default one.
     228                 :            :          */
     229   [ +  -  -  + ]:        252 :         if (mlx5_pci_id_table == NULL && pci_ids_table_update(empty_table))
     230                 :          0 :                 return;
     231                 :        252 :         rte_pci_register(&mlx5_common_pci_driver);
     232                 :            : }
     233                 :            : 
     234                 :        252 : RTE_FINI(mlx5_common_pci_finish)
     235                 :            : {
     236         [ +  - ]:        252 :         if (mlx5_pci_id_table != NULL) {
     237                 :            :                 /* Constructor doesn't register with PCI bus if it failed
     238                 :            :                  * to build the table.
     239                 :            :                  */
     240                 :        252 :                 rte_pci_unregister(&mlx5_common_pci_driver);
     241                 :        252 :                 free(mlx5_pci_id_table);
     242                 :            :         }
     243                 :        252 : }
     244                 :            : 
     245                 :            : RTE_PMD_EXPORT_NAME(mlx5_common_pci, __COUNTER__);

Generated by: LCOV version 1.14