LCOV - code coverage report
Current view: top level - drivers/net/cnxk - cnxk_eswitch_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 227 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 9 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 94 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                 :            : 
       9                 :            : const uint8_t eswitch_vlan_rss_key[ROC_NIX_RSS_KEY_LEN] = {
      10                 :            :         0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
      11                 :            :         0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
      12                 :            :         0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
      13                 :            :         0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
      14                 :            :         0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
      15                 :            :         0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE};
      16                 :            : 
      17                 :            : int
      18                 :          0 : cnxk_eswitch_flow_rules_remove_list(struct cnxk_eswitch_dev *eswitch_dev, struct flow_list *list,
      19                 :            :                                     uint16_t hw_func)
      20                 :            : {
      21                 :            :         struct roc_npc_flow *flow, *tvar;
      22                 :            :         int rc = 0;
      23                 :            : 
      24         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(flow, list, next, tvar) {
      25                 :          0 :                 plt_esw_dbg("Removing flow %d", flow->mcam_id);
      26                 :          0 :                 rc = roc_eswitch_npc_mcam_delete_rule(&eswitch_dev->npc, flow,
      27                 :            :                                                       hw_func);
      28         [ #  # ]:          0 :                 if (rc)
      29                 :          0 :                         plt_err("Failed to delete rule %d", flow->mcam_id);
      30                 :          0 :                 rc = roc_npc_mcam_free(&eswitch_dev->npc, flow);
      31         [ #  # ]:          0 :                 if (rc)
      32                 :          0 :                         plt_err("Failed to free entry %d", flow->mcam_id);
      33         [ #  # ]:          0 :                 TAILQ_REMOVE(list, flow, next);
      34                 :          0 :                 rte_free(flow);
      35                 :            :         }
      36                 :            : 
      37                 :          0 :         return rc;
      38                 :            : }
      39                 :            : 
      40                 :            : static int
      41                 :          0 : eswitch_npc_vlan_rss_configure(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
      42                 :            : {
      43                 :          0 :         struct roc_nix *roc_nix = roc_npc->roc_nix;
      44                 :            :         uint32_t qid, idx, hash, vlan_tci;
      45                 :            :         uint16_t *reta, reta_sz, id;
      46                 :            :         int rc = 0;
      47                 :            : 
      48                 :          0 :         id = flow->mcam_id;
      49                 :            :         /* Setting up the key */
      50                 :          0 :         roc_nix_rss_key_set(roc_nix, eswitch_vlan_rss_key);
      51                 :            : 
      52                 :          0 :         reta_sz = roc_nix->reta_sz;
      53                 :          0 :         reta = plt_zmalloc(reta_sz * sizeof(uint16_t), 0);
      54         [ #  # ]:          0 :         if (!reta) {
      55                 :          0 :                 plt_err("Failed to allocate mem for reta table");
      56                 :            :                 rc = -ENOMEM;
      57                 :          0 :                 goto fail;
      58                 :            :         }
      59         [ #  # ]:          0 :         for (qid = 0; qid < reta_sz; qid++) {
      60                 :          0 :                 vlan_tci = (1 << CNXK_ESWITCH_VFPF_SHIFT) | qid;
      61                 :          0 :                 hash = rte_softrss(&vlan_tci, 1, eswitch_vlan_rss_key);
      62                 :          0 :                 idx = hash & 0xFF;
      63                 :          0 :                 reta[idx] = qid;
      64                 :            :         }
      65                 :          0 :         flow->mcam_id = id;
      66                 :          0 :         rc = roc_eswitch_npc_rss_action_configure(roc_npc, flow, FLOW_KEY_TYPE_VLAN, reta);
      67         [ #  # ]:          0 :         if (rc) {
      68                 :          0 :                 plt_err("Failed to configure rss action, err %d", rc);
      69                 :          0 :                 goto done;
      70                 :            :         }
      71                 :            : 
      72                 :          0 : done:
      73                 :          0 :         plt_free(reta);
      74                 :          0 : fail:
      75                 :          0 :         return rc;
      76                 :            : }
      77                 :            : 
      78                 :            : static int
      79                 :          0 : eswitch_pfvf_mcam_install_rules(struct cnxk_eswitch_dev *eswitch_dev, struct roc_npc_flow *flow,
      80                 :            :                                 bool is_vf)
      81                 :            : {
      82                 :            :         uint16_t vlan_tci = 0, hw_func;
      83                 :            :         int rc;
      84                 :            : 
      85                 :          0 :         hw_func = eswitch_dev->npc.pf_func | is_vf;
      86         [ #  # ]:          0 :         if (!is_vf) {
      87                 :            :                 /* Eswitch PF RX VLAN rule */
      88                 :            :                 vlan_tci = 1ULL << CNXK_ESWITCH_VFPF_SHIFT;
      89                 :          0 :                 rc = roc_eswitch_npc_mcam_rx_rule(&eswitch_dev->npc, flow, hw_func, vlan_tci,
      90                 :            :                                                   0xFF00);
      91         [ #  # ]:          0 :                 if (rc) {
      92                 :          0 :                         plt_err("Failed to install RX rule for ESW PF to ESW VF, rc %d", rc);
      93                 :          0 :                         goto exit;
      94                 :            :                 }
      95                 :          0 :                 plt_esw_dbg("Installed eswitch PF RX rule %d", flow->mcam_id);
      96                 :          0 :                 rc = eswitch_npc_vlan_rss_configure(&eswitch_dev->npc, flow);
      97         [ #  # ]:          0 :                 if (rc)
      98                 :          0 :                         goto exit;
      99                 :          0 :                 flow->enable = true;
     100                 :            :         } else {
     101                 :            :                 /* Eswitch VF RX VLAN rule */
     102                 :          0 :                 rc = roc_eswitch_npc_mcam_rx_rule(&eswitch_dev->npc, flow, hw_func, vlan_tci,
     103                 :            :                                                   0xFF00);
     104         [ #  # ]:          0 :                 if (rc) {
     105                 :          0 :                         plt_err("Failed to install RX rule for ESW VF to ESW PF, rc %d", rc);
     106                 :          0 :                         goto exit;
     107                 :            :                 }
     108                 :          0 :                 flow->enable = true;
     109                 :          0 :                 plt_esw_dbg("Installed eswitch PF RX rule %d", flow->mcam_id);
     110                 :            :         }
     111                 :            : 
     112                 :            :         return 0;
     113                 :            : exit:
     114                 :            :         return rc;
     115                 :            : }
     116                 :            : 
     117                 :            : static int
     118                 :          0 : eswitch_npc_get_counter(struct roc_npc *npc, struct roc_npc_flow *flow)
     119                 :            : {
     120                 :            :         uint16_t ctr_id;
     121                 :            :         int rc;
     122                 :            : 
     123                 :          0 :         rc = roc_npc_mcam_alloc_counter(npc, &ctr_id);
     124         [ #  # ]:          0 :         if (rc < 0) {
     125                 :          0 :                 plt_err("Failed to allocate counter, rc %d", rc);
     126                 :          0 :                 goto fail;
     127                 :            :         }
     128                 :          0 :         flow->ctr_id = ctr_id;
     129                 :          0 :         flow->use_ctr = true;
     130                 :            : 
     131                 :          0 :         rc = roc_npc_mcam_clear_counter(npc, flow->ctr_id);
     132         [ #  # ]:          0 :         if (rc < 0) {
     133                 :          0 :                 plt_err("Failed to clear counter idx %d, rc %d", flow->ctr_id, rc);
     134                 :          0 :                 goto free;
     135                 :            :         }
     136                 :            :         return 0;
     137                 :            : free:
     138                 :          0 :         roc_npc_mcam_free_counter(npc, ctr_id);
     139                 :            : fail:
     140                 :            :         return rc;
     141                 :            : }
     142                 :            : 
     143                 :            : static int
     144                 :          0 : eswitch_npc_get_counter_entry_ref(struct roc_npc *npc, struct roc_npc_flow *flow,
     145                 :            :                                   struct roc_npc_flow *ref_flow)
     146                 :            : {
     147                 :            :         int rc = 0, resp_count;
     148                 :            : 
     149                 :          0 :         rc = eswitch_npc_get_counter(npc, flow);
     150         [ #  # ]:          0 :         if (rc)
     151                 :          0 :                 goto free;
     152                 :            : 
     153                 :            :         /* Allocate an entry viz higher priority than ref flow */
     154                 :          0 :         rc = roc_npc_mcam_alloc_entry(npc, flow, ref_flow, NPC_MCAM_HIGHER_PRIO, &resp_count);
     155         [ #  # ]:          0 :         if (rc) {
     156                 :          0 :                 plt_err("Failed to allocate entry, err %d", rc);
     157                 :          0 :                 goto free;
     158                 :            :         }
     159                 :          0 :         plt_esw_dbg("New entry %d ref entry %d resp_count %d", flow->mcam_id, ref_flow->mcam_id,
     160                 :            :                     resp_count);
     161                 :            : 
     162                 :          0 :         return 0;
     163                 :          0 : free:
     164                 :          0 :         roc_npc_mcam_free_counter(npc, flow->ctr_id);
     165                 :          0 :         return rc;
     166                 :            : }
     167                 :            : 
     168                 :            : int
     169                 :          0 : cnxk_eswitch_flow_rule_shift(uint16_t hw_func, uint16_t *entry)
     170                 :            : {
     171                 :            :         struct cnxk_esw_repr_hw_info *repr_info;
     172                 :            :         struct cnxk_eswitch_dev *eswitch_dev;
     173                 :            :         struct roc_npc_flow *ref_flow, *flow;
     174                 :            :         uint16_t curr_entry, new_entry;
     175                 :            :         int rc = 0, resp_count;
     176                 :            : 
     177                 :            :         eswitch_dev = cnxk_eswitch_pmd_priv();
     178                 :            :         if (!eswitch_dev) {
     179                 :          0 :                 plt_err("Invalid eswitch_dev handle");
     180                 :            :                 rc = -EINVAL;
     181                 :          0 :                 goto fail;
     182                 :            :         }
     183                 :            : 
     184                 :          0 :         repr_info = cnxk_eswitch_representor_hw_info(eswitch_dev, hw_func);
     185         [ #  # ]:          0 :         if (!repr_info) {
     186                 :          0 :                 plt_warn("Failed to get representor group for %x", hw_func);
     187                 :            :                 rc = -ENOENT;
     188                 :          0 :                 goto fail;
     189                 :            :         }
     190                 :            : 
     191                 :          0 :         ref_flow = TAILQ_FIRST(&repr_info->repr_flow_list);
     192         [ #  # ]:          0 :         if (*entry > ref_flow->mcam_id) {
     193                 :          0 :                 flow = plt_zmalloc(sizeof(struct roc_npc_flow), 0);
     194         [ #  # ]:          0 :                 if (!flow) {
     195                 :          0 :                         plt_err("Failed to allocate memory");
     196                 :            :                         rc = -ENOMEM;
     197                 :          0 :                         goto fail;
     198                 :            :                 }
     199                 :            : 
     200                 :            :                 /* Allocate a higher priority flow rule */
     201                 :          0 :                 rc = roc_npc_mcam_alloc_entry(&eswitch_dev->npc, flow, ref_flow,
     202                 :            :                                               NPC_MCAM_HIGHER_PRIO, &resp_count);
     203         [ #  # ]:          0 :                 if (rc < 0) {
     204                 :          0 :                         plt_err("Failed to allocate a newmcam entry, rc %d", rc);
     205                 :          0 :                         goto fail;
     206                 :            :                 }
     207                 :            : 
     208         [ #  # ]:          0 :                 if (flow->mcam_id > ref_flow->mcam_id) {
     209                 :          0 :                         plt_err("New flow %d is still at higher priority than ref_flow %d",
     210                 :            :                                 flow->mcam_id, ref_flow->mcam_id);
     211                 :            :                         rc = -EINVAL;
     212                 :          0 :                         goto free_entry;
     213                 :            :                 }
     214                 :            : 
     215                 :          0 :                 plt_info("Before shift: HW_func %x curr_entry %d ref flow id %d new_entry %d",
     216                 :            :                          hw_func, *entry, ref_flow->mcam_id, flow->mcam_id);
     217                 :            : 
     218                 :          0 :                 curr_entry = *entry;
     219                 :          0 :                 new_entry = flow->mcam_id;
     220                 :            : 
     221                 :          0 :                 rc = roc_npc_mcam_move(&eswitch_dev->npc, curr_entry, new_entry);
     222         [ #  # ]:          0 :                 if (rc) {
     223                 :          0 :                         plt_err("Failed to shift the new index %d to curr index %d, err    %d", *entry,
     224                 :            :                                 curr_entry, rc);
     225                 :          0 :                         goto free_entry;
     226                 :            :                 }
     227                 :          0 :                 *entry = flow->mcam_id;
     228                 :            : 
     229                 :            :                 /* Freeing the current entry */
     230                 :          0 :                 rc = roc_npc_mcam_free_entry(&eswitch_dev->npc, curr_entry);
     231         [ #  # ]:          0 :                 if (rc) {
     232                 :          0 :                         plt_err("Failed to free the old entry. err %d", rc);
     233                 :          0 :                         goto free_entry;
     234                 :            :                 }
     235                 :            : 
     236                 :          0 :                 plt_free(flow);
     237                 :          0 :                 plt_info("After shift: HW_func %x old_entry %d new_entry %d", hw_func, curr_entry,
     238                 :            :                          *entry);
     239                 :            :         }
     240                 :            : 
     241                 :            :         return 0;
     242                 :            : free_entry:
     243                 :            : 
     244                 :            : fail:
     245                 :            :         return rc;
     246                 :            : }
     247                 :            : 
     248                 :            : int
     249                 :          0 : cnxk_eswitch_flow_rules_delete(struct cnxk_eswitch_dev *eswitch_dev, uint16_t hw_func)
     250                 :            : {
     251                 :            :         struct cnxk_esw_repr_hw_info *repr_info;
     252                 :            :         struct flow_list *list;
     253                 :            :         int rc = 0;
     254                 :            : 
     255                 :          0 :         repr_info = cnxk_eswitch_representor_hw_info(eswitch_dev, hw_func);
     256         [ #  # ]:          0 :         if (!repr_info) {
     257                 :          0 :                 plt_warn("Failed to get representor group for %x", hw_func);
     258                 :            :                 rc = -ENOENT;
     259                 :          0 :                 goto fail;
     260                 :            :         }
     261                 :          0 :         list = &repr_info->repr_flow_list;
     262                 :            : 
     263                 :          0 :         plt_esw_dbg("Deleting flows for %x", hw_func);
     264                 :          0 :         rc = cnxk_eswitch_flow_rules_remove_list(eswitch_dev, list, hw_func);
     265         [ #  # ]:          0 :         if (rc)
     266                 :          0 :                 plt_err("Failed to delete rules for hw func %x", hw_func);
     267                 :            : 
     268                 :          0 : fail:
     269                 :          0 :         return rc;
     270                 :            : }
     271                 :            : 
     272                 :            : int
     273                 :          0 : cnxk_eswitch_flow_rules_install(struct cnxk_eswitch_dev *eswitch_dev, uint16_t hw_func)
     274                 :            : {
     275                 :            :         struct roc_npc_flow *rx_flow, *tx_flow, *flow_iter, *esw_pf_flow = NULL;
     276                 :            :         struct cnxk_esw_repr_hw_info *repr_info;
     277                 :            :         struct flow_list *list;
     278                 :            :         uint16_t vlan_tci;
     279                 :            :         int rc = 0;
     280                 :            : 
     281                 :          0 :         repr_info = cnxk_eswitch_representor_hw_info(eswitch_dev, hw_func);
     282         [ #  # ]:          0 :         if (!repr_info) {
     283                 :          0 :                 plt_err("Failed to get representor group for %x", hw_func);
     284                 :            :                 rc = -EINVAL;
     285                 :          0 :                 goto fail;
     286                 :            :         }
     287                 :            :         list = &repr_info->repr_flow_list;
     288                 :            : 
     289                 :            :         /* Taking ESW PF as reference entry for installing new rules */
     290         [ #  # ]:          0 :         TAILQ_FOREACH(flow_iter, &eswitch_dev->esw_flow_list, next) {
     291         [ #  # ]:          0 :                 if (flow_iter->mcam_id == eswitch_dev->esw_pf_entry) {
     292                 :            :                         esw_pf_flow = flow_iter;
     293                 :            :                         break;
     294                 :            :                 }
     295                 :            :         }
     296                 :            : 
     297         [ #  # ]:          0 :         if (!esw_pf_flow) {
     298                 :          0 :                 plt_err("Failed to get the ESW PF flow");
     299                 :            :                 rc = -EINVAL;
     300                 :          0 :                 goto fail;
     301                 :            :         }
     302                 :            : 
     303                 :            :         /* Installing RX rule */
     304                 :          0 :         rx_flow = plt_zmalloc(sizeof(struct roc_npc_flow), 0);
     305         [ #  # ]:          0 :         if (!rx_flow) {
     306                 :          0 :                 plt_err("Failed to allocate memory");
     307                 :            :                 rc = -ENOMEM;
     308                 :          0 :                 goto fail;
     309                 :            :         }
     310                 :            : 
     311                 :          0 :         rc = eswitch_npc_get_counter_entry_ref(&eswitch_dev->npc, rx_flow, esw_pf_flow);
     312         [ #  # ]:          0 :         if (rc) {
     313                 :          0 :                 plt_err("Failed to get counter and mcam entry, rc %d", rc);
     314                 :          0 :                 goto free_rx_flow;
     315                 :            :         }
     316                 :            : 
     317                 :            :         /* VLAN TCI value for this representee is the rep id from AF driver */
     318                 :          0 :         vlan_tci = repr_info->rep_id;
     319                 :          0 :         rc = roc_eswitch_npc_mcam_rx_rule(&eswitch_dev->npc, rx_flow, hw_func, vlan_tci, 0xFFFF);
     320         [ #  # ]:          0 :         if (rc) {
     321                 :          0 :                 plt_err("Failed to install RX rule for ESW PF to ESW VF, rc %d", rc);
     322                 :          0 :                 goto free_rx_entry;
     323                 :            :         }
     324                 :          0 :         rx_flow->enable = true;
     325                 :            :         /* List in ascending order of mcam entries */
     326         [ #  # ]:          0 :         TAILQ_FOREACH(flow_iter, list, next) {
     327         [ #  # ]:          0 :                 if (flow_iter->mcam_id > rx_flow->mcam_id) {
     328                 :          0 :                         TAILQ_INSERT_BEFORE(flow_iter, rx_flow, next);
     329                 :          0 :                         goto done_rx;
     330                 :            :                 }
     331                 :            :         }
     332                 :          0 :         TAILQ_INSERT_TAIL(list, rx_flow, next);
     333                 :          0 : done_rx:
     334                 :          0 :         repr_info->num_flow_entries++;
     335                 :          0 :         plt_esw_dbg("Installed RX flow rule %d for representee %x with vlan tci %x MCAM id %d",
     336                 :            :                     eswitch_dev->num_entries, hw_func, vlan_tci, rx_flow->mcam_id);
     337                 :            : 
     338                 :            :         /* Installing TX rule */
     339                 :          0 :         tx_flow = plt_zmalloc(sizeof(struct roc_npc_flow), 0);
     340         [ #  # ]:          0 :         if (!tx_flow) {
     341                 :          0 :                 plt_err("Failed to allocate memory");
     342                 :            :                 rc = -ENOMEM;
     343                 :          0 :                 goto remove_rx_rule;
     344                 :            :         }
     345                 :            : 
     346                 :          0 :         rc = eswitch_npc_get_counter_entry_ref(&eswitch_dev->npc, tx_flow, esw_pf_flow);
     347         [ #  # ]:          0 :         if (rc) {
     348                 :          0 :                 plt_err("Failed to get counter and mcam entry, rc %d", rc);
     349                 :          0 :                 goto free_tx_flow;
     350                 :            :         }
     351                 :            : 
     352                 :          0 :         vlan_tci = (1ULL << CNXK_ESWITCH_VFPF_SHIFT) | repr_info->rep_id;
     353                 :          0 :         rc = roc_eswitch_npc_mcam_tx_rule(&eswitch_dev->npc, tx_flow, hw_func, vlan_tci);
     354         [ #  # ]:          0 :         if (rc) {
     355                 :          0 :                 plt_err("Failed to install RX rule for ESW PF to ESW VF, rc %d", rc);
     356                 :          0 :                 goto free_tx_entry;
     357                 :            :         }
     358                 :          0 :         tx_flow->enable = true;
     359                 :            :         /* List in ascending order of mcam entries */
     360         [ #  # ]:          0 :         TAILQ_FOREACH(flow_iter, list, next) {
     361         [ #  # ]:          0 :                 if (flow_iter->mcam_id > tx_flow->mcam_id) {
     362                 :          0 :                         TAILQ_INSERT_BEFORE(flow_iter, tx_flow, next);
     363                 :          0 :                         goto done_tx;
     364                 :            :                 }
     365                 :            :         }
     366                 :          0 :         TAILQ_INSERT_TAIL(list, tx_flow, next);
     367                 :          0 : done_tx:
     368                 :          0 :         repr_info->num_flow_entries++;
     369                 :          0 :         plt_esw_dbg("Installed TX flow rule %d for representee %x with vlan tci %x MCAM id %d",
     370                 :            :                     repr_info->num_flow_entries, hw_func, vlan_tci, tx_flow->mcam_id);
     371                 :            : 
     372                 :          0 :         return 0;
     373                 :            : free_tx_entry:
     374                 :          0 :         roc_npc_mcam_free(&eswitch_dev->npc, tx_flow);
     375                 :          0 : free_tx_flow:
     376                 :          0 :         rte_free(tx_flow);
     377                 :          0 : remove_rx_rule:
     378         [ #  # ]:          0 :         TAILQ_REMOVE(list, rx_flow, next);
     379                 :          0 : free_rx_entry:
     380                 :          0 :         roc_npc_mcam_free(&eswitch_dev->npc, rx_flow);
     381                 :          0 : free_rx_flow:
     382                 :          0 :         rte_free(rx_flow);
     383                 :            : fail:
     384                 :            :         return rc;
     385                 :            : }
     386                 :            : 
     387                 :            : int
     388                 :          0 : cnxk_eswitch_pfvf_flow_rules_install(struct cnxk_eswitch_dev *eswitch_dev, bool is_vf)
     389                 :            : {
     390                 :            :         struct roc_npc_flow *flow, *flow_iter;
     391                 :            :         struct flow_list *list;
     392                 :            :         int rc = 0;
     393                 :            : 
     394                 :          0 :         list = &eswitch_dev->esw_flow_list;
     395                 :          0 :         flow = plt_zmalloc(sizeof(struct roc_npc_flow), 0);
     396         [ #  # ]:          0 :         if (!flow) {
     397                 :          0 :                 plt_err("Failed to allocate memory");
     398                 :            :                 rc = -ENOMEM;
     399                 :          0 :                 goto fail;
     400                 :            :         }
     401                 :            : 
     402                 :          0 :         rc = eswitch_npc_get_counter(&eswitch_dev->npc, flow);
     403         [ #  # ]:          0 :         if (rc) {
     404                 :          0 :                 plt_err("Failed to get counter and mcam entry, rc %d", rc);
     405                 :          0 :                 goto free_flow;
     406                 :            :         }
     407         [ #  # ]:          0 :         if (!is_vf) {
     408                 :            :                 /* Reserving an entry for esw VF but will not be installed */
     409                 :          0 :                 rc = roc_npc_get_free_mcam_entry(&eswitch_dev->npc, flow);
     410         [ #  # ]:          0 :                 if (rc < 0) {
     411                 :          0 :                         plt_err("Failed to allocate entry for vf, err %d", rc);
     412                 :          0 :                         goto free_flow;
     413                 :            :                 }
     414                 :          0 :                 eswitch_dev->esw_vf_entry = flow->mcam_id;
     415                 :            :                 /* Allocate an entry for esw PF */
     416                 :          0 :                 rc = eswitch_npc_get_counter_entry_ref(&eswitch_dev->npc, flow, flow);
     417         [ #  # ]:          0 :                 if (rc) {
     418                 :          0 :                         plt_err("Failed to allocate entry for pf, err %d", rc);
     419                 :          0 :                         goto free_flow;
     420                 :            :                 }
     421                 :          0 :                 eswitch_dev->esw_pf_entry = flow->mcam_id;
     422                 :          0 :                 plt_esw_dbg("Allocated entries for esw: PF %d and VF %d", eswitch_dev->esw_pf_entry,
     423                 :            :                             eswitch_dev->esw_vf_entry);
     424                 :            :         } else {
     425                 :          0 :                 flow->mcam_id = eswitch_dev->esw_vf_entry;
     426                 :            :         }
     427                 :            : 
     428                 :          0 :         rc = eswitch_pfvf_mcam_install_rules(eswitch_dev, flow, is_vf);
     429         [ #  # ]:          0 :         if (rc) {
     430                 :          0 :                 plt_err("Failed to install entries, rc %d", rc);
     431                 :          0 :                 goto free_flow;
     432                 :            :         }
     433                 :            : 
     434                 :            :         /* List in ascending order of mcam entries */
     435         [ #  # ]:          0 :         TAILQ_FOREACH(flow_iter, list, next) {
     436         [ #  # ]:          0 :                 if (flow_iter->mcam_id > flow->mcam_id) {
     437                 :          0 :                         TAILQ_INSERT_BEFORE(flow_iter, flow, next);
     438                 :          0 :                         goto done;
     439                 :            :                 }
     440                 :            :         }
     441                 :          0 :         TAILQ_INSERT_TAIL(list, flow, next);
     442                 :          0 : done:
     443                 :          0 :         eswitch_dev->num_entries++;
     444                 :          0 :         plt_esw_dbg("Installed new eswitch flow rule %d with MCAM id %d", eswitch_dev->num_entries,
     445                 :            :                     flow->mcam_id);
     446                 :            : 
     447                 :          0 :         return 0;
     448                 :            : 
     449                 :          0 : free_flow:
     450                 :          0 :         cnxk_eswitch_flow_rules_remove_list(eswitch_dev, &eswitch_dev->esw_flow_list,
     451                 :          0 :                                             eswitch_dev->npc.pf_func);
     452                 :            : fail:
     453                 :            :         return rc;
     454                 :            : }

Generated by: LCOV version 1.14