LCOV - code coverage report
Current view: top level - drivers/raw/cnxk_bphy - cnxk_bphy.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 2 167 1.2 %
Date: 2025-02-01 18:54:23 Functions: 2 13 15.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 88 1.1 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : #include <bus_pci_driver.h>
       5                 :            : #include <rte_common.h>
       6                 :            : #include <dev_driver.h>
       7                 :            : #include <rte_eal.h>
       8                 :            : #include <rte_lcore.h>
       9                 :            : #include <rte_pci.h>
      10                 :            : #include <rte_rawdev.h>
      11                 :            : #include <rte_rawdev_pmd.h>
      12                 :            : 
      13                 :            : #include <roc_api.h>
      14                 :            : 
      15                 :            : #include "cnxk_bphy_irq.h"
      16                 :            : #include "rte_pmd_bphy.h"
      17                 :            : 
      18                 :            : static const struct rte_pci_id pci_bphy_map[] = {
      19                 :            :         {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_BPHY)},
      20                 :            :         {
      21                 :            :                 .vendor_id = 0,
      22                 :            :         },
      23                 :            : };
      24                 :            : 
      25                 :            : struct bphy_test {
      26                 :            :         int irq_num;
      27                 :            :         cnxk_bphy_intr_handler_t handler;
      28                 :            :         void *data;
      29                 :            :         int cpu;
      30                 :            :         bool handled_intr;
      31                 :            :         int handled_data;
      32                 :            :         int test_data;
      33                 :            : };
      34                 :            : 
      35                 :            : static struct bphy_test *test;
      36                 :            : 
      37                 :            : static void
      38                 :          0 : bphy_test_handler_fn(int irq_num, void *isr_data)
      39                 :            : {
      40                 :          0 :         test[irq_num].handled_intr = true;
      41                 :          0 :         test[irq_num].handled_data = *((int *)isr_data);
      42                 :          0 : }
      43                 :            : 
      44                 :            : int
      45                 :          0 : rte_pmd_bphy_npa_pf_func_get_rmt(uint16_t *pf_func)
      46                 :            : {
      47                 :          0 :         *pf_func = roc_bphy_npa_pf_func_get();
      48                 :            : 
      49                 :          0 :         return 0;
      50                 :            : }
      51                 :            : 
      52                 :            : int
      53                 :          0 : rte_pmd_bphy_sso_pf_func_get_rmt(uint16_t *pf_func)
      54                 :            : {
      55                 :          0 :         *pf_func = roc_bphy_sso_pf_func_get();
      56                 :            : 
      57                 :          0 :         return 0;
      58                 :            : }
      59                 :            : 
      60                 :            : static int
      61                 :          0 : bphy_rawdev_selftest(uint16_t dev_id)
      62                 :            : {
      63                 :            :         unsigned int i, queues, descs;
      64                 :            :         uint16_t pf_func;
      65                 :            :         uint64_t max_irq;
      66                 :            :         int ret;
      67                 :            : 
      68                 :          0 :         queues = rte_rawdev_queue_count(dev_id);
      69         [ #  # ]:          0 :         if (queues == 0)
      70                 :            :                 return -ENODEV;
      71         [ #  # ]:          0 :         if (queues != BPHY_QUEUE_CNT)
      72                 :            :                 return -EINVAL;
      73                 :            : 
      74                 :          0 :         ret = rte_rawdev_start(dev_id);
      75         [ #  # ]:          0 :         if (ret)
      76                 :            :                 return ret;
      77                 :            : 
      78                 :          0 :         ret = rte_rawdev_queue_conf_get(dev_id, CNXK_BPHY_DEF_QUEUE, &descs,
      79                 :            :                                         sizeof(descs));
      80         [ #  # ]:          0 :         if (ret)
      81                 :          0 :                 goto err_desc;
      82         [ #  # ]:          0 :         if (descs != 1) {
      83                 :            :                 ret = -ENODEV;
      84                 :          0 :                 CNXK_BPHY_LOG(ERR, "Wrong number of descs reported");
      85                 :          0 :                 goto err_desc;
      86                 :            :         }
      87                 :            : 
      88                 :            :         ret = rte_pmd_bphy_npa_pf_func_get(dev_id, &pf_func);
      89         [ #  # ]:          0 :         if (ret || pf_func == 0)
      90                 :          0 :                 CNXK_BPHY_LOG(WARNING, "NPA pf_func is invalid");
      91                 :            : 
      92                 :            :         ret = rte_pmd_bphy_sso_pf_func_get(dev_id, &pf_func);
      93         [ #  # ]:          0 :         if (ret || pf_func == 0)
      94                 :          0 :                 CNXK_BPHY_LOG(WARNING, "SSO pf_func is invalid");
      95                 :            : 
      96                 :            :         ret = rte_pmd_bphy_intr_init(dev_id);
      97                 :            :         if (ret) {
      98                 :          0 :                 CNXK_BPHY_LOG(ERR, "intr init failed");
      99                 :          0 :                 return ret;
     100                 :            :         }
     101                 :            : 
     102                 :          0 :         max_irq = cnxk_bphy_irq_max_get(dev_id);
     103                 :            : 
     104                 :          0 :         test = rte_zmalloc("BPHY", max_irq * sizeof(*test), 0);
     105         [ #  # ]:          0 :         if (test == NULL) {
     106                 :          0 :                 CNXK_BPHY_LOG(ERR, "intr alloc failed");
     107                 :          0 :                 goto err_alloc;
     108                 :            :         }
     109                 :            : 
     110         [ #  # ]:          0 :         for (i = 0; i < max_irq; i++) {
     111                 :          0 :                 test[i].test_data = i;
     112                 :          0 :                 test[i].irq_num = i;
     113                 :          0 :                 test[i].handler = bphy_test_handler_fn;
     114                 :          0 :                 test[i].data = &test[i].test_data;
     115                 :            :         }
     116                 :            : 
     117         [ #  # ]:          0 :         for (i = 0; i < max_irq; i++) {
     118                 :          0 :                 ret = rte_pmd_bphy_intr_register(dev_id, test[i].irq_num,
     119                 :          0 :                                                  test[i].handler, test[i].data,
     120                 :            :                                                  0);
     121         [ #  # ]:          0 :                 if (ret == -ENOTSUP) {
     122                 :            :                         /* In the test we iterate over all irq numbers
     123                 :            :                          * so if some of them are not supported by given
     124                 :            :                          * platform we treat respective results as valid
     125                 :            :                          * ones. This way they have no impact on overall
     126                 :            :                          * test results.
     127                 :            :                          */
     128                 :          0 :                         test[i].handled_intr = true;
     129                 :          0 :                         test[i].handled_data = test[i].test_data;
     130                 :            :                         ret = 0;
     131                 :          0 :                         continue;
     132                 :            :                 }
     133                 :            : 
     134         [ #  # ]:          0 :                 if (ret) {
     135                 :          0 :                         CNXK_BPHY_LOG(ERR, "intr register failed at irq %d", i);
     136                 :          0 :                         goto err_register;
     137                 :            :                 }
     138                 :            :         }
     139                 :            : 
     140         [ #  # ]:          0 :         for (i = 0; i < max_irq; i++)
     141                 :          0 :                 roc_bphy_intr_handler(i);
     142                 :            : 
     143         [ #  # ]:          0 :         for (i = 0; i < max_irq; i++) {
     144         [ #  # ]:          0 :                 if (!test[i].handled_intr) {
     145                 :          0 :                         CNXK_BPHY_LOG(ERR, "intr %u not handled", i);
     146                 :            :                         ret = -1;
     147                 :          0 :                         break;
     148                 :            :                 }
     149         [ #  # ]:          0 :                 if (test[i].handled_data != test[i].test_data) {
     150                 :          0 :                         CNXK_BPHY_LOG(ERR, "intr %u has wrong handler", i);
     151                 :            :                         ret = -1;
     152                 :          0 :                         break;
     153                 :            :                 }
     154                 :            :         }
     155                 :            : 
     156                 :          0 : err_register:
     157                 :            :         /*
     158                 :            :          * In case of registration failure the loop goes over all
     159                 :            :          * interrupts which is safe due to internal guards in
     160                 :            :          * rte_pmd_bphy_intr_unregister().
     161                 :            :          */
     162         [ #  # ]:          0 :         for (i = 0; i < max_irq; i++)
     163                 :          0 :                 rte_pmd_bphy_intr_unregister(dev_id, i);
     164                 :            : 
     165                 :          0 :         rte_free(test);
     166                 :          0 : err_alloc:
     167                 :            :         rte_pmd_bphy_intr_fini(dev_id);
     168                 :          0 : err_desc:
     169                 :          0 :         rte_rawdev_stop(dev_id);
     170                 :            : 
     171                 :          0 :         return ret;
     172                 :            : }
     173                 :            : 
     174                 :            : static void
     175                 :          0 : bphy_rawdev_get_name(char *name, struct rte_pci_device *pci_dev)
     176                 :            : {
     177                 :          0 :         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "BPHY:%02x:%02x.%x",
     178                 :          0 :                  pci_dev->addr.bus, pci_dev->addr.devid,
     179                 :          0 :                  pci_dev->addr.function);
     180                 :          0 : }
     181                 :            : 
     182                 :            : static int
     183                 :          0 : cnxk_bphy_irq_enqueue_bufs(struct rte_rawdev *dev,
     184                 :            :                            struct rte_rawdev_buf **buffers, unsigned int count,
     185                 :            :                            rte_rawdev_obj_t context)
     186                 :            : {
     187                 :          0 :         struct bphy_device *bphy_dev = (struct bphy_device *)dev->dev_private;
     188                 :          0 :         struct cnxk_bphy_irq_msg *msg = buffers[0]->buf_addr;
     189                 :            :         struct bphy_irq_queue *qp = &bphy_dev->queues[0];
     190                 :          0 :         unsigned int queue = (size_t)context;
     191                 :            :         struct cnxk_bphy_irq_info *info;
     192                 :            :         struct cnxk_bphy_mem *mem;
     193                 :            :         uint16_t *pf_func;
     194                 :            :         void *rsp = NULL;
     195                 :            :         int ret;
     196                 :            : 
     197         [ #  # ]:          0 :         if (queue >= RTE_DIM(bphy_dev->queues))
     198                 :            :                 return -EINVAL;
     199                 :            : 
     200         [ #  # ]:          0 :         if (count == 0)
     201                 :            :                 return 0;
     202                 :            : 
     203   [ #  #  #  #  :          0 :         switch (msg->type) {
             #  #  #  # ]
     204                 :          0 :         case CNXK_BPHY_IRQ_MSG_TYPE_INIT:
     205                 :          0 :                 ret = cnxk_bphy_intr_init(dev->dev_id);
     206         [ #  # ]:          0 :                 if (ret)
     207                 :            :                         return ret;
     208                 :            :                 break;
     209                 :          0 :         case CNXK_BPHY_IRQ_MSG_TYPE_FINI:
     210                 :          0 :                 cnxk_bphy_intr_fini(dev->dev_id);
     211                 :          0 :                 break;
     212                 :          0 :         case CNXK_BPHY_IRQ_MSG_TYPE_REGISTER:
     213                 :          0 :                 info = (struct cnxk_bphy_irq_info *)msg->data;
     214                 :          0 :                 ret = cnxk_bphy_intr_register(dev->dev_id, info->irq_num,
     215                 :            :                                               info->handler, info->data,
     216                 :            :                                               info->cpu);
     217         [ #  # ]:          0 :                 if (ret)
     218                 :            :                         return ret;
     219                 :            :                 break;
     220                 :          0 :         case CNXK_BPHY_IRQ_MSG_TYPE_UNREGISTER:
     221                 :          0 :                 info = (struct cnxk_bphy_irq_info *)msg->data;
     222                 :          0 :                 cnxk_bphy_intr_unregister(dev->dev_id, info->irq_num);
     223                 :          0 :                 break;
     224                 :          0 :         case CNXK_BPHY_IRQ_MSG_TYPE_MEM_GET:
     225                 :          0 :                 mem = rte_zmalloc(NULL, sizeof(*mem), 0);
     226         [ #  # ]:          0 :                 if (!mem)
     227                 :            :                         return -ENOMEM;
     228                 :            : 
     229                 :          0 :                 *mem = bphy_dev->mem;
     230                 :            :                 rsp = mem;
     231                 :          0 :                 break;
     232                 :          0 :         case CNXK_BPHY_MSG_TYPE_NPA_PF_FUNC:
     233                 :          0 :                 pf_func = rte_malloc(NULL, sizeof(*pf_func), 0);
     234         [ #  # ]:          0 :                 if (!pf_func)
     235                 :            :                         return -ENOMEM;
     236                 :            : 
     237                 :          0 :                 *pf_func = roc_bphy_npa_pf_func_get();
     238                 :            :                 rsp = pf_func;
     239                 :          0 :                 break;
     240                 :          0 :         case CNXK_BPHY_MSG_TYPE_SSO_PF_FUNC:
     241                 :          0 :                 pf_func = rte_malloc(NULL, sizeof(*pf_func), 0);
     242         [ #  # ]:          0 :                 if (!pf_func)
     243                 :            :                         return -ENOMEM;
     244                 :            : 
     245                 :          0 :                 *pf_func = roc_bphy_sso_pf_func_get();
     246                 :            :                 rsp = pf_func;
     247                 :          0 :                 break;
     248                 :            :         default:
     249                 :            :                 return -EINVAL;
     250                 :            :         }
     251                 :            : 
     252                 :            :         /* get rid of last response if any */
     253         [ #  # ]:          0 :         if (qp->rsp) {
     254                 :          0 :                 CNXK_BPHY_LOG(WARNING, "Previous response got overwritten");
     255                 :          0 :                 rte_free(qp->rsp);
     256                 :            :         }
     257                 :          0 :         qp->rsp = rsp;
     258                 :            : 
     259                 :          0 :         return 1;
     260                 :            : }
     261                 :            : 
     262                 :            : static int
     263                 :          0 : cnxk_bphy_irq_dequeue_bufs(struct rte_rawdev *dev,
     264                 :            :                            struct rte_rawdev_buf **buffers, unsigned int count,
     265                 :            :                            rte_rawdev_obj_t context)
     266                 :            : {
     267                 :          0 :         struct bphy_device *bphy_dev = (struct bphy_device *)dev->dev_private;
     268                 :          0 :         unsigned int queue = (size_t)context;
     269                 :            :         struct bphy_irq_queue *qp;
     270                 :            : 
     271         [ #  # ]:          0 :         if (queue >= RTE_DIM(bphy_dev->queues))
     272                 :            :                 return -EINVAL;
     273                 :            : 
     274         [ #  # ]:          0 :         if (count == 0)
     275                 :            :                 return 0;
     276                 :            : 
     277                 :            :         qp = &bphy_dev->queues[queue];
     278         [ #  # ]:          0 :         if (qp->rsp) {
     279                 :          0 :                 buffers[0]->buf_addr = qp->rsp;
     280                 :          0 :                 qp->rsp = NULL;
     281                 :            : 
     282                 :          0 :                 return 1;
     283                 :            :         }
     284                 :            : 
     285                 :            :         return 0;
     286                 :            : }
     287                 :            : 
     288                 :            : static uint16_t
     289                 :          0 : cnxk_bphy_irq_queue_count(struct rte_rawdev *dev)
     290                 :            : {
     291                 :            :         struct bphy_device *bphy_dev = (struct bphy_device *)dev->dev_private;
     292                 :            : 
     293                 :          0 :         return RTE_DIM(bphy_dev->queues);
     294                 :            : }
     295                 :            : 
     296                 :            : static int
     297                 :          0 : cnxk_bphy_irq_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id,
     298                 :            :                              rte_rawdev_obj_t queue_conf,
     299                 :            :                              size_t queue_conf_size)
     300                 :            : {
     301                 :            :         RTE_SET_USED(dev);
     302                 :            :         RTE_SET_USED(queue_id);
     303                 :            : 
     304         [ #  # ]:          0 :         if (queue_conf_size != sizeof(unsigned int))
     305                 :            :                 return -EINVAL;
     306                 :            : 
     307                 :          0 :         *(unsigned int *)queue_conf = 1;
     308                 :            : 
     309                 :          0 :         return 0;
     310                 :            : }
     311                 :            : 
     312                 :            : static const struct rte_rawdev_ops bphy_rawdev_ops = {
     313                 :            :         .queue_def_conf = cnxk_bphy_irq_queue_def_conf,
     314                 :            :         .enqueue_bufs = cnxk_bphy_irq_enqueue_bufs,
     315                 :            :         .dequeue_bufs = cnxk_bphy_irq_dequeue_bufs,
     316                 :            :         .queue_count = cnxk_bphy_irq_queue_count,
     317                 :            :         .dev_selftest = bphy_rawdev_selftest,
     318                 :            : };
     319                 :            : 
     320                 :            : static int
     321                 :          0 : bphy_rawdev_probe(struct rte_pci_driver *pci_drv,
     322                 :            :                   struct rte_pci_device *pci_dev)
     323                 :            : {
     324                 :            :         struct bphy_device *bphy_dev = NULL;
     325                 :            :         char name[RTE_RAWDEV_NAME_MAX_LEN];
     326                 :            :         struct rte_rawdev *bphy_rawdev;
     327                 :            :         int ret;
     328                 :            : 
     329                 :            :         RTE_SET_USED(pci_drv);
     330                 :            : 
     331         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     332                 :            :                 return 0;
     333                 :            : 
     334         [ #  # ]:          0 :         if (!pci_dev->mem_resource[0].addr) {
     335                 :          0 :                 CNXK_BPHY_LOG(ERR, "BARs have invalid values: BAR0 %p BAR2 %p",
     336                 :            :                               pci_dev->mem_resource[0].addr, pci_dev->mem_resource[2].addr);
     337                 :          0 :                 return -ENODEV;
     338                 :            :         }
     339                 :            : 
     340                 :          0 :         ret = roc_plt_init();
     341         [ #  # ]:          0 :         if (ret)
     342                 :            :                 return ret;
     343                 :            : 
     344                 :          0 :         bphy_rawdev_get_name(name, pci_dev);
     345                 :          0 :         bphy_rawdev = rte_rawdev_pmd_allocate(name, sizeof(*bphy_dev),
     346                 :          0 :                                               rte_socket_id());
     347         [ #  # ]:          0 :         if (bphy_rawdev == NULL) {
     348                 :          0 :                 CNXK_BPHY_LOG(ERR, "Failed to allocate rawdev");
     349                 :          0 :                 return -ENOMEM;
     350                 :            :         }
     351                 :            : 
     352                 :          0 :         bphy_rawdev->dev_ops = &bphy_rawdev_ops;
     353                 :          0 :         bphy_rawdev->device = &pci_dev->device;
     354                 :          0 :         bphy_rawdev->driver_name = pci_dev->driver->driver.name;
     355                 :            : 
     356                 :          0 :         bphy_dev = (struct bphy_device *)bphy_rawdev->dev_private;
     357                 :          0 :         bphy_dev->mem.res0 = pci_dev->mem_resource[0];
     358                 :          0 :         bphy_dev->mem.res2 = pci_dev->mem_resource[2];
     359                 :          0 :         bphy_dev->bphy.pci_dev = pci_dev;
     360                 :            : 
     361         [ #  # ]:          0 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
     362                 :          0 :                 ret = roc_bphy_dev_init(&bphy_dev->bphy);
     363         [ #  # ]:          0 :                 if (ret) {
     364                 :          0 :                         rte_rawdev_pmd_release(bphy_rawdev);
     365                 :          0 :                         return ret;
     366                 :            :                 }
     367                 :            :         }
     368                 :            : 
     369                 :            :         return 0;
     370                 :            : }
     371                 :            : 
     372                 :            : static int
     373                 :          0 : bphy_rawdev_remove(struct rte_pci_device *pci_dev)
     374                 :            : {
     375                 :            :         char name[RTE_RAWDEV_NAME_MAX_LEN];
     376                 :            :         struct bphy_device *bphy_dev;
     377                 :            :         struct rte_rawdev *rawdev;
     378                 :            : 
     379         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     380                 :            :                 return 0;
     381                 :            : 
     382         [ #  # ]:          0 :         if (pci_dev == NULL) {
     383                 :          0 :                 CNXK_BPHY_LOG(ERR, "invalid pci_dev");
     384                 :          0 :                 return -EINVAL;
     385                 :            :         }
     386                 :            : 
     387                 :          0 :         bphy_rawdev_get_name(name, pci_dev);
     388                 :          0 :         rawdev = rte_rawdev_pmd_get_named_dev(name);
     389         [ #  # ]:          0 :         if (rawdev == NULL) {
     390                 :          0 :                 CNXK_BPHY_LOG(ERR, "invalid device name (%s)", name);
     391                 :          0 :                 return -EINVAL;
     392                 :            :         }
     393                 :            : 
     394         [ #  # ]:          0 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
     395                 :          0 :                 bphy_dev = (struct bphy_device *)rawdev->dev_private;
     396                 :          0 :                 roc_bphy_dev_fini(&bphy_dev->bphy);
     397                 :            :         }
     398                 :            : 
     399                 :          0 :         return rte_rawdev_pmd_release(rawdev);
     400                 :            : }
     401                 :            : 
     402                 :            : static struct rte_pci_driver cnxk_bphy_rawdev_pmd = {
     403                 :            :         .id_table = pci_bphy_map,
     404                 :            :         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
     405                 :            :         .probe = bphy_rawdev_probe,
     406                 :            :         .remove = bphy_rawdev_remove,
     407                 :            : };
     408                 :            : 
     409                 :        252 : RTE_PMD_REGISTER_PCI(bphy_rawdev_pci_driver, cnxk_bphy_rawdev_pmd);
     410                 :            : RTE_PMD_REGISTER_PCI_TABLE(bphy_rawdev_pci_driver, pci_bphy_map);
     411                 :            : RTE_PMD_REGISTER_KMOD_DEP(bphy_rawdev_pci_driver, "vfio-pci");
     412         [ -  + ]:        252 : RTE_LOG_REGISTER_SUFFIX(cnxk_logtype_bphy, bphy, INFO);

Generated by: LCOV version 1.14