LCOV - code coverage report
Current view: top level - drivers/net/cnxk - cnxk_eswitch.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 1 373 0.3 %
Date: 2025-02-01 18:54:23 Functions: 1 18 5.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 171 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2024 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_thash.h>
       6                 :            : 
       7                 :            : #include <cnxk_eswitch.h>
       8                 :            : #include <cnxk_rep.h>
       9                 :            : 
      10                 :            : #define CNXK_NIX_DEF_SQ_COUNT 512
      11                 :            : 
      12                 :            : int
      13                 :          0 : cnxk_eswitch_representor_id(struct cnxk_eswitch_dev *eswitch_dev, uint16_t hw_func,
      14                 :            :                             uint16_t *rep_id)
      15                 :            : {
      16                 :            :         struct cnxk_esw_repr_hw_info *repr_info;
      17                 :            :         int rc = 0;
      18                 :            : 
      19                 :          0 :         repr_info = cnxk_eswitch_representor_hw_info(eswitch_dev, hw_func);
      20         [ #  # ]:          0 :         if (!repr_info) {
      21                 :          0 :                 plt_warn("Failed to get representor group for %x", hw_func);
      22                 :            :                 rc = -ENOENT;
      23                 :          0 :                 goto fail;
      24                 :            :         }
      25                 :            : 
      26                 :          0 :         *rep_id = repr_info->rep_id;
      27                 :            : 
      28                 :          0 :         return 0;
      29                 :            : fail:
      30                 :          0 :         return rc;
      31                 :            : }
      32                 :            : 
      33                 :            : struct cnxk_esw_repr_hw_info *
      34                 :          0 : cnxk_eswitch_representor_hw_info(struct cnxk_eswitch_dev *eswitch_dev, uint16_t hw_func)
      35                 :            : {
      36                 :            :         struct cnxk_eswitch_devargs *esw_da;
      37                 :            :         int i, j;
      38                 :            : 
      39         [ #  # ]:          0 :         if (!eswitch_dev)
      40                 :            :                 return NULL;
      41                 :            : 
      42                 :            :         /* Traversing the initialized represented list */
      43         [ #  # ]:          0 :         for (i = 0; i < eswitch_dev->nb_esw_da; i++) {
      44                 :            :                 esw_da = &eswitch_dev->esw_da[i];
      45         [ #  # ]:          0 :                 for (j = 0; j < esw_da->nb_repr_ports; j++) {
      46         [ #  # ]:          0 :                         if (esw_da->repr_hw_info[j].hw_func == hw_func)
      47                 :          0 :                                 return &esw_da->repr_hw_info[j];
      48                 :            :                 }
      49                 :            :         }
      50                 :            :         return NULL;
      51                 :            : }
      52                 :            : 
      53                 :            : static int
      54                 :          0 : eswitch_hw_rsrc_cleanup(struct cnxk_eswitch_dev *eswitch_dev, struct rte_pci_device *pci_dev)
      55                 :            : {
      56                 :            :         struct roc_nix *nix;
      57                 :            :         int rc = 0;
      58                 :            : 
      59                 :          0 :         nix = &eswitch_dev->nix;
      60                 :            : 
      61                 :          0 :         roc_nix_unregister_queue_irqs(nix);
      62                 :          0 :         roc_nix_tm_fini(nix);
      63                 :          0 :         rc = roc_nix_lf_free(nix);
      64         [ #  # ]:          0 :         if (rc) {
      65                 :          0 :                 plt_err("Failed to cleanup sq, rc %d", rc);
      66                 :          0 :                 goto exit;
      67                 :            :         }
      68                 :            : 
      69                 :            :         /* Check if this device is hosting common resource */
      70                 :          0 :         nix = roc_idev_npa_nix_get();
      71   [ #  #  #  # ]:          0 :         if (!nix || nix->pci_dev != pci_dev) {
      72                 :            :                 rc = 0;
      73                 :          0 :                 goto exit;
      74                 :            :         }
      75                 :            : 
      76                 :            :         /* Try nix fini now */
      77                 :          0 :         rc = roc_nix_dev_fini(nix);
      78         [ #  # ]:          0 :         if (rc == -EAGAIN) {
      79                 :          0 :                 plt_info("Common resource in use by other devices %s", pci_dev->name);
      80                 :          0 :                 goto exit;
      81         [ #  # ]:          0 :         } else if (rc) {
      82                 :          0 :                 plt_err("Failed in nix dev fini, rc=%d", rc);
      83                 :          0 :                 goto exit;
      84                 :            :         }
      85                 :            : 
      86                 :          0 :         rte_free(eswitch_dev->txq);
      87                 :          0 :         rte_free(eswitch_dev->rxq);
      88                 :          0 :         rte_free(eswitch_dev->cxq);
      89                 :            : 
      90                 :          0 : exit:
      91                 :          0 :         return rc;
      92                 :            : }
      93                 :            : 
      94                 :            : static int
      95                 :          0 : cnxk_eswitch_dev_remove(struct rte_pci_device *pci_dev)
      96                 :            : {
      97                 :            :         struct cnxk_eswitch_dev *eswitch_dev;
      98                 :            :         int rc = 0;
      99                 :            : 
     100         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     101                 :            :                 return 0;
     102                 :            : 
     103                 :            :         eswitch_dev = cnxk_eswitch_pmd_priv();
     104         [ #  # ]:          0 :         if (!eswitch_dev) {
     105                 :            :                 rc = -EINVAL;
     106                 :          0 :                 goto exit;
     107                 :            :         }
     108                 :            : 
     109                 :            :         /* Remove representor devices associated with PF */
     110         [ #  # ]:          0 :         if (eswitch_dev->repr_cnt.nb_repr_created) {
     111                 :            :                 /* Exiting the rep msg ctrl thread */
     112         [ #  # ]:          0 :                 if (eswitch_dev->start_ctrl_msg_thrd) {
     113                 :            :                         uint32_t sunlen;
     114                 :          0 :                         struct sockaddr_un sun = {0};
     115                 :            :                         int sock_fd = 0;
     116                 :            : 
     117                 :          0 :                         eswitch_dev->start_ctrl_msg_thrd = false;
     118         [ #  # ]:          0 :                         if (!eswitch_dev->client_connected) {
     119                 :          0 :                                 plt_esw_dbg("Establishing connection for teardown");
     120                 :          0 :                                 sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
     121         [ #  # ]:          0 :                                 if (sock_fd == -1) {
     122                 :          0 :                                         plt_err("Failed to open socket. err %d", -errno);
     123                 :          0 :                                         return -errno;
     124                 :            :                                 }
     125                 :          0 :                                 sun.sun_family = AF_UNIX;
     126                 :            :                                 sunlen = sizeof(struct sockaddr_un);
     127                 :            :                                 strncpy(sun.sun_path, CNXK_ESWITCH_CTRL_MSG_SOCK_PATH,
     128                 :            :                                         sizeof(sun.sun_path) - 1);
     129                 :            : 
     130         [ #  # ]:          0 :                                 if (connect(sock_fd, (struct sockaddr *)&sun, sunlen) < 0) {
     131                 :          0 :                                         plt_err("Failed to connect socket: %s, err %d",
     132                 :            :                                                 CNXK_ESWITCH_CTRL_MSG_SOCK_PATH, errno);
     133                 :          0 :                                         close(sock_fd);
     134                 :          0 :                                         return -errno;
     135                 :            :                                 }
     136                 :            :                         }
     137                 :          0 :                         rte_thread_join(eswitch_dev->rep_ctrl_msg_thread, NULL);
     138         [ #  # ]:          0 :                         if (!eswitch_dev->client_connected)
     139                 :          0 :                                 close(sock_fd);
     140                 :            :                 }
     141                 :            : 
     142         [ #  # ]:          0 :                 if (eswitch_dev->repte_msg_proc.start_thread) {
     143                 :          0 :                         eswitch_dev->repte_msg_proc.start_thread = false;
     144                 :          0 :                         pthread_cond_signal(&eswitch_dev->repte_msg_proc.repte_msg_cond);
     145                 :          0 :                         rte_thread_join(eswitch_dev->repte_msg_proc.repte_msg_thread, NULL);
     146                 :          0 :                         pthread_mutex_destroy(&eswitch_dev->repte_msg_proc.mutex);
     147                 :          0 :                         pthread_cond_destroy(&eswitch_dev->repte_msg_proc.repte_msg_cond);
     148                 :            :                 }
     149                 :            : 
     150                 :            :                 /* Remove representor devices associated with PF */
     151                 :          0 :                 cnxk_rep_dev_remove(eswitch_dev);
     152                 :            :         }
     153                 :            : 
     154                 :            :         /* Cleanup NPC rxtx flow rules */
     155                 :          0 :         cnxk_eswitch_flow_rules_remove_list(eswitch_dev, &eswitch_dev->esw_flow_list,
     156                 :          0 :                                             eswitch_dev->npc.pf_func);
     157                 :            : 
     158                 :            :         /* Cleanup HW resources */
     159                 :          0 :         eswitch_hw_rsrc_cleanup(eswitch_dev, pci_dev);
     160                 :            : 
     161                 :          0 :         rte_free(eswitch_dev);
     162                 :            : exit:
     163                 :            :         return rc;
     164                 :            : }
     165                 :            : 
     166                 :            : int
     167                 :          0 : cnxk_eswitch_nix_rsrc_start(struct cnxk_eswitch_dev *eswitch_dev)
     168                 :            : {
     169                 :            :         int rc;
     170                 :            : 
     171                 :            :         /* Install eswitch PF mcam rules */
     172                 :          0 :         rc = cnxk_eswitch_pfvf_flow_rules_install(eswitch_dev, false);
     173         [ #  # ]:          0 :         if (rc) {
     174                 :          0 :                 plt_err("Failed to install rxtx rules, rc %d", rc);
     175                 :          0 :                 goto done;
     176                 :            :         }
     177                 :            : 
     178                 :            :         /* Configure TPID for Eswitch PF LFs */
     179                 :          0 :         rc = roc_eswitch_nix_vlan_tpid_set(&eswitch_dev->nix, ROC_NIX_VLAN_TYPE_OUTER,
     180                 :            :                                            CNXK_ESWITCH_VLAN_TPID, false);
     181         [ #  # ]:          0 :         if (rc) {
     182                 :          0 :                 plt_err("Failed to configure tpid, rc %d", rc);
     183                 :          0 :                 goto done;
     184                 :            :         }
     185                 :            : 
     186                 :            :         /* Enable Rx in NPC */
     187                 :          0 :         rc = roc_nix_npc_rx_ena_dis(&eswitch_dev->nix, true);
     188         [ #  # ]:          0 :         if (rc) {
     189                 :          0 :                 plt_err("Failed to enable NPC rx %d", rc);
     190                 :          0 :                 goto done;
     191                 :            :         }
     192                 :            : 
     193                 :          0 :         rc = roc_npc_mcam_enable_all_entries(&eswitch_dev->npc, 1);
     194         [ #  # ]:          0 :         if (rc) {
     195                 :          0 :                 plt_err("Failed to enable NPC entries %d", rc);
     196                 :          0 :                 goto done;
     197                 :            :         }
     198                 :            : 
     199                 :          0 : done:
     200                 :          0 :         return 0;
     201                 :            : }
     202                 :            : 
     203                 :            : int
     204                 :          0 : cnxk_eswitch_txq_start(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
     205                 :            : {
     206                 :          0 :         struct roc_nix_sq *sq = &eswitch_dev->txq[qid].sqs;
     207                 :            :         int rc = -EINVAL;
     208                 :            : 
     209         [ #  # ]:          0 :         if (eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STARTED)
     210                 :            :                 return 0;
     211                 :            : 
     212         [ #  # ]:          0 :         if (eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_CONFIGURED) {
     213                 :          0 :                 plt_err("Eswitch txq %d not configured yet", qid);
     214                 :          0 :                 goto done;
     215                 :            :         }
     216                 :            : 
     217                 :          0 :         rc = roc_nix_sq_ena_dis(sq, true);
     218         [ #  # ]:          0 :         if (rc) {
     219                 :          0 :                 plt_err("Failed to enable sq aura fc, txq=%u, rc=%d", qid, rc);
     220                 :          0 :                 goto done;
     221                 :            :         }
     222                 :            : 
     223                 :          0 :         eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STARTED;
     224                 :            : done:
     225                 :            :         return rc;
     226                 :            : }
     227                 :            : 
     228                 :            : int
     229                 :          0 : cnxk_eswitch_txq_stop(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
     230                 :            : {
     231                 :          0 :         struct roc_nix_sq *sq = &eswitch_dev->txq[qid].sqs;
     232                 :            :         int rc = -EINVAL;
     233                 :            : 
     234         [ #  # ]:          0 :         if (eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STOPPED ||
     235                 :            :             eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
     236                 :            :                 return 0;
     237                 :            : 
     238         [ #  # ]:          0 :         if (eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_STARTED) {
     239                 :          0 :                 plt_err("Eswitch txq %d not started", qid);
     240                 :          0 :                 goto done;
     241                 :            :         }
     242                 :            : 
     243                 :          0 :         rc = roc_nix_sq_ena_dis(sq, false);
     244         [ #  # ]:          0 :         if (rc) {
     245                 :          0 :                 plt_err("Failed to disable sqb aura fc, txq=%u, rc=%d", qid, rc);
     246                 :          0 :                 goto done;
     247                 :            :         }
     248                 :            : 
     249                 :          0 :         eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STOPPED;
     250                 :            : done:
     251                 :            :         return rc;
     252                 :            : }
     253                 :            : 
     254                 :            : int
     255                 :          0 : cnxk_eswitch_rxq_start(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
     256                 :            : {
     257                 :          0 :         struct roc_nix_rq *rq = &eswitch_dev->rxq[qid].rqs;
     258                 :            :         int rc = -EINVAL;
     259                 :            : 
     260         [ #  # ]:          0 :         if (eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STARTED)
     261                 :            :                 return 0;
     262                 :            : 
     263         [ #  # ]:          0 :         if (eswitch_dev->rxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_CONFIGURED) {
     264                 :          0 :                 plt_err("Eswitch rxq %d not configured yet", qid);
     265                 :          0 :                 goto done;
     266                 :            :         }
     267                 :            : 
     268                 :          0 :         rc = roc_nix_rq_ena_dis(rq, true);
     269         [ #  # ]:          0 :         if (rc) {
     270                 :          0 :                 plt_err("Failed to enable rxq=%u, rc=%d", qid, rc);
     271                 :          0 :                 goto done;
     272                 :            :         }
     273                 :            : 
     274                 :          0 :         eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STARTED;
     275                 :            : done:
     276                 :            :         return rc;
     277                 :            : }
     278                 :            : 
     279                 :            : int
     280                 :          0 : cnxk_eswitch_rxq_stop(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
     281                 :            : {
     282                 :          0 :         struct roc_nix_rq *rq = &eswitch_dev->rxq[qid].rqs;
     283                 :            :         int rc = -EINVAL;
     284                 :            : 
     285         [ #  # ]:          0 :         if (eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STOPPED ||
     286                 :            :             eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
     287                 :            :                 return 0;
     288                 :            : 
     289         [ #  # ]:          0 :         if (eswitch_dev->rxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_STARTED) {
     290                 :          0 :                 plt_err("Eswitch rxq %d not started", qid);
     291                 :          0 :                 goto done;
     292                 :            :         }
     293                 :            : 
     294                 :          0 :         rc = roc_nix_rq_ena_dis(rq, false);
     295         [ #  # ]:          0 :         if (rc) {
     296                 :          0 :                 plt_err("Failed to disable rxq=%u, rc=%d", qid, rc);
     297                 :          0 :                 goto done;
     298                 :            :         }
     299                 :            : 
     300                 :          0 :         eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STOPPED;
     301                 :            : done:
     302                 :            :         return rc;
     303                 :            : }
     304                 :            : 
     305                 :            : int
     306                 :          0 : cnxk_eswitch_rxq_release(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
     307                 :            : {
     308                 :            :         struct roc_nix_rq *rq;
     309                 :            :         struct roc_nix_cq *cq;
     310                 :            :         int rc;
     311                 :            : 
     312         [ #  # ]:          0 :         if (eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
     313                 :            :                 return 0;
     314                 :            : 
     315                 :            :         /* Cleanup ROC SQ */
     316                 :          0 :         rq = &eswitch_dev->rxq[qid].rqs;
     317                 :          0 :         rc = roc_nix_rq_fini(rq);
     318         [ #  # ]:          0 :         if (rc) {
     319                 :          0 :                 plt_err("Failed to cleanup sq, rc=%d", rc);
     320                 :          0 :                 goto fail;
     321                 :            :         }
     322                 :            : 
     323                 :          0 :         eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_RELEASED;
     324                 :            : 
     325                 :            :         /* Cleanup ROC CQ */
     326                 :          0 :         cq = &eswitch_dev->cxq[qid].cqs;
     327                 :          0 :         rc = roc_nix_cq_fini(cq);
     328         [ #  # ]:          0 :         if (rc) {
     329                 :          0 :                 plt_err("Failed to cleanup cq, rc=%d", rc);
     330                 :          0 :                 goto fail;
     331                 :            :         }
     332                 :            : 
     333                 :          0 :         eswitch_dev->cxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_RELEASED;
     334                 :            : fail:
     335                 :            :         return rc;
     336                 :            : }
     337                 :            : 
     338                 :            : int
     339                 :          0 : cnxk_eswitch_rxq_setup(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid, uint16_t nb_desc,
     340                 :            :                        const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp)
     341                 :            : {
     342                 :          0 :         struct roc_nix *nix = &eswitch_dev->nix;
     343                 :            :         struct rte_mempool *lpb_pool = mp;
     344                 :            :         struct rte_mempool_ops *ops;
     345                 :            :         const char *platform_ops;
     346                 :            :         struct roc_nix_rq *rq;
     347                 :            :         struct roc_nix_cq *cq;
     348                 :            :         uint16_t first_skip;
     349                 :            :         int rc = -EINVAL;
     350                 :            : 
     351         [ #  # ]:          0 :         if (eswitch_dev->rxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_RELEASED ||
     352         [ #  # ]:          0 :             eswitch_dev->cxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_RELEASED) {
     353                 :          0 :                 plt_err("Queue %d is in invalid state %d, cannot be setup", qid,
     354                 :            :                         eswitch_dev->txq[qid].state);
     355                 :          0 :                 goto fail;
     356                 :            :         }
     357                 :            : 
     358                 :            :         RTE_SET_USED(rx_conf);
     359                 :          0 :         platform_ops = rte_mbuf_platform_mempool_ops();
     360                 :            :         /* This driver needs cnxk_npa mempool ops to work */
     361         [ #  # ]:          0 :         ops = rte_mempool_get_ops(lpb_pool->ops_index);
     362         [ #  # ]:          0 :         if (strncmp(ops->name, platform_ops, RTE_MEMPOOL_OPS_NAMESIZE)) {
     363                 :          0 :                 plt_err("mempool ops should be of cnxk_npa type");
     364                 :          0 :                 goto fail;
     365                 :            :         }
     366                 :            : 
     367         [ #  # ]:          0 :         if (lpb_pool->pool_id == 0) {
     368                 :          0 :                 plt_err("Invalid pool_id");
     369                 :          0 :                 goto fail;
     370                 :            :         }
     371                 :            : 
     372                 :            :         /* Setup ROC CQ */
     373                 :          0 :         cq = &eswitch_dev->cxq[qid].cqs;
     374                 :            :         memset(cq, 0, sizeof(struct roc_nix_cq));
     375                 :          0 :         cq->qid = qid;
     376                 :          0 :         cq->nb_desc = nb_desc;
     377                 :          0 :         rc = roc_nix_cq_init(nix, cq);
     378         [ #  # ]:          0 :         if (rc) {
     379                 :          0 :                 plt_err("Failed to init roc cq for rq=%d, rc=%d", qid, rc);
     380                 :          0 :                 goto fail;
     381                 :            :         }
     382                 :          0 :         eswitch_dev->cxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_CONFIGURED;
     383                 :            : 
     384                 :            :         /* Setup ROC RQ */
     385         [ #  # ]:          0 :         rq = &eswitch_dev->rxq[qid].rqs;
     386                 :            :         memset(rq, 0, sizeof(struct roc_nix_rq));
     387                 :          0 :         rq->qid = qid;
     388                 :          0 :         rq->cqid = cq->qid;
     389                 :          0 :         rq->aura_handle = lpb_pool->pool_id;
     390         [ #  # ]:          0 :         rq->flow_tag_width = 32;
     391                 :            :         rq->sso_ena = false;
     392                 :            : 
     393                 :            :         /* Calculate first mbuf skip */
     394                 :            :         first_skip = (sizeof(struct rte_mbuf));
     395                 :            :         first_skip += RTE_PKTMBUF_HEADROOM;
     396                 :          0 :         first_skip += rte_pktmbuf_priv_size(lpb_pool);
     397                 :          0 :         rq->first_skip = first_skip;
     398                 :          0 :         rq->later_skip = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(lpb_pool);
     399         [ #  # ]:          0 :         rq->lpb_size = lpb_pool->elt_size;
     400         [ #  # ]:          0 :         if (roc_errata_nix_no_meta_aura())
     401                 :          0 :                 rq->lpb_drop_ena = true;
     402                 :            : 
     403                 :          0 :         rc = roc_nix_rq_init(nix, rq, true);
     404         [ #  # ]:          0 :         if (rc) {
     405                 :          0 :                 plt_err("Failed to init roc rq for rq=%d, rc=%d", qid, rc);
     406                 :          0 :                 goto cq_fini;
     407                 :            :         }
     408                 :          0 :         eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_CONFIGURED;
     409                 :            : 
     410                 :          0 :         return 0;
     411                 :            : cq_fini:
     412                 :          0 :         rc |= roc_nix_cq_fini(cq);
     413                 :            : fail:
     414                 :            :         return rc;
     415                 :            : }
     416                 :            : 
     417                 :            : int
     418                 :          0 : cnxk_eswitch_txq_release(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
     419                 :            : {
     420                 :            :         struct roc_nix_sq *sq;
     421                 :            :         int rc = 0;
     422                 :            : 
     423         [ #  # ]:          0 :         if (eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
     424                 :            :                 return 0;
     425                 :            : 
     426                 :            :         /* Cleanup ROC SQ */
     427                 :          0 :         sq = &eswitch_dev->txq[qid].sqs;
     428                 :          0 :         rc = roc_nix_sq_fini(sq);
     429         [ #  # ]:          0 :         if (rc) {
     430                 :          0 :                 plt_err("Failed to cleanup sq, rc=%d", rc);
     431                 :          0 :                 goto fail;
     432                 :            :         }
     433                 :            : 
     434                 :          0 :         eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_RELEASED;
     435                 :            : fail:
     436                 :            :         return rc;
     437                 :            : }
     438                 :            : 
     439                 :            : int
     440                 :          0 : cnxk_eswitch_txq_setup(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid, uint16_t nb_desc,
     441                 :            :                        const struct rte_eth_txconf *tx_conf)
     442                 :            : {
     443                 :            :         struct roc_nix_sq *sq;
     444                 :            :         int rc = 0;
     445                 :            : 
     446         [ #  # ]:          0 :         if (eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_RELEASED) {
     447                 :          0 :                 plt_err("Queue %d is in invalid state %d, cannot be setup", qid,
     448                 :            :                         eswitch_dev->txq[qid].state);
     449                 :            :                 rc = -EINVAL;
     450                 :          0 :                 goto fail;
     451                 :            :         }
     452                 :            :         RTE_SET_USED(tx_conf);
     453                 :            :         /* Setup ROC SQ */
     454         [ #  # ]:          0 :         sq = &eswitch_dev->txq[qid].sqs;
     455                 :            :         memset(sq, 0, sizeof(struct roc_nix_sq));
     456                 :          0 :         sq->qid = qid;
     457                 :          0 :         sq->nb_desc = nb_desc;
     458                 :            :         sq->max_sqe_sz = NIX_MAXSQESZ_W16;
     459         [ #  # ]:          0 :         if (sq->nb_desc >= CNXK_NIX_DEF_SQ_COUNT)
     460                 :          0 :                 sq->fc_hyst_bits = 0x1;
     461                 :            : 
     462                 :          0 :         rc = roc_nix_sq_init(&eswitch_dev->nix, sq);
     463         [ #  # ]:          0 :         if (rc)
     464                 :          0 :                 plt_err("Failed to init sq=%d, rc=%d", qid, rc);
     465                 :            : 
     466                 :          0 :         eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_CONFIGURED;
     467                 :            : 
     468                 :          0 : fail:
     469                 :          0 :         return rc;
     470                 :            : }
     471                 :            : 
     472                 :            : static int
     473                 :          0 : nix_lf_setup(struct cnxk_eswitch_dev *eswitch_dev)
     474                 :            : {
     475                 :            :         uint16_t nb_rxq, nb_txq, nb_cq;
     476                 :            :         struct roc_nix_fc_cfg fc_cfg;
     477                 :            :         struct roc_nix *nix;
     478                 :            :         uint64_t rx_cfg;
     479                 :            :         void *qs;
     480                 :            :         int rc;
     481                 :            : 
     482                 :            :         /* Initialize base roc nix */
     483                 :          0 :         nix = &eswitch_dev->nix;
     484                 :          0 :         nix->pci_dev = eswitch_dev->pci_dev;
     485                 :          0 :         nix->hw_vlan_ins = true;
     486                 :          0 :         nix->reta_sz = ROC_NIX_RSS_RETA_SZ_256;
     487                 :          0 :         rc = roc_nix_dev_init(nix);
     488         [ #  # ]:          0 :         if (rc) {
     489                 :          0 :                 plt_err("Failed to init nix eswitch device, rc=%d(%s)", rc, roc_error_msg_get(rc));
     490                 :          0 :                 goto fail;
     491                 :            :         }
     492                 :            : 
     493                 :            :         /* Get the representors count */
     494                 :          0 :         rc = roc_nix_max_rep_count(&eswitch_dev->nix);
     495         [ #  # ]:          0 :         if (rc) {
     496                 :          0 :                 plt_err("Failed to get rep cnt, rc=%d(%s)", rc, roc_error_msg_get(rc));
     497                 :          0 :                 goto free_cqs;
     498                 :            :         }
     499                 :          0 :         eswitch_dev->repr_cnt.max_repr = eswitch_dev->nix.rep_cnt;
     500                 :            : 
     501                 :            :         /* Allocating an NIX LF */
     502                 :            :         nb_rxq = CNXK_ESWITCH_MAX_RXQ;
     503                 :            :         nb_txq = CNXK_ESWITCH_MAX_TXQ;
     504                 :            :         nb_cq = CNXK_ESWITCH_MAX_RXQ;
     505                 :            :         rx_cfg = ROC_NIX_LF_RX_CFG_DIS_APAD;
     506                 :          0 :         rc = roc_nix_lf_alloc(nix, nb_rxq, nb_txq, rx_cfg);
     507         [ #  # ]:          0 :         if (rc) {
     508                 :          0 :                 plt_err("lf alloc failed = %s(%d)", roc_error_msg_get(rc), rc);
     509                 :          0 :                 goto dev_fini;
     510                 :            :         }
     511                 :            : 
     512                 :            :         if (nb_rxq) {
     513                 :            :                 /* Allocate memory for eswitch rq's and cq's */
     514                 :          0 :                 qs = plt_zmalloc(sizeof(struct cnxk_eswitch_rxq) * nb_rxq, 0);
     515         [ #  # ]:          0 :                 if (!qs) {
     516                 :          0 :                         plt_err("Failed to alloc eswitch rxq");
     517                 :          0 :                         goto lf_free;
     518                 :            :                 }
     519                 :          0 :                 eswitch_dev->rxq = qs;
     520                 :            :         }
     521                 :            : 
     522                 :            :         if (nb_txq) {
     523                 :            :                 /* Allocate memory for roc sq's */
     524                 :          0 :                 qs = plt_zmalloc(sizeof(struct cnxk_eswitch_txq) * nb_txq, 0);
     525         [ #  # ]:          0 :                 if (!qs) {
     526                 :          0 :                         plt_err("Failed to alloc eswitch txq");
     527                 :          0 :                         goto free_rqs;
     528                 :            :                 }
     529                 :          0 :                 eswitch_dev->txq = qs;
     530                 :            :         }
     531                 :            : 
     532                 :            :         if (nb_cq) {
     533                 :          0 :                 qs = plt_zmalloc(sizeof(struct cnxk_eswitch_cxq) * nb_cq, 0);
     534         [ #  # ]:          0 :                 if (!qs) {
     535                 :          0 :                         plt_err("Failed to alloc eswitch cxq");
     536                 :          0 :                         goto free_sqs;
     537                 :            :                 }
     538                 :          0 :                 eswitch_dev->cxq = qs;
     539                 :            :         }
     540                 :            : 
     541                 :          0 :         eswitch_dev->nb_rxq = nb_rxq;
     542                 :          0 :         eswitch_dev->nb_txq = nb_txq;
     543                 :            : 
     544                 :            :         /* Re-enable NIX LF error interrupts */
     545                 :          0 :         roc_nix_err_intr_ena_dis(nix, true);
     546                 :          0 :         roc_nix_ras_intr_ena_dis(nix, true);
     547                 :            : 
     548                 :          0 :         rc = roc_nix_lso_fmt_setup(nix);
     549         [ #  # ]:          0 :         if (rc) {
     550                 :          0 :                 plt_err("lso setup failed = %s(%d)", roc_error_msg_get(rc), rc);
     551                 :          0 :                 goto free_cqs;
     552                 :            :         }
     553                 :            : 
     554                 :          0 :         rc = roc_nix_switch_hdr_set(nix, 0, 0, 0, 0);
     555         [ #  # ]:          0 :         if (rc) {
     556                 :          0 :                 plt_err("switch hdr set failed = %s(%d)", roc_error_msg_get(rc), rc);
     557                 :          0 :                 goto free_cqs;
     558                 :            :         }
     559                 :            : 
     560                 :          0 :         rc = roc_nix_tm_init(nix);
     561         [ #  # ]:          0 :         if (rc) {
     562                 :          0 :                 plt_err("tm failed = %s(%d)", roc_error_msg_get(rc), rc);
     563                 :          0 :                 goto free_cqs;
     564                 :            :         }
     565                 :            : 
     566                 :            :         /* Register queue IRQs */
     567                 :          0 :         rc = roc_nix_register_queue_irqs(nix);
     568         [ #  # ]:          0 :         if (rc) {
     569                 :          0 :                 plt_err("Failed to register queue interrupts rc=%d", rc);
     570                 :          0 :                 goto tm_fini;
     571                 :            :         }
     572                 :            : 
     573                 :            :         /* Enable default tree */
     574                 :          0 :         rc = roc_nix_tm_hierarchy_enable(nix, ROC_NIX_TM_DEFAULT, false);
     575         [ #  # ]:          0 :         if (rc) {
     576                 :          0 :                 plt_err("tm default hierarchy enable failed = %s(%d)", roc_error_msg_get(rc), rc);
     577                 :          0 :                 goto q_irq_fini;
     578                 :            :         }
     579                 :            : 
     580                 :            :         memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
     581                 :            :         fc_cfg.rxchan_cfg.enable = false;
     582                 :          0 :         rc = roc_nix_fc_config_set(nix, &fc_cfg);
     583         [ #  # ]:          0 :         if (rc) {
     584                 :          0 :                 plt_err("Failed to setup flow control, rc=%d(%s)", rc, roc_error_msg_get(rc));
     585                 :          0 :                 goto q_irq_fini;
     586                 :            :         }
     587                 :            : 
     588                 :          0 :         roc_nix_fc_mode_get(nix);
     589                 :            : 
     590                 :          0 :         return rc;
     591                 :          0 : q_irq_fini:
     592                 :          0 :         roc_nix_unregister_queue_irqs(nix);
     593                 :          0 : tm_fini:
     594                 :          0 :         roc_nix_tm_fini(nix);
     595                 :          0 : free_cqs:
     596                 :          0 :         rte_free(eswitch_dev->cxq);
     597                 :          0 : free_sqs:
     598                 :          0 :         rte_free(eswitch_dev->txq);
     599                 :          0 : free_rqs:
     600                 :          0 :         rte_free(eswitch_dev->rxq);
     601                 :          0 : lf_free:
     602                 :          0 :         roc_nix_lf_free(nix);
     603                 :          0 : dev_fini:
     604                 :          0 :         roc_nix_dev_fini(nix);
     605                 :            : fail:
     606                 :            :         return rc;
     607                 :            : }
     608                 :            : 
     609                 :            : static int
     610                 :          0 : eswitch_hw_rsrc_setup(struct cnxk_eswitch_dev *eswitch_dev, struct rte_pci_device *pci_dev)
     611                 :            : {
     612                 :            :         struct roc_nix *nix;
     613                 :            :         int rc;
     614                 :            : 
     615                 :          0 :         nix = &eswitch_dev->nix;
     616                 :          0 :         rc = nix_lf_setup(eswitch_dev);
     617         [ #  # ]:          0 :         if (rc) {
     618                 :          0 :                 plt_err("Failed to setup hw rsrc, rc=%d(%s)", rc, roc_error_msg_get(rc));
     619                 :          0 :                 goto fail;
     620                 :            :         }
     621                 :            : 
     622                 :            :         /* Initialize roc npc */
     623                 :          0 :         eswitch_dev->npc.roc_nix = nix;
     624                 :          0 :         eswitch_dev->npc.flow_max_priority = 3;
     625                 :          0 :         eswitch_dev->npc.flow_prealloc_size = 1;
     626                 :          0 :         rc = roc_npc_init(&eswitch_dev->npc);
     627         [ #  # ]:          0 :         if (rc)
     628                 :          0 :                 goto rsrc_cleanup;
     629                 :            : 
     630                 :            :         /* List for eswitch default flows */
     631                 :          0 :         TAILQ_INIT(&eswitch_dev->esw_flow_list);
     632                 :            : 
     633                 :          0 :         return rc;
     634                 :            : rsrc_cleanup:
     635                 :          0 :         eswitch_hw_rsrc_cleanup(eswitch_dev, pci_dev);
     636                 :            : fail:
     637                 :            :         return rc;
     638                 :            : }
     639                 :            : 
     640                 :            : int
     641                 :          0 : cnxk_eswitch_representor_info_get(struct cnxk_eswitch_dev *eswitch_dev,
     642                 :            :                                   struct rte_eth_representor_info *info)
     643                 :            : {
     644                 :            :         struct cnxk_eswitch_devargs *esw_da;
     645                 :            :         int rc = 0, n_entries, i, j = 0, k = 0;
     646                 :            : 
     647         [ #  # ]:          0 :         for (i = 0; i < eswitch_dev->nb_esw_da; i++) {
     648         [ #  # ]:          0 :                 for (j = 0; j < eswitch_dev->esw_da[i].nb_repr_ports; j++)
     649                 :          0 :                         k++;
     650                 :            :         }
     651                 :            :         n_entries = k;
     652                 :            : 
     653         [ #  # ]:          0 :         if (info == NULL)
     654                 :          0 :                 goto out;
     655                 :            : 
     656                 :            :         if ((uint32_t)n_entries > info->nb_ranges_alloc)
     657                 :            :                 n_entries = info->nb_ranges_alloc;
     658                 :            : 
     659                 :            :         k = 0;
     660                 :          0 :         info->controller = 0;
     661                 :          0 :         info->pf = 0;
     662         [ #  # ]:          0 :         for (i = 0; i < eswitch_dev->nb_esw_da; i++) {
     663                 :            :                 esw_da = &eswitch_dev->esw_da[i];
     664                 :          0 :                 info->ranges[k].type = esw_da->da.type;
     665      [ #  #  # ]:          0 :                 switch (esw_da->da.type) {
     666                 :          0 :                 case RTE_ETH_REPRESENTOR_PF:
     667                 :          0 :                         info->ranges[k].controller = 0;
     668                 :          0 :                         info->ranges[k].pf = esw_da->repr_hw_info[0].pfvf;
     669                 :          0 :                         info->ranges[k].vf = 0;
     670                 :          0 :                         info->ranges[k].id_base = info->ranges[i].pf;
     671                 :          0 :                         info->ranges[k].id_end = info->ranges[i].pf;
     672                 :          0 :                         snprintf(info->ranges[k].name, sizeof(info->ranges[k].name), "pf%d",
     673                 :            :                                  info->ranges[k].pf);
     674                 :          0 :                         k++;
     675                 :          0 :                         break;
     676                 :            :                 case RTE_ETH_REPRESENTOR_VF:
     677         [ #  # ]:          0 :                         for (j = 0; j < esw_da->nb_repr_ports; j++) {
     678                 :          0 :                                 info->ranges[k].controller = 0;
     679                 :          0 :                                 info->ranges[k].pf = esw_da->da.ports[0];
     680                 :          0 :                                 info->ranges[k].vf = esw_da->repr_hw_info[j].pfvf;
     681                 :          0 :                                 info->ranges[k].id_base = esw_da->repr_hw_info[j].port_id;
     682                 :          0 :                                 info->ranges[k].id_end = esw_da->repr_hw_info[j].port_id;
     683                 :          0 :                                 snprintf(info->ranges[k].name, sizeof(info->ranges[k].name),
     684                 :            :                                          "pf%dvf%d", info->ranges[k].pf, info->ranges[k].vf);
     685                 :          0 :                                 k++;
     686                 :            :                         }
     687                 :            :                         break;
     688                 :          0 :                 default:
     689                 :          0 :                         plt_err("Invalid type %d", esw_da->da.type);
     690                 :            :                         rc = 0;
     691                 :          0 :                         goto fail;
     692                 :            :                 };
     693                 :            :         }
     694                 :          0 :         info->nb_ranges = k;
     695                 :            : fail:
     696                 :            :         return rc;
     697                 :            : out:
     698                 :          0 :         return n_entries;
     699                 :            : }
     700                 :            : 
     701                 :            : static int
     702                 :          0 : cnxk_eswitch_dev_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
     703                 :            : {
     704                 :            :         struct cnxk_eswitch_dev *eswitch_dev;
     705                 :            :         const struct rte_memzone *mz = NULL;
     706                 :            :         uint16_t num_reps;
     707                 :            :         int rc = -ENOMEM;
     708                 :            : 
     709                 :            :         RTE_SET_USED(pci_drv);
     710                 :            : 
     711                 :            :         eswitch_dev = cnxk_eswitch_pmd_priv();
     712         [ #  # ]:          0 :         if (!eswitch_dev) {
     713                 :          0 :                 rc = roc_plt_init();
     714         [ #  # ]:          0 :                 if (rc) {
     715                 :          0 :                         plt_err("Failed to initialize platform model, rc=%d", rc);
     716                 :          0 :                         return rc;
     717                 :            :                 }
     718                 :            : 
     719         [ #  # ]:          0 :                 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     720                 :            :                         return 0;
     721                 :            : 
     722                 :          0 :                 mz = rte_memzone_reserve_aligned(CNXK_REP_ESWITCH_DEV_MZ, sizeof(*eswitch_dev),
     723                 :            :                                                  SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
     724         [ #  # ]:          0 :                 if (mz == NULL) {
     725                 :          0 :                         plt_err("Failed to reserve a memzone");
     726                 :          0 :                         goto fail;
     727                 :            :                 }
     728                 :            : 
     729                 :          0 :                 eswitch_dev = mz->addr;
     730                 :          0 :                 eswitch_dev->pci_dev = pci_dev;
     731                 :            : 
     732                 :          0 :                 rc = eswitch_hw_rsrc_setup(eswitch_dev, pci_dev);
     733         [ #  # ]:          0 :                 if (rc) {
     734                 :          0 :                         plt_err("Failed to setup hw rsrc, rc=%d(%s)", rc, roc_error_msg_get(rc));
     735                 :          0 :                         goto free_mem;
     736                 :            :                 }
     737                 :            :         }
     738                 :            : 
     739         [ #  # ]:          0 :         if (pci_dev->device.devargs) {
     740                 :          0 :                 rc = cnxk_eswitch_repr_devargs(pci_dev, eswitch_dev);
     741         [ #  # ]:          0 :                 if (rc)
     742                 :          0 :                         goto rsrc_cleanup;
     743                 :            :         }
     744                 :            : 
     745         [ #  # ]:          0 :         if (eswitch_dev->repr_cnt.nb_repr_created > eswitch_dev->repr_cnt.max_repr) {
     746                 :          0 :                 plt_err("Representors to be created %d can be greater than max allowed %d",
     747                 :            :                         eswitch_dev->repr_cnt.nb_repr_created, eswitch_dev->repr_cnt.max_repr);
     748                 :            :                 rc = -EINVAL;
     749                 :          0 :                 goto rsrc_cleanup;
     750                 :            :         }
     751                 :            : 
     752                 :            :         num_reps = eswitch_dev->repr_cnt.nb_repr_created;
     753         [ #  # ]:          0 :         if (!num_reps) {
     754                 :          0 :                 plt_err("No representors enabled");
     755                 :          0 :                 goto fail;
     756                 :            :         }
     757                 :            : 
     758                 :          0 :         plt_esw_dbg("Max no of reps %d reps to be created %d Eswtch pfunc %x",
     759                 :            :                     eswitch_dev->repr_cnt.max_repr, eswitch_dev->repr_cnt.nb_repr_created,
     760                 :            :                     roc_nix_get_pf_func(&eswitch_dev->nix));
     761                 :            : 
     762                 :            :         /* Probe representor ports */
     763                 :          0 :         rc = cnxk_rep_dev_probe(pci_dev, eswitch_dev);
     764         [ #  # ]:          0 :         if (rc) {
     765                 :          0 :                 plt_err("Failed to probe representor ports");
     766                 :          0 :                 goto rsrc_cleanup;
     767                 :            :         }
     768                 :            : 
     769                 :            :         /* Spinlock for synchronization between representors traffic and control
     770                 :            :          * messages
     771                 :            :          */
     772                 :            :         rte_spinlock_init(&eswitch_dev->rep_lock);
     773                 :            : 
     774                 :          0 :         return rc;
     775                 :          0 : rsrc_cleanup:
     776                 :          0 :         eswitch_hw_rsrc_cleanup(eswitch_dev, pci_dev);
     777                 :          0 : free_mem:
     778                 :          0 :         rte_memzone_free(mz);
     779                 :            : fail:
     780                 :            :         return rc;
     781                 :            : }
     782                 :            : 
     783                 :            : static const struct rte_pci_id cnxk_eswitch_pci_map[] = {
     784                 :            :         {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_RVU_ESWITCH_PF)},
     785                 :            :         {
     786                 :            :                 .vendor_id = 0,
     787                 :            :         },
     788                 :            : };
     789                 :            : 
     790                 :            : static struct rte_pci_driver cnxk_eswitch_pci = {
     791                 :            :         .id_table = cnxk_eswitch_pci_map,
     792                 :            :         .drv_flags =
     793                 :            :                 RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA | RTE_PCI_DRV_PROBE_AGAIN,
     794                 :            :         .probe = cnxk_eswitch_dev_probe,
     795                 :            :         .remove = cnxk_eswitch_dev_remove,
     796                 :            : };
     797                 :            : 
     798                 :        252 : RTE_PMD_REGISTER_PCI(cnxk_eswitch, cnxk_eswitch_pci);
     799                 :            : RTE_PMD_REGISTER_PCI_TABLE(cnxk_eswitch, cnxk_eswitch_pci_map);
     800                 :            : RTE_PMD_REGISTER_KMOD_DEP(cnxk_eswitch, "vfio-pci");

Generated by: LCOV version 1.14