common/cnxk: support add/delete NIX TM node
[dpdk.git] / drivers / common / cnxk / roc_nix_tm_ops.c
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 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         plt_tm_dbg("Setting SQ %u SQB aura FC to %s", sq->qid,
19                    enable ? "enable" : "disable");
20
21         lf = idev_npa_obj_get();
22         if (!lf)
23                 return NPA_ERR_DEVICE_NOT_BOUNDED;
24
25         mbox = lf->mbox;
26         /* Set/clear sqb aura fc_ena */
27         aura_handle = sq->aura_handle;
28         req = mbox_alloc_msg_npa_aq_enq(mbox);
29         if (req == NULL)
30                 return rc;
31
32         req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
33         req->ctype = NPA_AQ_CTYPE_AURA;
34         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         req->aura.pool_addr = req->aura_id;
38
39         req->aura.fc_ena = enable;
40         req->aura_mask.fc_ena = 1;
41
42         rc = mbox_process(mbox);
43         if (rc)
44                 return rc;
45
46         /* Read back npa aura ctx */
47         req = mbox_alloc_msg_npa_aq_enq(mbox);
48         if (req == NULL)
49                 return -ENOSPC;
50
51         req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
52         req->ctype = NPA_AQ_CTYPE_AURA;
53         req->op = NPA_AQ_INSTOP_READ;
54
55         rc = mbox_process_msg(mbox, (void *)&rsp);
56         if (rc)
57                 return rc;
58
59         /* Init when enabled as there might be no triggers */
60         if (enable)
61                 *(volatile uint64_t *)sq->fc = rsp->aura.count;
62         else
63                 *(volatile uint64_t *)sq->fc = sq->nb_sqb_bufs;
64         /* Sync write barrier */
65         plt_wmb();
66         return 0;
67 }
68
69 int
70 roc_nix_tm_node_add(struct roc_nix *roc_nix, struct roc_nix_tm_node *roc_node)
71 {
72         struct nix_tm_node *node;
73
74         node = (struct nix_tm_node *)&roc_node->reserved;
75         node->id = roc_node->id;
76         node->priority = roc_node->priority;
77         node->weight = roc_node->weight;
78         node->lvl = roc_node->lvl;
79         node->parent_id = roc_node->parent_id;
80         node->shaper_profile_id = roc_node->shaper_profile_id;
81         node->pkt_mode = roc_node->pkt_mode;
82         node->pkt_mode_set = roc_node->pkt_mode_set;
83         node->free_fn = roc_node->free_fn;
84         node->tree = ROC_NIX_TM_USER;
85
86         return nix_tm_node_add(roc_nix, node);
87 }
88
89 int
90 roc_nix_tm_node_pkt_mode_update(struct roc_nix *roc_nix, uint32_t node_id,
91                                 bool pkt_mode)
92 {
93         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
94         struct nix_tm_node *node, *child;
95         struct nix_tm_node_list *list;
96         int num_children = 0;
97
98         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
99         if (!node)
100                 return NIX_ERR_TM_INVALID_NODE;
101
102         if (node->pkt_mode == pkt_mode) {
103                 node->pkt_mode_set = true;
104                 return 0;
105         }
106
107         /* Check for any existing children, if there are any,
108          * then we cannot update the pkt mode as children's quantum
109          * are already taken in.
110          */
111         list = nix_tm_node_list(nix, ROC_NIX_TM_USER);
112         TAILQ_FOREACH(child, list, node) {
113                 if (child->parent == node)
114                         num_children++;
115         }
116
117         /* Cannot update mode if it has children or tree is enabled */
118         if ((nix->tm_flags & NIX_TM_HIERARCHY_ENA) && num_children)
119                 return -EBUSY;
120
121         if (node->pkt_mode_set && num_children)
122                 return NIX_ERR_TM_PKT_MODE_MISMATCH;
123
124         node->pkt_mode = pkt_mode;
125         node->pkt_mode_set = true;
126
127         return 0;
128 }
129
130 int
131 roc_nix_tm_node_name_get(struct roc_nix *roc_nix, uint32_t node_id, char *buf,
132                          size_t buflen)
133 {
134         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
135         struct nix_tm_node *node;
136
137         node = nix_tm_node_search(nix, node_id, ROC_NIX_TM_USER);
138         if (!node) {
139                 plt_strlcpy(buf, "???", buflen);
140                 return NIX_ERR_TM_INVALID_NODE;
141         }
142
143         if (node->hw_lvl == NIX_TXSCH_LVL_CNT)
144                 snprintf(buf, buflen, "SQ_%d", node->id);
145         else
146                 snprintf(buf, buflen, "%s_%d", nix_tm_hwlvl2str(node->hw_lvl),
147                          node->hw_id);
148         return 0;
149 }
150
151 int
152 roc_nix_tm_node_delete(struct roc_nix *roc_nix, uint32_t node_id, bool free)
153 {
154         return nix_tm_node_delete(roc_nix, node_id, ROC_NIX_TM_USER, free);
155 }