LCOV - code coverage report
Current view: top level - drivers/common/cnxk - roc_nix_tm_ops.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 577 0.0 %
Date: 2024-01-22 16:13:49 Functions: 0 26 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 414 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "roc_api.h"
       6                 :            : #include "roc_priv.h"
       7                 :            : 
       8                 :            : int
       9                 :          0 : roc_nix_tm_sq_aura_fc(struct roc_nix_sq *sq, bool enable)
      10                 :            : {
      11                 :            :         struct npa_aq_enq_req *req;
      12                 :            :         struct npa_aq_enq_rsp *rsp;
      13                 :            :         uint64_t aura_handle;
      14                 :            :         struct npa_lf *lf;
      15                 :            :         struct mbox *mbox;
      16                 :            :         int rc = -ENOSPC;
      17                 :            : 
      18         [ #  # ]:          0 :         plt_tm_dbg("Setting SQ %u SQB aura FC to %s", sq->qid,
      19                 :            :                    enable ? "enable" : "disable");
      20                 :            : 
      21                 :          0 :         lf = idev_npa_obj_get();
      22         [ #  # ]:          0 :         if (!lf)
      23                 :            :                 return NPA_ERR_DEVICE_NOT_BOUNDED;
      24                 :            : 
      25                 :          0 :         mbox = mbox_get(lf->mbox);
      26                 :            :         /* Set/clear sqb aura fc_ena */
      27                 :          0 :         aura_handle = sq->aura_handle;
      28                 :          0 :         req = mbox_alloc_msg_npa_aq_enq(mbox);
      29         [ #  # ]:          0 :         if (req == NULL)
      30                 :          0 :                 goto exit;
      31                 :            : 
      32                 :          0 :         req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
      33                 :          0 :         req->ctype = NPA_AQ_CTYPE_AURA;
      34                 :          0 :         req->op = NPA_AQ_INSTOP_WRITE;
      35                 :            :         /* Below is not needed for aura writes but AF driver needs it */
      36                 :            :         /* AF will translate to associated poolctx */
      37                 :          0 :         req->aura.pool_addr = req->aura_id;
      38                 :            : 
      39                 :          0 :         req->aura.fc_ena = enable;
      40         [ #  # ]:          0 :         req->aura_mask.fc_ena = 1;
      41   [ #  #  #  # ]:          0 :         if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp()) {
      42                 :          0 :                 req->aura.fc_stype = 0x0;      /* STF */
      43                 :          0 :                 req->aura_mask.fc_stype = 0x0; /* STF */
      44                 :            :         } else {
      45                 :          0 :                 req->aura.fc_stype = 0x3;      /* STSTP */
      46                 :          0 :                 req->aura_mask.fc_stype = 0x3; /* STSTP */
      47                 :            :         }
      48                 :            : 
      49                 :          0 :         rc = mbox_process(mbox);
      50         [ #  # ]:          0 :         if (rc)
      51                 :          0 :                 goto exit;
      52                 :            : 
      53                 :            :         /* Read back npa aura ctx */
      54                 :          0 :         req = mbox_alloc_msg_npa_aq_enq(mbox);
      55         [ #  # ]:          0 :         if (req == NULL) {
      56                 :            :                 rc = -ENOSPC;
      57                 :          0 :                 goto exit;
      58                 :            :         }
      59                 :            : 
      60                 :          0 :         req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
      61                 :          0 :         req->ctype = NPA_AQ_CTYPE_AURA;
      62                 :          0 :         req->op = NPA_AQ_INSTOP_READ;
      63                 :            : 
      64                 :            :         rc = mbox_process_msg(mbox, (void *)&rsp);
      65         [ #  # ]:          0 :         if (rc)
      66                 :          0 :                 goto exit;
      67                 :            : 
      68                 :            :         /* Init when enabled as there might be no triggers */
      69         [ #  # ]:          0 :         if (enable)
      70                 :          0 :                 *(volatile uint64_t *)sq->fc = rsp->aura.count;
      71                 :            :         else
      72                 :          0 :                 *(volatile uint64_t *)sq->fc = sq->aura_sqb_bufs;
      73                 :            :         /* Sync write barrier */
      74                 :            :         plt_wmb();
      75                 :            :         rc = 0;
      76                 :          0 : exit:
      77                 :            :         mbox_put(mbox);
      78                 :          0 :         return rc;
      79                 :            : }
      80                 :            : 
      81                 :            : int
      82                 :          0 : roc_nix_tm_free_resources(struct roc_nix *roc_nix, bool hw_only)
      83                 :            : {
      84                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
      85                 :            : 
      86         [ #  # ]:          0 :         if (nix->tm_flags & NIX_TM_HIERARCHY_ENA)
      87                 :            :                 return -EBUSY;
      88                 :            : 
      89                 :          0 :         return nix_tm_free_resources(roc_nix, BIT(ROC_NIX_TM_USER), hw_only);
      90                 :            : }
      91                 :            : 
      92                 :            : static int
      93                 :          0 : nix_tm_adjust_shaper_pps_rate(struct nix_tm_shaper_profile *profile)
      94                 :            : {
      95                 :          0 :         uint64_t min_rate = profile->commit.rate;
      96                 :            : 
      97         [ #  # ]:          0 :         if (!profile->pkt_mode)
      98                 :            :                 return 0;
      99                 :            : 
     100                 :          0 :         profile->pkt_mode_adj = 1;
     101                 :            : 
     102         [ #  # ]:          0 :         if (profile->commit.rate &&
     103                 :            :             (profile->commit.rate < NIX_TM_MIN_SHAPER_PPS_RATE ||
     104                 :            :              profile->commit.rate > NIX_TM_MAX_SHAPER_PPS_RATE))
     105                 :            :                 return NIX_ERR_TM_INVALID_COMMIT_RATE;
     106                 :            : 
     107         [ #  # ]:          0 :         if (profile->peak.rate &&
     108                 :            :             (profile->peak.rate < NIX_TM_MIN_SHAPER_PPS_RATE ||
     109                 :            :              profile->peak.rate > NIX_TM_MAX_SHAPER_PPS_RATE))
     110                 :            :                 return NIX_ERR_TM_INVALID_PEAK_RATE;
     111                 :            : 
     112         [ #  # ]:          0 :         if (profile->peak.rate && min_rate > profile->peak.rate)
     113                 :            :                 min_rate = profile->peak.rate;
     114                 :            : 
     115                 :            :         /* Each packet accumulate single count, whereas HW
     116                 :            :          * considers each unit as Byte, so we need convert
     117                 :            :          * user pps to bps
     118                 :            :          */
     119                 :          0 :         profile->commit.rate = profile->commit.rate * 8;
     120                 :          0 :         profile->peak.rate = profile->peak.rate * 8;
     121                 :          0 :         min_rate = min_rate * 8;
     122                 :            : 
     123         [ #  # ]:          0 :         if (min_rate && (min_rate < NIX_TM_MIN_SHAPER_RATE)) {
     124                 :          0 :                 int adjust = NIX_TM_MIN_SHAPER_RATE / min_rate;
     125                 :            : 
     126                 :            :                 if (adjust > NIX_TM_LENGTH_ADJUST_MAX)
     127                 :            :                         return NIX_ERR_TM_SHAPER_PKT_LEN_ADJUST;
     128                 :            : 
     129                 :          0 :                 profile->pkt_mode_adj += adjust;
     130                 :          0 :                 profile->commit.rate += (adjust * profile->commit.rate);
     131                 :          0 :                 profile->peak.rate += (adjust * profile->peak.rate);
     132                 :            :                 /* Number of tokens freed after scheduling was proportional
     133                 :            :                  * to adjust value
     134                 :            :                  */
     135                 :          0 :                 profile->commit.size *= adjust;
     136                 :          0 :                 profile->peak.size *= adjust;
     137                 :            :         }
     138                 :            : 
     139                 :            :         return 0;
     140                 :            : }
     141                 :            : 
     142                 :            : static int
     143                 :          0 : nix_tm_shaper_profile_add(struct roc_nix *roc_nix,
     144                 :            :                           struct nix_tm_shaper_profile *profile, int skip_ins)
     145                 :            : {
     146                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     147                 :            :         uint64_t commit_rate, commit_sz;
     148                 :            :         uint64_t min_burst, max_burst;
     149                 :            :         uint64_t peak_rate, peak_sz;
     150                 :            :         uint32_t id;
     151                 :            :         int rc;
     152                 :            : 
     153                 :          0 :         id = profile->id;
     154                 :          0 :         rc = nix_tm_adjust_shaper_pps_rate(profile);
     155         [ #  # ]:          0 :         if (rc)
     156                 :            :                 return rc;
     157                 :            : 
     158                 :          0 :         commit_rate = profile->commit.rate;
     159                 :          0 :         commit_sz = profile->commit.size;
     160                 :          0 :         peak_rate = profile->peak.rate;
     161         [ #  # ]:          0 :         peak_sz = profile->peak.size;
     162                 :            : 
     163                 :            :         min_burst = NIX_TM_MIN_SHAPER_BURST;
     164                 :            :         max_burst = roc_nix_tm_max_shaper_burst_get();
     165                 :            : 
     166   [ #  #  #  # ]:          0 :         if (nix_tm_shaper_profile_search(nix, id) && !skip_ins)
     167                 :            :                 return NIX_ERR_TM_SHAPER_PROFILE_EXISTS;
     168                 :            : 
     169         [ #  # ]:          0 :         if (profile->pkt_len_adj < NIX_TM_LENGTH_ADJUST_MIN ||
     170                 :            :             profile->pkt_len_adj > NIX_TM_LENGTH_ADJUST_MAX)
     171                 :            :                 return NIX_ERR_TM_SHAPER_PKT_LEN_ADJUST;
     172                 :            : 
     173                 :            :         /* We cannot support both pkt length adjust and pkt mode */
     174   [ #  #  #  # ]:          0 :         if (profile->pkt_mode && profile->pkt_len_adj)
     175                 :            :                 return NIX_ERR_TM_SHAPER_PKT_LEN_ADJUST;
     176                 :            : 
     177                 :            :         /* commit rate and burst size can be enabled/disabled */
     178         [ #  # ]:          0 :         if (commit_rate || commit_sz) {
     179         [ #  # ]:          0 :                 if (commit_sz < min_burst || commit_sz > max_burst)
     180                 :            :                         return NIX_ERR_TM_INVALID_COMMIT_SZ;
     181         [ #  # ]:          0 :                 else if (!nix_tm_shaper_rate_conv(commit_rate, NULL, NULL, NULL,
     182                 :          0 :                                                   profile->accuracy))
     183                 :            :                         return NIX_ERR_TM_INVALID_COMMIT_RATE;
     184                 :            :         }
     185                 :            : 
     186                 :            :         /* Peak rate and burst size can be enabled/disabled */
     187         [ #  # ]:          0 :         if (peak_sz || peak_rate) {
     188         [ #  # ]:          0 :                 if (peak_sz < min_burst || peak_sz > max_burst)
     189                 :            :                         return NIX_ERR_TM_INVALID_PEAK_SZ;
     190         [ #  # ]:          0 :                 else if (!nix_tm_shaper_rate_conv(peak_rate, NULL, NULL, NULL,
     191                 :          0 :                                                   profile->accuracy))
     192                 :            :                         return NIX_ERR_TM_INVALID_PEAK_RATE;
     193                 :            :         }
     194                 :            : 
     195                 :            :         /* If PIR and CIR are requested, PIR should always be larger than CIR */
     196   [ #  #  #  # ]:          0 :         if (peak_rate && commit_rate && (commit_rate > peak_rate))
     197                 :            :                 return NIX_ERR_TM_INVALID_PEAK_RATE;
     198                 :            : 
     199         [ #  # ]:          0 :         if (!skip_ins)
     200                 :          0 :                 TAILQ_INSERT_TAIL(&nix->shaper_profile_list, profile, shaper);
     201                 :            : 
     202                 :          0 :         plt_tm_dbg("Added TM shaper profile %u, "
     203                 :            :                    " pir %" PRIu64 " , pbs %" PRIu64 ", cir %" PRIu64
     204                 :            :                    ", cbs %" PRIu64 " , adj %u, pkt_mode %u",
     205                 :            :                    id, profile->peak.rate, profile->peak.size,
     206                 :            :                    profile->commit.rate, profile->commit.size,
     207                 :            :                    profile->pkt_len_adj, profile->pkt_mode);
     208                 :            : 
     209                 :            :         /* Always use PIR for single rate shaping */
     210         [ #  # ]:          0 :         if (!peak_rate && commit_rate) {
     211                 :          0 :                 profile->peak.rate = profile->commit.rate;
     212                 :          0 :                 profile->peak.size = profile->commit.size;
     213                 :          0 :                 profile->commit.rate = 0;
     214                 :          0 :                 profile->commit.size = 0;
     215                 :            :         }
     216                 :            : 
     217                 :            :         /* update min rate */
     218                 :          0 :         nix->tm_rate_min = nix_tm_shaper_profile_rate_min(nix);
     219                 :          0 :         return 0;
     220                 :            : }
     221                 :            : 
     222                 :            : int
     223                 :          0 : roc_nix_tm_shaper_profile_add(struct roc_nix *roc_nix,
     224                 :            :                               struct roc_nix_tm_shaper_profile *roc_profile)
     225                 :            : {
     226                 :            :         struct nix_tm_shaper_profile *profile;
     227                 :            : 
     228                 :          0 :         profile = (struct nix_tm_shaper_profile *)roc_profile->reserved;
     229                 :            : 
     230                 :          0 :         profile->ref_cnt = 0;
     231                 :          0 :         profile->id = roc_profile->id;
     232                 :          0 :         profile->commit.rate = roc_profile->commit_rate;
     233                 :          0 :         profile->peak.rate = roc_profile->peak_rate;
     234                 :          0 :         profile->commit.size = roc_profile->commit_sz;
     235                 :          0 :         profile->peak.size = roc_profile->peak_sz;
     236                 :          0 :         profile->pkt_len_adj = roc_profile->pkt_len_adj;
     237                 :          0 :         profile->pkt_mode = roc_profile->pkt_mode;
     238                 :          0 :         profile->free_fn = roc_profile->free_fn;
     239                 :          0 :         profile->accuracy = roc_profile->accuracy;
     240                 :            : 
     241                 :          0 :         return nix_tm_shaper_profile_add(roc_nix, profile, 0);
     242                 :            : }
     243                 :            : 
     244                 :            : int
     245                 :          0 : roc_nix_tm_shaper_profile_update(struct roc_nix *roc_nix,
     246                 :            :                                  struct roc_nix_tm_shaper_profile *roc_profile)
     247                 :            : {
     248                 :            :         struct nix_tm_shaper_profile *profile;
     249                 :            : 
     250                 :          0 :         profile = (struct nix_tm_shaper_profile *)roc_profile->reserved;
     251                 :            : 
     252                 :          0 :         profile->commit.rate = roc_profile->commit_rate;
     253                 :          0 :         profile->peak.rate = roc_profile->peak_rate;
     254                 :          0 :         profile->commit.size = roc_profile->commit_sz;
     255                 :          0 :         profile->peak.size = roc_profile->peak_sz;
     256                 :          0 :         profile->pkt_len_adj = roc_profile->pkt_len_adj;
     257                 :          0 :         profile->accuracy = roc_profile->accuracy;
     258                 :            : 
     259                 :          0 :         return nix_tm_shaper_profile_add(roc_nix, profile, 1);
     260                 :            : }
     261                 :            : 
     262                 :            : int
     263                 :          0 : roc_nix_tm_shaper_profile_delete(struct roc_nix *roc_nix, uint32_t id)
     264                 :            : {
     265                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     266                 :            :         struct nix_tm_shaper_profile *profile;
     267                 :            : 
     268                 :          0 :         profile = nix_tm_shaper_profile_search(nix, id);
     269         [ #  # ]:          0 :         if (!profile)
     270                 :            :                 return NIX_ERR_TM_INVALID_SHAPER_PROFILE;
     271                 :            : 
     272         [ #  # ]:          0 :         if (profile->ref_cnt)
     273                 :            :                 return NIX_ERR_TM_SHAPER_PROFILE_IN_USE;
     274                 :            : 
     275                 :          0 :         plt_tm_dbg("Removing TM shaper profile %u", id);
     276         [ #  # ]:          0 :         TAILQ_REMOVE(&nix->shaper_profile_list, profile, shaper);
     277                 :          0 :         nix_tm_shaper_profile_free(profile);
     278                 :            : 
     279                 :            :         /* update min rate */
     280                 :          0 :         nix->tm_rate_min = nix_tm_shaper_profile_rate_min(nix);
     281                 :          0 :         return 0;
     282                 :            : }
     283                 :            : 
     284                 :            : int
     285                 :          0 : roc_nix_tm_node_add(struct roc_nix *roc_nix, struct roc_nix_tm_node *roc_node)
     286                 :            : {
     287                 :            :         struct nix_tm_node *node;
     288                 :            : 
     289                 :          0 :         node = (struct nix_tm_node *)&roc_node->reserved;
     290                 :          0 :         node->id = roc_node->id;
     291                 :          0 :         node->priority = roc_node->priority;
     292                 :          0 :         node->weight = roc_node->weight;
     293                 :          0 :         node->lvl = roc_node->lvl;
     294                 :          0 :         node->parent_id = roc_node->parent_id;
     295                 :          0 :         node->shaper_profile_id = roc_node->shaper_profile_id;
     296                 :          0 :         node->pkt_mode = roc_node->pkt_mode;
     297                 :          0 :         node->pkt_mode_set = roc_node->pkt_mode_set;
     298                 :          0 :         node->free_fn = roc_node->free_fn;
     299                 :          0 :         node->tree = ROC_NIX_TM_USER;
     300                 :          0 :         node->rel_chan = NIX_TM_CHAN_INVALID;
     301                 :            : 
     302                 :          0 :         return nix_tm_node_add(roc_nix, node);
     303                 :            : }
     304                 :            : 
     305                 :            : int
     306                 :          0 : roc_nix_tm_node_pkt_mode_update(struct roc_nix *roc_nix, uint32_t node_id,
     307                 :            :                                 bool pkt_mode)
     308                 :            : {
     309                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     310                 :            :         struct nix_tm_node *node, *child;
     311                 :            :         struct nix_tm_node_list *list;
     312                 :            :         int num_children = 0;
     313                 :            : 
     314                 :          0 :         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
     315         [ #  # ]:          0 :         if (!node)
     316                 :            :                 return NIX_ERR_TM_INVALID_NODE;
     317                 :            : 
     318         [ #  # ]:          0 :         if (node->pkt_mode == pkt_mode) {
     319                 :          0 :                 node->pkt_mode_set = true;
     320                 :          0 :                 return 0;
     321                 :            :         }
     322                 :            : 
     323                 :            :         /* Check for any existing children, if there are any,
     324                 :            :          * then we cannot update the pkt mode as children's quantum
     325                 :            :          * are already taken in.
     326                 :            :          */
     327                 :            :         list = nix_tm_node_list(nix, ROC_NIX_TM_USER);
     328         [ #  # ]:          0 :         TAILQ_FOREACH(child, list, node) {
     329         [ #  # ]:          0 :                 if (child->parent == node)
     330                 :          0 :                         num_children++;
     331                 :            :         }
     332                 :            : 
     333                 :            :         /* Cannot update mode if it has children or tree is enabled */
     334   [ #  #  #  # ]:          0 :         if ((nix->tm_flags & NIX_TM_HIERARCHY_ENA) && num_children)
     335                 :            :                 return -EBUSY;
     336                 :            : 
     337   [ #  #  #  # ]:          0 :         if (node->pkt_mode_set && num_children)
     338                 :            :                 return NIX_ERR_TM_PKT_MODE_MISMATCH;
     339                 :            : 
     340                 :          0 :         node->pkt_mode = pkt_mode;
     341                 :          0 :         node->pkt_mode_set = true;
     342                 :            : 
     343                 :          0 :         return 0;
     344                 :            : }
     345                 :            : 
     346                 :            : int
     347                 :          0 : roc_nix_tm_node_name_get(struct roc_nix *roc_nix, uint32_t node_id, char *buf,
     348                 :            :                          size_t buflen)
     349                 :            : {
     350                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     351                 :            :         struct nix_tm_node *node;
     352                 :            : 
     353                 :          0 :         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
     354         [ #  # ]:          0 :         if (!node) {
     355                 :            :                 plt_strlcpy(buf, "???", buflen);
     356                 :          0 :                 return NIX_ERR_TM_INVALID_NODE;
     357                 :            :         }
     358                 :            : 
     359         [ #  # ]:          0 :         if (node->hw_lvl == NIX_TXSCH_LVL_CNT)
     360                 :          0 :                 snprintf(buf, buflen, "SQ_%d", node->id);
     361                 :            :         else
     362   [ #  #  #  #  :          0 :                 snprintf(buf, buflen, "%s_%d", nix_tm_hwlvl2str(node->hw_lvl),
                   #  # ]
     363                 :            :                          node->hw_id);
     364                 :            :         return 0;
     365                 :            : }
     366                 :            : 
     367                 :            : int
     368                 :          0 : roc_nix_tm_node_delete(struct roc_nix *roc_nix, uint32_t node_id, bool free)
     369                 :            : {
     370                 :          0 :         return nix_tm_node_delete(roc_nix, node_id, ROC_NIX_TM_USER, free);
     371                 :            : }
     372                 :            : 
     373                 :            : int
     374         [ #  # ]:          0 : roc_nix_smq_flush(struct roc_nix *roc_nix)
     375                 :            : {
     376                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     377                 :            :         struct nix_tm_node_list *list;
     378                 :            :         enum roc_nix_tm_tree tree;
     379                 :            :         struct nix_tm_node *node;
     380                 :            :         int rc = 0;
     381                 :            : 
     382         [ #  # ]:          0 :         if (!(nix->tm_flags & NIX_TM_HIERARCHY_ENA))
     383                 :            :                 return 0;
     384                 :            : 
     385                 :          0 :         tree = nix->tm_tree;
     386                 :            :         list = nix_tm_node_list(nix, tree);
     387                 :            : 
     388                 :            :         /* XOFF & Flush all SMQ's. HRM mandates
     389                 :            :          * all SQ's empty before SMQ flush is issued.
     390                 :            :          */
     391         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     392         [ #  # ]:          0 :                 if (node->hw_lvl != NIX_TXSCH_LVL_SMQ)
     393                 :          0 :                         continue;
     394         [ #  # ]:          0 :                 if (!(node->flags & NIX_TM_NODE_HWRES))
     395                 :          0 :                         continue;
     396                 :            : 
     397                 :          0 :                 rc = nix_tm_smq_xoff(nix, node, true);
     398         [ #  # ]:          0 :                 if (rc) {
     399                 :          0 :                         plt_err("Failed to enable smq %u, rc=%d", node->hw_id,
     400                 :            :                                 rc);
     401                 :          0 :                         goto exit;
     402                 :            :                 }
     403                 :            :         }
     404                 :            : 
     405                 :            :         /* XON all SMQ's */
     406         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     407         [ #  # ]:          0 :                 if (node->hw_lvl != NIX_TXSCH_LVL_SMQ)
     408                 :          0 :                         continue;
     409         [ #  # ]:          0 :                 if (!(node->flags & NIX_TM_NODE_HWRES))
     410                 :          0 :                         continue;
     411                 :            : 
     412                 :          0 :                 rc = nix_tm_smq_xoff(nix, node, false);
     413         [ #  # ]:          0 :                 if (rc) {
     414                 :          0 :                         plt_err("Failed to enable smq %u, rc=%d", node->hw_id,
     415                 :            :                                 rc);
     416                 :          0 :                         goto exit;
     417                 :            :                 }
     418                 :            :         }
     419                 :          0 : exit:
     420                 :            :         return rc;
     421                 :            : }
     422                 :            : 
     423                 :            : int
     424         [ #  # ]:          0 : roc_nix_tm_hierarchy_disable(struct roc_nix *roc_nix)
     425                 :            : {
     426                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     427                 :            :         uint16_t sqb_cnt, head_off, tail_off;
     428                 :          0 :         uint16_t sq_cnt = nix->nb_tx_queues;
     429                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
     430                 :            :         struct nix_tm_node_list *list;
     431                 :            :         enum roc_nix_tm_tree tree;
     432                 :            :         struct nix_tm_node *node;
     433                 :            :         struct roc_nix_sq *sq;
     434                 :            :         uint64_t wdata, val;
     435                 :            :         uintptr_t regaddr;
     436                 :            :         int rc = -1, i;
     437                 :            : 
     438         [ #  # ]:          0 :         if (!(nix->tm_flags & NIX_TM_HIERARCHY_ENA))
     439                 :            :                 return 0;
     440                 :            : 
     441                 :          0 :         plt_tm_dbg("Disabling hierarchy on %s", nix->pci_dev->name);
     442                 :            : 
     443                 :          0 :         tree = nix->tm_tree;
     444                 :            :         list = nix_tm_node_list(nix, tree);
     445                 :            : 
     446                 :            :         /* Enable CGX RXTX to drain pkts */
     447         [ #  # ]:          0 :         if (!roc_nix->io_enabled) {
     448                 :            :                 /* Though it enables both RX MCAM Entries and CGX Link
     449                 :            :                  * we assume all the rx queues are stopped way back.
     450                 :            :                  */
     451                 :          0 :                 mbox_alloc_msg_nix_lf_start_rx(mbox_get(mbox));
     452                 :          0 :                 rc = mbox_process(mbox);
     453         [ #  # ]:          0 :                 if (rc) {
     454                 :            :                         mbox_put(mbox);
     455                 :          0 :                         plt_err("cgx start failed, rc=%d", rc);
     456                 :          0 :                         return rc;
     457                 :            :                 }
     458                 :            :                 mbox_put(mbox);
     459                 :            :         }
     460                 :            : 
     461                 :            :         /* XON all SMQ's */
     462         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     463         [ #  # ]:          0 :                 if (node->hw_lvl != NIX_TXSCH_LVL_SMQ)
     464                 :          0 :                         continue;
     465         [ #  # ]:          0 :                 if (!(node->flags & NIX_TM_NODE_HWRES))
     466                 :          0 :                         continue;
     467                 :            : 
     468                 :          0 :                 rc = nix_tm_smq_xoff(nix, node, false);
     469         [ #  # ]:          0 :                 if (rc) {
     470                 :          0 :                         plt_err("Failed to enable smq %u, rc=%d", node->hw_id,
     471                 :            :                                 rc);
     472                 :          0 :                         goto cleanup;
     473                 :            :                 }
     474                 :            :         }
     475                 :            : 
     476                 :            :         /* Disable backpressure, it will be enabled back if needed on
     477                 :            :          * hierarchy enable
     478                 :            :          */
     479         [ #  # ]:          0 :         for (i = 0; i < sq_cnt; i++) {
     480                 :          0 :                 sq = nix->sqs[i];
     481         [ #  # ]:          0 :                 if (!sq)
     482                 :          0 :                         continue;
     483                 :            : 
     484                 :          0 :                 rc = nix_tm_bp_config_set(roc_nix, sq->qid, 0, false);
     485         [ #  # ]:          0 :                 if (rc && rc != -ENOENT) {
     486                 :          0 :                         plt_err("Failed to disable backpressure, rc=%d", rc);
     487                 :          0 :                         goto cleanup;
     488                 :            :                 }
     489                 :            :         }
     490                 :            : 
     491                 :            :         /* Flush all tx queues */
     492         [ #  # ]:          0 :         for (i = 0; i < sq_cnt; i++) {
     493                 :          0 :                 sq = nix->sqs[i];
     494         [ #  # ]:          0 :                 if (!sq)
     495                 :          0 :                         continue;
     496                 :            : 
     497                 :          0 :                 rc = roc_nix_tm_sq_aura_fc(sq, false);
     498         [ #  # ]:          0 :                 if (rc) {
     499                 :          0 :                         plt_err("Failed to disable sqb aura fc, rc=%d", rc);
     500                 :          0 :                         goto cleanup;
     501                 :            :                 }
     502                 :            : 
     503                 :            :                 /* Wait for sq entries to be flushed */
     504                 :          0 :                 rc = roc_nix_tm_sq_flush_spin(sq);
     505         [ #  # ]:          0 :                 if (rc) {
     506                 :          0 :                         plt_err("Failed to drain sq, rc=%d\n", rc);
     507                 :          0 :                         goto cleanup;
     508                 :            :                 }
     509                 :            :         }
     510                 :            : 
     511                 :            :         /* XOFF & Flush all SMQ's. HRM mandates
     512                 :            :          * all SQ's empty before SMQ flush is issued.
     513                 :            :          */
     514         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     515         [ #  # ]:          0 :                 if (node->hw_lvl != NIX_TXSCH_LVL_SMQ)
     516                 :          0 :                         continue;
     517         [ #  # ]:          0 :                 if (!(node->flags & NIX_TM_NODE_HWRES))
     518                 :          0 :                         continue;
     519                 :            : 
     520                 :          0 :                 rc = nix_tm_smq_xoff(nix, node, true);
     521         [ #  # ]:          0 :                 if (rc) {
     522                 :          0 :                         plt_err("Failed to enable smq %u, rc=%d", node->hw_id,
     523                 :            :                                 rc);
     524                 :          0 :                         goto cleanup;
     525                 :            :                 }
     526                 :            : 
     527                 :          0 :                 node->flags &= ~NIX_TM_NODE_ENABLED;
     528                 :            :         }
     529                 :            : 
     530                 :            :         /* Verify sanity of all tx queues */
     531         [ #  # ]:          0 :         for (i = 0; i < sq_cnt; i++) {
     532                 :          0 :                 sq = nix->sqs[i];
     533         [ #  # ]:          0 :                 if (!sq)
     534                 :          0 :                         continue;
     535                 :            : 
     536                 :          0 :                 wdata = ((uint64_t)sq->qid << 32);
     537                 :            :                 regaddr = nix->base + NIX_LF_SQ_OP_STATUS;
     538                 :            :                 val = roc_atomic64_add_nosync(wdata, (int64_t *)regaddr);
     539                 :            : 
     540                 :            :                 sqb_cnt = val & 0xFFFF;
     541                 :            :                 head_off = (val >> 20) & 0x3F;
     542                 :            :                 tail_off = (val >> 28) & 0x3F;
     543                 :            : 
     544                 :          0 :                 if (sqb_cnt > 1 || head_off != tail_off ||
     545         [ #  # ]:          0 :                     (*(uint64_t *)sq->fc != sq->aura_sqb_bufs))
     546                 :          0 :                         plt_err("Failed to gracefully flush sq %u", sq->qid);
     547                 :            :         }
     548                 :            : 
     549                 :          0 :         nix->tm_flags &= ~NIX_TM_HIERARCHY_ENA;
     550                 :          0 : cleanup:
     551                 :            :         /* Restore cgx state */
     552         [ #  # ]:          0 :         if (!roc_nix->io_enabled) {
     553                 :          0 :                 mbox_alloc_msg_nix_lf_stop_rx(mbox_get(mbox));
     554                 :          0 :                 rc |= mbox_process(mbox);
     555                 :            :                 mbox_put(mbox);
     556                 :            :         }
     557                 :            :         return rc;
     558                 :            : }
     559                 :            : 
     560                 :            : int
     561         [ #  # ]:          0 : roc_nix_tm_hierarchy_xmit_enable(struct roc_nix *roc_nix, enum roc_nix_tm_tree tree)
     562                 :            : {
     563                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     564                 :            :         struct nix_tm_node_list *list;
     565                 :            :         struct nix_tm_node *node;
     566                 :            :         struct roc_nix_sq *sq;
     567                 :            :         uint16_t sq_id;
     568                 :            :         int rc;
     569                 :            : 
     570         [ #  # ]:          0 :         if (tree >= ROC_NIX_TM_TREE_MAX)
     571                 :            :                 return NIX_ERR_PARAM;
     572                 :            : 
     573                 :            :         list = nix_tm_node_list(nix, tree);
     574                 :            : 
     575                 :            :         /* Update SQ Sched Data while SQ is idle */
     576         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     577   [ #  #  #  # ]:          0 :                 if (!nix_tm_is_leaf(nix, node->lvl))
     578                 :          0 :                         continue;
     579                 :            : 
     580                 :          0 :                 rc = nix_tm_sq_sched_conf(nix, node, false);
     581         [ #  # ]:          0 :                 if (rc) {
     582                 :          0 :                         plt_err("SQ %u sched update failed, rc=%d", node->id,
     583                 :            :                                 rc);
     584                 :          0 :                         return rc;
     585                 :            :                 }
     586                 :            :         }
     587                 :            : 
     588                 :            :         /* Finally XON all SMQ's */
     589         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     590         [ #  # ]:          0 :                 if (node->hw_lvl != NIX_TXSCH_LVL_SMQ)
     591                 :          0 :                         continue;
     592                 :            : 
     593                 :          0 :                 rc = nix_tm_smq_xoff(nix, node, false);
     594         [ #  # ]:          0 :                 if (rc) {
     595                 :          0 :                         plt_err("Failed to enable smq %u, rc=%d", node->hw_id,
     596                 :            :                                 rc);
     597                 :          0 :                         return rc;
     598                 :            :                 }
     599                 :            :         }
     600                 :            : 
     601                 :            :         /* Enable xmit as all the topology is ready */
     602         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     603   [ #  #  #  # ]:          0 :                 if (!nix_tm_is_leaf(nix, node->lvl))
     604                 :          0 :                         continue;
     605                 :            : 
     606                 :          0 :                 sq_id = node->id;
     607                 :          0 :                 sq = nix->sqs[sq_id];
     608                 :            : 
     609                 :          0 :                 rc = roc_nix_tm_sq_aura_fc(sq, true);
     610         [ #  # ]:          0 :                 if (rc) {
     611                 :          0 :                         plt_err("TM sw xon failed on SQ %u, rc=%d", node->id,
     612                 :            :                                 rc);
     613                 :          0 :                         return rc;
     614                 :            :                 }
     615                 :          0 :                 node->flags |= NIX_TM_NODE_ENABLED;
     616                 :            :         }
     617                 :            : 
     618                 :            :         return 0;
     619                 :            : }
     620                 :            : 
     621                 :            : int
     622         [ #  # ]:          0 : roc_nix_tm_hierarchy_enable(struct roc_nix *roc_nix, enum roc_nix_tm_tree tree,
     623                 :            :                             bool xmit_enable)
     624                 :            : {
     625                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     626                 :            :         struct nix_tm_node_list *list;
     627                 :            :         struct nix_tm_node *node;
     628                 :            :         uint32_t tree_mask;
     629                 :            :         int rc;
     630                 :            : 
     631         [ #  # ]:          0 :         if (tree >= ROC_NIX_TM_TREE_MAX)
     632                 :            :                 return NIX_ERR_PARAM;
     633                 :            : 
     634         [ #  # ]:          0 :         if (nix->tm_flags & NIX_TM_HIERARCHY_ENA) {
     635         [ #  # ]:          0 :                 if (nix->tm_tree != tree)
     636                 :            :                         return -EBUSY;
     637                 :          0 :                 return 0;
     638                 :            :         }
     639                 :            : 
     640                 :          0 :         plt_tm_dbg("Enabling hierarchy on %s, xmit_ena %u, tree %u",
     641                 :            :                    nix->pci_dev->name, xmit_enable, tree);
     642                 :            : 
     643                 :            :         /* Free hw resources of other trees */
     644                 :            :         tree_mask = NIX_TM_TREE_MASK_ALL;
     645                 :          0 :         tree_mask &= ~BIT(tree);
     646                 :            : 
     647                 :          0 :         rc = nix_tm_free_resources(roc_nix, tree_mask, true);
     648         [ #  # ]:          0 :         if (rc) {
     649                 :          0 :                 plt_err("failed to free resources of other trees, rc=%d", rc);
     650                 :          0 :                 return rc;
     651                 :            :         }
     652                 :            : 
     653                 :            :         /* Update active tree before starting to do anything */
     654                 :          0 :         nix->tm_tree = tree;
     655                 :            : 
     656                 :          0 :         nix_tm_update_parent_info(nix, tree);
     657                 :            : 
     658                 :          0 :         rc = nix_tm_alloc_txschq(nix, tree);
     659         [ #  # ]:          0 :         if (rc) {
     660                 :          0 :                 plt_err("TM failed to alloc tm resources=%d", rc);
     661                 :          0 :                 return rc;
     662                 :            :         }
     663                 :            : 
     664                 :          0 :         rc = nix_tm_assign_resources(nix, tree);
     665         [ #  # ]:          0 :         if (rc) {
     666                 :          0 :                 plt_err("TM failed to assign tm resources=%d", rc);
     667                 :          0 :                 return rc;
     668                 :            :         }
     669                 :            : 
     670                 :          0 :         rc = nix_tm_txsch_reg_config(nix, tree);
     671         [ #  # ]:          0 :         if (rc) {
     672                 :          0 :                 plt_err("TM failed to configure sched registers=%d", rc);
     673                 :          0 :                 return rc;
     674                 :            :         }
     675                 :            : 
     676                 :            :         list = nix_tm_node_list(nix, tree);
     677                 :            :         /* Mark all non-leaf's as enabled */
     678         [ #  # ]:          0 :         TAILQ_FOREACH(node, list, node) {
     679   [ #  #  #  # ]:          0 :                 if (!nix_tm_is_leaf(nix, node->lvl))
     680                 :          0 :                         node->flags |= NIX_TM_NODE_ENABLED;
     681                 :            :         }
     682                 :            : 
     683         [ #  # ]:          0 :         if (xmit_enable)
     684                 :          0 :                 rc = roc_nix_tm_hierarchy_xmit_enable(roc_nix, tree);
     685                 :            : 
     686         [ #  # ]:          0 :         if (!rc)
     687                 :          0 :                 nix->tm_flags |= NIX_TM_HIERARCHY_ENA;
     688                 :            :         return rc;
     689                 :            : }
     690                 :            : 
     691                 :            : int
     692                 :          0 : roc_nix_tm_node_suspend_resume(struct roc_nix *roc_nix, uint32_t node_id,
     693                 :            :                                bool suspend)
     694                 :            : {
     695                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     696                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
     697                 :            :         struct nix_txschq_config *req;
     698                 :            :         struct nix_tm_node *node;
     699                 :            :         uint16_t flags;
     700                 :            :         int rc;
     701                 :            : 
     702                 :          0 :         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
     703         [ #  # ]:          0 :         if (!node)
     704                 :            :                 return NIX_ERR_TM_INVALID_NODE;
     705                 :            : 
     706                 :          0 :         flags = node->flags;
     707         [ #  # ]:          0 :         flags = suspend ? (flags & ~NIX_TM_NODE_ENABLED) :
     708                 :            :                                 (flags | NIX_TM_NODE_ENABLED);
     709                 :            : 
     710         [ #  # ]:          0 :         if (node->flags == flags)
     711                 :            :                 return 0;
     712                 :            : 
     713                 :            :         /* send mbox for state change */
     714                 :          0 :         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     715                 :            : 
     716                 :          0 :         req->lvl = node->hw_lvl;
     717                 :          0 :         req->num_regs =
     718                 :          0 :                 nix_tm_sw_xoff_prep(node, suspend, req->reg, req->regval);
     719                 :          0 :         rc = mbox_process(mbox);
     720                 :            :         mbox_put(mbox);
     721         [ #  # ]:          0 :         if (!rc)
     722                 :          0 :                 node->flags = flags;
     723                 :            :         return rc;
     724                 :            : }
     725                 :            : 
     726                 :            : int
     727                 :          0 : roc_nix_tm_prealloc_res(struct roc_nix *roc_nix, uint8_t lvl,
     728                 :            :                         uint16_t discontig, uint16_t contig)
     729                 :            : {
     730                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     731                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
     732                 :            :         struct nix_txsch_alloc_req *req;
     733                 :            :         struct nix_txsch_alloc_rsp *rsp;
     734                 :            :         uint8_t hw_lvl;
     735                 :            :         int rc = -ENOSPC;
     736                 :            : 
     737                 :          0 :         hw_lvl = nix_tm_lvl2nix(nix, lvl);
     738         [ #  # ]:          0 :         if (hw_lvl == NIX_TXSCH_LVL_CNT)
     739                 :            :                 return -EINVAL;
     740                 :            : 
     741                 :            :         /* Preallocate contiguous */
     742         [ #  # ]:          0 :         if (nix->contig_rsvd[hw_lvl] < contig) {
     743                 :          0 :                 req = mbox_alloc_msg_nix_txsch_alloc(mbox_get(mbox));
     744         [ #  # ]:          0 :                 if (req == NULL) {
     745                 :            :                         mbox_put(mbox);
     746                 :          0 :                         return rc;
     747                 :            :                 }
     748                 :          0 :                 req->schq_contig[hw_lvl] = contig - nix->contig_rsvd[hw_lvl];
     749                 :            : 
     750                 :            :                 rc = mbox_process_msg(mbox, (void *)&rsp);
     751         [ #  # ]:          0 :                 if (rc) {
     752                 :            :                         mbox_put(mbox);
     753                 :          0 :                         return rc;
     754                 :            :                 }
     755                 :            : 
     756                 :          0 :                 nix_tm_copy_rsp_to_nix(nix, rsp);
     757                 :            :                 mbox_put(mbox);
     758                 :            :         }
     759                 :            : 
     760                 :            :         /* Preallocate contiguous */
     761         [ #  # ]:          0 :         if (nix->discontig_rsvd[hw_lvl] < discontig) {
     762                 :          0 :                 req = mbox_alloc_msg_nix_txsch_alloc(mbox_get(mbox));
     763         [ #  # ]:          0 :                 if (req == NULL) {
     764                 :            :                         mbox_put(mbox);
     765                 :          0 :                         return -ENOSPC;
     766                 :            :                 }
     767                 :          0 :                 req->schq[hw_lvl] = discontig - nix->discontig_rsvd[hw_lvl];
     768                 :            : 
     769                 :            :                 rc = mbox_process_msg(mbox, (void *)&rsp);
     770         [ #  # ]:          0 :                 if (rc) {
     771                 :            :                         mbox_put(mbox);
     772                 :          0 :                         return rc;
     773                 :            :                 }
     774                 :            : 
     775                 :          0 :                 nix_tm_copy_rsp_to_nix(nix, rsp);
     776                 :            :                 mbox_put(mbox);
     777                 :            :         }
     778                 :            : 
     779                 :            :         /* Save thresholds */
     780                 :          0 :         nix->contig_rsvd[hw_lvl] = contig;
     781                 :          0 :         nix->discontig_rsvd[hw_lvl] = discontig;
     782                 :            :         /* Release anything present above thresholds */
     783                 :          0 :         nix_tm_release_resources(nix, hw_lvl, true, true);
     784                 :          0 :         nix_tm_release_resources(nix, hw_lvl, false, true);
     785                 :          0 :         return 0;
     786                 :            : }
     787                 :            : 
     788                 :            : int
     789                 :          0 : roc_nix_tm_node_shaper_update(struct roc_nix *roc_nix, uint32_t node_id,
     790                 :            :                               uint32_t profile_id, bool force_update)
     791                 :            : {
     792                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     793                 :            :         struct nix_tm_shaper_profile *profile = NULL;
     794                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
     795                 :            :         struct nix_txschq_config *req;
     796                 :            :         struct nix_tm_node *node;
     797                 :            :         uint8_t k;
     798                 :            :         int rc;
     799                 :            : 
     800                 :            :         /* Shaper updates valid only for user nodes */
     801                 :          0 :         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
     802   [ #  #  #  #  :          0 :         if (!node || nix_tm_is_leaf(nix, node->lvl))
                   #  # ]
     803                 :            :                 return NIX_ERR_TM_INVALID_NODE;
     804                 :            : 
     805         [ #  # ]:          0 :         if (profile_id != ROC_NIX_TM_SHAPER_PROFILE_NONE) {
     806                 :          0 :                 profile = nix_tm_shaper_profile_search(nix, profile_id);
     807         [ #  # ]:          0 :                 if (!profile)
     808                 :            :                         return NIX_ERR_TM_INVALID_SHAPER_PROFILE;
     809                 :            :         }
     810                 :            : 
     811                 :            :         /* Pkt mode should match existing node's pkt mode */
     812         [ #  # ]:          0 :         if (profile && profile->pkt_mode != node->pkt_mode)
     813                 :            :                 return NIX_ERR_TM_PKT_MODE_MISMATCH;
     814                 :            : 
     815   [ #  #  #  # ]:          0 :         if ((profile_id == node->shaper_profile_id) && !force_update) {
     816                 :            :                 return 0;
     817         [ #  # ]:          0 :         } else if (profile_id != node->shaper_profile_id) {
     818                 :            :                 struct nix_tm_shaper_profile *old;
     819                 :            : 
     820                 :            :                 /* Find old shaper profile and reduce ref count */
     821                 :          0 :                 old = nix_tm_shaper_profile_search(nix,
     822                 :            :                                                    node->shaper_profile_id);
     823         [ #  # ]:          0 :                 if (old)
     824                 :          0 :                         old->ref_cnt--;
     825                 :            : 
     826         [ #  # ]:          0 :                 if (profile)
     827                 :          0 :                         profile->ref_cnt++;
     828                 :            : 
     829                 :            :                 /* Reduce older shaper ref count and increase new one */
     830                 :          0 :                 node->shaper_profile_id = profile_id;
     831                 :            :         }
     832                 :            : 
     833                 :            :         /* Nothing to do if hierarchy not yet enabled */
     834         [ #  # ]:          0 :         if (!(nix->tm_flags & NIX_TM_HIERARCHY_ENA))
     835                 :            :                 return 0;
     836                 :            : 
     837                 :          0 :         node->flags &= ~NIX_TM_NODE_ENABLED;
     838                 :            : 
     839                 :            :         /* Flush the specific node with SW_XOFF */
     840                 :          0 :         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     841                 :          0 :         req->lvl = node->hw_lvl;
     842                 :          0 :         k = nix_tm_sw_xoff_prep(node, true, req->reg, req->regval);
     843                 :          0 :         req->num_regs = k;
     844                 :            : 
     845                 :          0 :         rc = mbox_process(mbox);
     846         [ #  # ]:          0 :         if (rc) {
     847                 :            :                 mbox_put(mbox);
     848                 :          0 :                 return rc;
     849                 :            :         }
     850                 :            :         mbox_put(mbox);
     851                 :            : 
     852                 :            :         /* Update the PIR/CIR and clear SW XOFF */
     853                 :          0 :         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     854                 :          0 :         req->lvl = node->hw_lvl;
     855                 :            : 
     856                 :          0 :         k = nix_tm_shaper_reg_prep(node, profile, req->reg, req->regval);
     857                 :            : 
     858                 :          0 :         k += nix_tm_sw_xoff_prep(node, false, &req->reg[k], &req->regval[k]);
     859                 :            : 
     860                 :          0 :         req->num_regs = k;
     861                 :          0 :         rc = mbox_process(mbox);
     862                 :            :         mbox_put(mbox);
     863         [ #  # ]:          0 :         if (!rc)
     864                 :          0 :                 node->flags |= NIX_TM_NODE_ENABLED;
     865                 :            :         return rc;
     866                 :            : }
     867                 :            : 
     868                 :            : int
     869                 :          0 : roc_nix_tm_node_parent_update(struct roc_nix *roc_nix, uint32_t node_id,
     870                 :            :                               uint32_t new_parent_id, uint32_t priority,
     871                 :            :                               uint32_t weight)
     872                 :            : {
     873                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
     874                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
     875                 :            :         struct nix_tm_node *node, *sibling;
     876                 :            :         struct nix_tm_node *new_parent;
     877                 :            :         struct nix_txschq_config *req;
     878                 :            :         struct nix_tm_node_list *list;
     879                 :            :         uint8_t k;
     880                 :            :         int rc;
     881                 :            : 
     882                 :          0 :         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
     883         [ #  # ]:          0 :         if (!node)
     884                 :            :                 return NIX_ERR_TM_INVALID_NODE;
     885                 :            : 
     886                 :            :         /* Parent id valid only for non root nodes */
     887         [ #  # ]:          0 :         if (node->hw_lvl != nix->tm_root_lvl) {
     888                 :            :                 new_parent =
     889                 :          0 :                         nix_tm_node_search(nix, new_parent_id, ROC_NIX_TM_USER);
     890         [ #  # ]:          0 :                 if (!new_parent)
     891                 :            :                         return NIX_ERR_TM_INVALID_PARENT;
     892                 :            : 
     893                 :            :                 /* Current support is only for dynamic weight update */
     894   [ #  #  #  # ]:          0 :                 if (node->parent != new_parent || node->priority != priority)
     895                 :            :                         return NIX_ERR_TM_PARENT_PRIO_UPDATE;
     896                 :            :         }
     897                 :            : 
     898                 :            :         list = nix_tm_node_list(nix, ROC_NIX_TM_USER);
     899                 :            :         /* Skip if no change */
     900         [ #  # ]:          0 :         if (node->weight == weight)
     901                 :            :                 return 0;
     902                 :            : 
     903                 :          0 :         node->weight = weight;
     904                 :            : 
     905                 :            :         /* Nothing to do if hierarchy not yet enabled */
     906         [ #  # ]:          0 :         if (!(nix->tm_flags & NIX_TM_HIERARCHY_ENA))
     907                 :            :                 return 0;
     908                 :            : 
     909                 :            :         /* For leaf nodes, SQ CTX needs update */
     910   [ #  #  #  # ]:          0 :         if (nix_tm_is_leaf(nix, node->lvl)) {
     911                 :            :                 /* Update SQ quantum data on the fly */
     912                 :          0 :                 rc = nix_tm_sq_sched_conf(nix, node, true);
     913         [ #  # ]:          0 :                 if (rc)
     914                 :          0 :                         return NIX_ERR_TM_SQ_UPDATE_FAIL;
     915                 :            :         } else {
     916                 :            :                 /* XOFF Parent node */
     917                 :          0 :                 req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     918                 :          0 :                 req->lvl = node->parent->hw_lvl;
     919                 :          0 :                 req->num_regs = nix_tm_sw_xoff_prep(node->parent, true,
     920                 :          0 :                                                     req->reg, req->regval);
     921                 :          0 :                 rc = mbox_process(mbox);
     922                 :            :                 mbox_put(mbox);
     923         [ #  # ]:          0 :                 if (rc)
     924                 :            :                         return rc;
     925                 :            : 
     926                 :            :                 /* XOFF this node and all other siblings */
     927                 :          0 :                 req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     928                 :          0 :                 req->lvl = node->hw_lvl;
     929                 :            : 
     930                 :            :                 k = 0;
     931         [ #  # ]:          0 :                 TAILQ_FOREACH(sibling, list, node) {
     932         [ #  # ]:          0 :                         if (sibling->parent != node->parent)
     933                 :          0 :                                 continue;
     934                 :          0 :                         k += nix_tm_sw_xoff_prep(sibling, true, &req->reg[k], &req->regval[k]);
     935         [ #  # ]:          0 :                         if (k >= MAX_REGS_PER_MBOX_MSG) {
     936                 :          0 :                                 req->num_regs = k;
     937                 :          0 :                                 rc = mbox_process(mbox);
     938                 :            :                                 mbox_put(mbox);
     939         [ #  # ]:          0 :                                 if (rc)
     940                 :          0 :                                         return rc;
     941                 :            :                                 k = 0;
     942                 :          0 :                                 req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     943                 :          0 :                                 req->lvl = node->hw_lvl;
     944                 :            :                         }
     945                 :            :                 }
     946                 :            : 
     947         [ #  # ]:          0 :                 if (k) {
     948                 :          0 :                         req->num_regs = k;
     949                 :          0 :                         rc = mbox_process(mbox);
     950                 :            :                         mbox_put(mbox);
     951         [ #  # ]:          0 :                         if (rc)
     952                 :            :                                 return rc;
     953                 :            :                         /* Update new weight for current node */
     954                 :          0 :                         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     955                 :            :                 }
     956                 :            : 
     957                 :          0 :                 req->lvl = node->hw_lvl;
     958                 :          0 :                 req->num_regs = nix_tm_sched_reg_prep(nix, node, req->reg, req->regval);
     959                 :          0 :                 rc = mbox_process(mbox);
     960                 :            :                 mbox_put(mbox);
     961         [ #  # ]:          0 :                 if (rc)
     962                 :            :                         return rc;
     963                 :            : 
     964                 :            :                 /* XON this node and all other siblings */
     965                 :          0 :                 req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     966                 :          0 :                 req->lvl = node->hw_lvl;
     967                 :            : 
     968                 :            :                 k = 0;
     969         [ #  # ]:          0 :                 TAILQ_FOREACH(sibling, list, node) {
     970         [ #  # ]:          0 :                         if (sibling->parent != node->parent)
     971                 :          0 :                                 continue;
     972                 :          0 :                         k += nix_tm_sw_xoff_prep(sibling, false, &req->reg[k], &req->regval[k]);
     973         [ #  # ]:          0 :                         if (k >= MAX_REGS_PER_MBOX_MSG) {
     974                 :          0 :                                 req->num_regs = k;
     975                 :          0 :                                 rc = mbox_process(mbox);
     976                 :            :                                 mbox_put(mbox);
     977         [ #  # ]:          0 :                                 if (rc)
     978                 :          0 :                                         return rc;
     979                 :            :                                 k = 0;
     980                 :          0 :                                 req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     981                 :          0 :                                 req->lvl = node->hw_lvl;
     982                 :            :                         }
     983                 :            :                 }
     984                 :            : 
     985         [ #  # ]:          0 :                 if (k) {
     986                 :          0 :                         req->num_regs = k;
     987                 :          0 :                         rc = mbox_process(mbox);
     988                 :            :                         mbox_put(mbox);
     989         [ #  # ]:          0 :                         if (rc)
     990                 :            :                                 return rc;
     991                 :            :                         /* XON Parent node */
     992                 :          0 :                         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
     993                 :            :                 }
     994                 :            : 
     995                 :          0 :                 req->lvl = node->parent->hw_lvl;
     996                 :          0 :                 req->num_regs = nix_tm_sw_xoff_prep(node->parent, false, req->reg, req->regval);
     997                 :          0 :                 rc = mbox_process(mbox);
     998                 :            :                 mbox_put(mbox);
     999         [ #  # ]:          0 :                 if (rc)
    1000                 :          0 :                         return rc;
    1001                 :            :         }
    1002                 :            :         return 0;
    1003                 :            : }
    1004                 :            : 
    1005                 :            : int
    1006                 :          0 : roc_nix_tm_init(struct roc_nix *roc_nix)
    1007                 :            : {
    1008                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
    1009                 :            :         uint32_t tree_mask;
    1010                 :            :         int rc;
    1011                 :            : 
    1012         [ #  # ]:          0 :         if (nix->tm_flags & NIX_TM_HIERARCHY_ENA) {
    1013                 :          0 :                 plt_err("Cannot init while existing hierarchy is enabled");
    1014                 :          0 :                 return -EBUSY;
    1015                 :            :         }
    1016                 :            : 
    1017                 :            :         /* Free up all user resources already held */
    1018                 :            :         tree_mask = NIX_TM_TREE_MASK_ALL;
    1019                 :          0 :         rc = nix_tm_free_resources(roc_nix, tree_mask, false);
    1020         [ #  # ]:          0 :         if (rc) {
    1021                 :          0 :                 plt_err("Failed to freeup all nodes and resources, rc=%d", rc);
    1022                 :          0 :                 return rc;
    1023                 :            :         }
    1024                 :            : 
    1025                 :            :         /* Prepare default tree */
    1026                 :          0 :         rc = nix_tm_prepare_default_tree(roc_nix);
    1027         [ #  # ]:          0 :         if (rc) {
    1028                 :          0 :                 plt_err("failed to prepare default tm tree, rc=%d", rc);
    1029                 :          0 :                 return rc;
    1030                 :            :         }
    1031                 :            : 
    1032                 :            :         return rc;
    1033                 :            : }
    1034                 :            : 
    1035                 :            : int
    1036         [ #  # ]:          0 : roc_nix_tm_pfc_rlimit_sq(struct roc_nix *roc_nix, uint16_t qid, uint64_t rate)
    1037                 :            : {
    1038                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
    1039                 :            :         struct nix_tm_shaper_profile profile;
    1040                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
    1041                 :            :         struct nix_tm_node *node, *parent;
    1042                 :            :         struct roc_nix_link_info link_info;
    1043                 :            : 
    1044                 :            :         volatile uint64_t *reg, *regval;
    1045                 :            :         struct nix_txschq_config *req;
    1046                 :            :         uint64_t tl2_rate = 0;
    1047                 :            :         uint16_t flags;
    1048                 :            :         uint8_t k = 0;
    1049                 :            :         int rc;
    1050                 :            : 
    1051   [ #  #  #  # ]:          0 :         if ((nix->tm_tree != ROC_NIX_TM_PFC) || !(nix->tm_flags & NIX_TM_HIERARCHY_ENA))
    1052                 :            :                 return NIX_ERR_TM_INVALID_TREE;
    1053                 :            : 
    1054                 :          0 :         node = nix_tm_node_search(nix, qid, nix->tm_tree);
    1055                 :            : 
    1056                 :            :         /* check if we found a valid leaf node */
    1057   [ #  #  #  #  :          0 :         if (!node || !nix_tm_is_leaf(nix, node->lvl) || !node->parent ||
             #  #  #  # ]
    1058         [ #  # ]:          0 :             node->parent->hw_id == NIX_TM_HW_ID_INVALID) {
    1059                 :            :                 return NIX_ERR_TM_INVALID_NODE;
    1060                 :            :         }
    1061                 :            : 
    1062                 :            :         /* Get the link Speed */
    1063         [ #  # ]:          0 :         if (roc_nix_mac_link_info_get(roc_nix, &link_info))
    1064                 :            :                 return -EINVAL;
    1065                 :            : 
    1066         [ #  # ]:          0 :         if (link_info.status)
    1067                 :          0 :                 tl2_rate = link_info.speed * (uint64_t)1E6;
    1068                 :            : 
    1069                 :            :         /* Configure TL3 of leaf node with requested rate */
    1070                 :          0 :         parent = node->parent;        /* SMQ/MDQ */
    1071                 :          0 :         parent = parent->parent; /* TL4 */
    1072                 :          0 :         parent = parent->parent; /* TL3 */
    1073                 :          0 :         flags = parent->flags;
    1074                 :            : 
    1075                 :          0 :         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
    1076                 :          0 :         req->lvl = parent->hw_lvl;
    1077                 :          0 :         reg = req->reg;
    1078                 :          0 :         regval = req->regval;
    1079                 :            : 
    1080         [ #  # ]:          0 :         if (rate == 0) {
    1081                 :          0 :                 k += nix_tm_sw_xoff_prep(parent, true, &reg[k], &regval[k]);
    1082                 :          0 :                 flags &= ~NIX_TM_NODE_ENABLED;
    1083                 :          0 :                 goto exit;
    1084                 :            :         }
    1085                 :            : 
    1086         [ #  # ]:          0 :         if (!(flags & NIX_TM_NODE_ENABLED)) {
    1087                 :          0 :                 k += nix_tm_sw_xoff_prep(parent, false, &reg[k], &regval[k]);
    1088                 :          0 :                 flags |= NIX_TM_NODE_ENABLED;
    1089                 :            :         }
    1090                 :            : 
    1091                 :            :         /* Use only PIR for rate limit */
    1092                 :            :         memset(&profile, 0, sizeof(profile));
    1093                 :          0 :         profile.peak.rate = rate;
    1094                 :            :         /* Minimum burst of ~4us Bytes of Tx */
    1095                 :          0 :         profile.peak.size =
    1096                 :          0 :                 PLT_MAX((uint64_t)roc_nix_max_pkt_len(roc_nix), (4ul * rate) / ((uint64_t)1E6 * 8));
    1097   [ #  #  #  # ]:          0 :         if (!nix->tm_rate_min || nix->tm_rate_min > rate)
    1098                 :          0 :                 nix->tm_rate_min = rate;
    1099                 :            : 
    1100                 :          0 :         k += nix_tm_shaper_reg_prep(parent, &profile, &reg[k], &regval[k]);
    1101                 :          0 : exit:
    1102                 :          0 :         req->num_regs = k;
    1103                 :          0 :         rc = mbox_process(mbox);
    1104                 :            :         mbox_put(mbox);
    1105         [ #  # ]:          0 :         if (rc)
    1106                 :            :                 return rc;
    1107                 :            : 
    1108                 :          0 :         parent->flags = flags;
    1109                 :            : 
    1110                 :            :         /* If link is up then configure TL2 with link speed */
    1111   [ #  #  #  # ]:          0 :         if (tl2_rate && (flags & NIX_TM_NODE_ENABLED)) {
    1112                 :            :                 k = 0;
    1113                 :          0 :                 parent = parent->parent;
    1114                 :          0 :                 req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
    1115                 :          0 :                 req->lvl = parent->hw_lvl;
    1116                 :          0 :                 reg = req->reg;
    1117                 :          0 :                 regval = req->regval;
    1118                 :            : 
    1119                 :            :                 /* Use only PIR for rate limit */
    1120                 :            :                 memset(&profile, 0, sizeof(profile));
    1121                 :          0 :                 profile.peak.rate = tl2_rate;
    1122                 :            :                 /* Minimum burst of ~4us Bytes of Tx */
    1123                 :          0 :                 profile.peak.size = PLT_MAX((uint64_t)roc_nix_max_pkt_len(roc_nix),
    1124                 :            :                                             (4ul * tl2_rate) / ((uint64_t)1E6 * 8));
    1125                 :          0 :                 k += nix_tm_shaper_reg_prep(parent, &profile, &reg[k], &regval[k]);
    1126                 :          0 :                 req->num_regs = k;
    1127                 :          0 :                 rc = mbox_process(mbox);
    1128                 :            :                 mbox_put(mbox);
    1129                 :            :         }
    1130                 :            :         return rc;
    1131                 :            : }
    1132                 :            : 
    1133                 :            : int
    1134         [ #  # ]:          0 : roc_nix_tm_rlimit_sq(struct roc_nix *roc_nix, uint16_t qid, uint64_t rate)
    1135                 :            : {
    1136                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
    1137                 :            :         struct nix_tm_shaper_profile profile;
    1138                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
    1139                 :            :         struct nix_tm_node *node, *parent;
    1140                 :            : 
    1141                 :            :         volatile uint64_t *reg, *regval;
    1142                 :            :         struct nix_txschq_config *req;
    1143                 :            :         uint16_t flags;
    1144                 :            :         uint8_t k = 0;
    1145                 :            :         int rc;
    1146                 :            : 
    1147         [ #  # ]:          0 :         if ((nix->tm_tree == ROC_NIX_TM_USER) ||
    1148         [ #  # ]:          0 :             !(nix->tm_flags & NIX_TM_HIERARCHY_ENA)) {
    1149                 :            :                 return NIX_ERR_TM_INVALID_TREE;
    1150                 :            :         }
    1151                 :            : 
    1152                 :          0 :         node = nix_tm_node_search(nix, qid, nix->tm_tree);
    1153                 :            : 
    1154                 :            :         /* check if we found a valid leaf node */
    1155   [ #  #  #  #  :          0 :         if (!node || !nix_tm_is_leaf(nix, node->lvl) || !node->parent ||
             #  #  #  # ]
    1156         [ #  # ]:          0 :             node->parent->hw_id == NIX_TM_HW_ID_INVALID) {
    1157                 :            :                 return NIX_ERR_TM_INVALID_NODE;
    1158                 :            :         }
    1159                 :            : 
    1160                 :            :         parent = node->parent;
    1161                 :          0 :         flags = parent->flags;
    1162                 :            : 
    1163                 :          0 :         req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox));
    1164                 :          0 :         req->lvl = NIX_TXSCH_LVL_MDQ;
    1165                 :          0 :         reg = req->reg;
    1166                 :          0 :         regval = req->regval;
    1167                 :            : 
    1168         [ #  # ]:          0 :         if (rate == 0) {
    1169                 :          0 :                 k += nix_tm_sw_xoff_prep(parent, true, &reg[k], &regval[k]);
    1170                 :          0 :                 flags &= ~NIX_TM_NODE_ENABLED;
    1171                 :          0 :                 goto exit;
    1172                 :            :         }
    1173                 :            : 
    1174         [ #  # ]:          0 :         if (!(flags & NIX_TM_NODE_ENABLED)) {
    1175                 :          0 :                 k += nix_tm_sw_xoff_prep(parent, false, &reg[k], &regval[k]);
    1176                 :          0 :                 flags |= NIX_TM_NODE_ENABLED;
    1177                 :            :         }
    1178                 :            : 
    1179                 :            :         /* Use only PIR for rate limit */
    1180                 :            :         memset(&profile, 0, sizeof(profile));
    1181                 :          0 :         profile.peak.rate = rate;
    1182                 :            :         /* Minimum burst of ~4us Bytes of Tx */
    1183                 :          0 :         profile.peak.size = PLT_MAX((uint64_t)roc_nix_max_pkt_len(roc_nix),
    1184                 :            :                                     (4ul * rate) / ((uint64_t)1E6 * 8));
    1185   [ #  #  #  # ]:          0 :         if (!nix->tm_rate_min || nix->tm_rate_min > rate)
    1186                 :          0 :                 nix->tm_rate_min = rate;
    1187                 :            : 
    1188                 :          0 :         k += nix_tm_shaper_reg_prep(parent, &profile, &reg[k], &regval[k]);
    1189                 :          0 : exit:
    1190                 :          0 :         req->num_regs = k;
    1191                 :          0 :         rc = mbox_process(mbox);
    1192                 :            :         mbox_put(mbox);
    1193         [ #  # ]:          0 :         if (rc)
    1194                 :            :                 return rc;
    1195                 :            : 
    1196                 :          0 :         parent->flags = flags;
    1197                 :          0 :         return 0;
    1198                 :            : }
    1199                 :            : 
    1200                 :            : void
    1201                 :          0 : roc_nix_tm_fini(struct roc_nix *roc_nix)
    1202                 :            : {
    1203                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
    1204                 :          0 :         struct mbox *mbox = (&nix->dev)->mbox;
    1205                 :            :         struct nix_txsch_free_req *req;
    1206                 :            :         uint32_t tree_mask;
    1207                 :            :         uint8_t hw_lvl;
    1208                 :            :         int rc;
    1209                 :            : 
    1210                 :            :         /* Xmit is assumed to be disabled */
    1211                 :            :         /* Free up resources already held */
    1212                 :            :         tree_mask = NIX_TM_TREE_MASK_ALL;
    1213                 :          0 :         rc = nix_tm_free_resources(roc_nix, tree_mask, false);
    1214         [ #  # ]:          0 :         if (rc)
    1215                 :          0 :                 plt_err("Failed to freeup existing nodes or rsrcs, rc=%d", rc);
    1216                 :            : 
    1217                 :            :         /* Free all other hw resources */
    1218                 :          0 :         req = mbox_alloc_msg_nix_txsch_free(mbox_get(mbox));
    1219         [ #  # ]:          0 :         if (req == NULL) {
    1220                 :            :                 mbox_put(mbox);
    1221                 :          0 :                 return;
    1222                 :            :         }
    1223                 :            : 
    1224                 :          0 :         req->flags = TXSCHQ_FREE_ALL;
    1225                 :          0 :         rc = mbox_process(mbox);
    1226         [ #  # ]:          0 :         if (rc)
    1227                 :          0 :                 plt_err("Failed to freeup all res, rc=%d", rc);
    1228                 :            :         mbox_put(mbox);
    1229                 :            : 
    1230         [ #  # ]:          0 :         for (hw_lvl = 0; hw_lvl < NIX_TXSCH_LVL_CNT; hw_lvl++) {
    1231                 :          0 :                 plt_bitmap_reset(nix->schq_bmp[hw_lvl]);
    1232                 :          0 :                 plt_bitmap_reset(nix->schq_contig_bmp[hw_lvl]);
    1233                 :          0 :                 nix->contig_rsvd[hw_lvl] = 0;
    1234                 :          0 :                 nix->discontig_rsvd[hw_lvl] = 0;
    1235                 :            :         }
    1236                 :            : 
    1237                 :            :         /* Clear shaper profiles */
    1238                 :          0 :         nix_tm_clear_shaper_profiles(nix);
    1239                 :          0 :         nix->tm_tree = 0;
    1240                 :          0 :         nix->tm_flags &= ~NIX_TM_HIERARCHY_ENA;
    1241                 :            : }
    1242                 :            : 
    1243                 :            : int
    1244                 :          0 : roc_nix_tm_rsrc_count(struct roc_nix *roc_nix, uint16_t schq[ROC_TM_LVL_MAX])
    1245                 :            : {
    1246                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
    1247                 :          0 :         struct mbox *mbox = mbox_get((&nix->dev)->mbox);
    1248                 :            :         struct free_rsrcs_rsp *rsp;
    1249                 :            :         uint8_t hw_lvl;
    1250                 :            :         int rc, i;
    1251                 :            : 
    1252                 :            :         /* Get the current free resources */
    1253                 :          0 :         mbox_alloc_msg_free_rsrc_cnt(mbox);
    1254                 :            :         rc = mbox_process_msg(mbox, (void *)&rsp);
    1255         [ #  # ]:          0 :         if (rc)
    1256                 :          0 :                 goto exit;
    1257                 :            : 
    1258         [ #  # ]:          0 :         for (i = 0; i < ROC_TM_LVL_MAX; i++) {
    1259                 :          0 :                 hw_lvl = nix_tm_lvl2nix(nix, i);
    1260         [ #  # ]:          0 :                 if (hw_lvl == NIX_TXSCH_LVL_CNT)
    1261                 :          0 :                         continue;
    1262                 :            : 
    1263         [ #  # ]:          0 :                 schq[i] = (nix->is_nix1 ? rsp->schq_nix1[hw_lvl] :
    1264                 :          0 :                                                 rsp->schq[hw_lvl]);
    1265                 :            :         }
    1266                 :            : 
    1267                 :            :         rc = 0;
    1268                 :          0 : exit:
    1269                 :            :         mbox_put(mbox);
    1270                 :          0 :         return rc;
    1271                 :            : }
    1272                 :            : 
    1273                 :            : void
    1274                 :          0 : roc_nix_tm_rsrc_max(bool pf, uint16_t schq[ROC_TM_LVL_MAX])
    1275                 :            : {
    1276                 :            :         uint8_t hw_lvl, i;
    1277                 :            :         uint16_t max;
    1278                 :            : 
    1279         [ #  # ]:          0 :         for (i = 0; i < ROC_TM_LVL_MAX; i++) {
    1280         [ #  # ]:          0 :                 hw_lvl = pf ? nix_tm_lvl2nix_tl1_root(i) :
    1281                 :          0 :                                     nix_tm_lvl2nix_tl2_root(i);
    1282                 :            : 
    1283   [ #  #  #  #  :          0 :                 switch (hw_lvl) {
                   #  # ]
    1284                 :            :                 case NIX_TXSCH_LVL_SMQ:
    1285         [ #  # ]:          0 :                         max = (roc_model_is_cn9k() ?
    1286                 :            :                                              NIX_CN9K_TXSCH_LVL_SMQ_MAX :
    1287                 :            :                                              NIX_TXSCH_LVL_SMQ_MAX);
    1288                 :            :                         break;
    1289                 :            :                 case NIX_TXSCH_LVL_TL4:
    1290                 :            :                         max = NIX_TXSCH_LVL_TL4_MAX;
    1291                 :            :                         break;
    1292                 :          0 :                 case NIX_TXSCH_LVL_TL3:
    1293                 :            :                         max = NIX_TXSCH_LVL_TL3_MAX;
    1294                 :          0 :                         break;
    1295                 :          0 :                 case NIX_TXSCH_LVL_TL2:
    1296         [ #  # ]:          0 :                         max = pf ? NIX_TXSCH_LVL_TL2_MAX : 1;
    1297                 :            :                         break;
    1298                 :          0 :                 case NIX_TXSCH_LVL_TL1:
    1299                 :          0 :                         max = pf ? 1 : 0;
    1300                 :          0 :                         break;
    1301                 :          0 :                 default:
    1302                 :            :                         max = 0;
    1303                 :          0 :                         break;
    1304                 :            :                 }
    1305                 :          0 :                 schq[i] = max;
    1306                 :            :         }
    1307                 :          0 : }
    1308                 :            : 
    1309                 :            : bool
    1310                 :          0 : roc_nix_tm_root_has_sp(struct roc_nix *roc_nix)
    1311                 :            : {
    1312                 :            :         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
    1313                 :            : 
    1314         [ #  # ]:          0 :         if (nix->tm_flags & NIX_TM_TL1_NO_SP)
    1315                 :          0 :                 return false;
    1316                 :            :         return true;
    1317                 :            : }

Generated by: LCOV version 1.14