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 : : static int
9 : : nix_fc_rxchan_bpid_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
10 : : {
11 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
12 : :
13 [ # # ]: 0 : if (nix->chan_cnt != 0)
14 : 0 : fc_cfg->rxchan_cfg.enable = true;
15 : : else
16 : 0 : fc_cfg->rxchan_cfg.enable = false;
17 : :
18 : 0 : fc_cfg->type = ROC_NIX_FC_RXCHAN_CFG;
19 : :
20 : : return 0;
21 : : }
22 : :
23 : : static int
24 : 0 : nix_fc_rxchan_bpid_set(struct roc_nix *roc_nix, bool enable)
25 : : {
26 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
27 : : struct dev *dev = &nix->dev;
28 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
29 : : struct nix_bp_cfg_req *req;
30 : : struct nix_bp_cfg_rsp *rsp;
31 : : int rc = -ENOSPC, i;
32 : :
33 [ # # ]: 0 : if (enable) {
34 : 0 : req = mbox_alloc_msg_nix_bp_enable(mbox);
35 [ # # ]: 0 : if (req == NULL)
36 : 0 : goto exit;
37 : :
38 : 0 : req->chan_base = 0;
39 [ # # # # ]: 0 : if (roc_nix_is_lbk(roc_nix) || roc_nix_is_sdp(roc_nix))
40 : 0 : req->chan_cnt = NIX_LBK_MAX_CHAN;
41 : : else
42 : 0 : req->chan_cnt = NIX_CGX_MAX_CHAN;
43 : :
44 : 0 : req->bpid_per_chan = true;
45 : :
46 : : rc = mbox_process_msg(mbox, (void *)&rsp);
47 [ # # # # ]: 0 : if (rc || (req->chan_cnt != rsp->chan_cnt)) {
48 : : rc = -EIO;
49 : 0 : goto exit;
50 : : }
51 : :
52 : 0 : nix->chan_cnt = rsp->chan_cnt;
53 [ # # ]: 0 : for (i = 0; i < rsp->chan_cnt; i++)
54 : 0 : nix->bpid[i] = rsp->chan_bpid[i] & 0x1FF;
55 : : } else {
56 : 0 : req = mbox_alloc_msg_nix_bp_disable(mbox);
57 [ # # ]: 0 : if (req == NULL)
58 : 0 : goto exit;
59 : 0 : req->chan_base = 0;
60 : 0 : req->chan_cnt = nix->chan_cnt;
61 : :
62 : 0 : rc = mbox_process(mbox);
63 [ # # ]: 0 : if (rc)
64 : 0 : goto exit;
65 : :
66 : 0 : memset(nix->bpid, 0, sizeof(uint16_t) * NIX_MAX_CHAN);
67 : 0 : nix->chan_cnt = 0;
68 : : }
69 : :
70 [ # # ]: 0 : if (roc_model_is_cn9k())
71 : 0 : goto exit;
72 : :
73 : : /* Enable backpressure on CPT if inline inb is enabled */
74 [ # # # # : 0 : if (enable && roc_nix_inl_inb_is_enabled(roc_nix) &&
# # ]
75 : : !roc_errata_cpt_hang_on_x2p_bp()) {
76 : 0 : req = mbox_alloc_msg_nix_cpt_bp_enable(mbox);
77 [ # # ]: 0 : if (req == NULL)
78 : 0 : goto exit;
79 : 0 : req->chan_base = 0;
80 [ # # # # ]: 0 : if (roc_nix_is_lbk(roc_nix) || roc_nix_is_sdp(roc_nix))
81 : 0 : req->chan_cnt = NIX_LBK_MAX_CHAN;
82 : : else
83 : 0 : req->chan_cnt = NIX_CGX_MAX_CHAN;
84 : 0 : req->bpid_per_chan = 0;
85 : :
86 : : rc = mbox_process_msg(mbox, (void *)&rsp);
87 [ # # ]: 0 : if (rc)
88 : 0 : goto exit;
89 : 0 : nix->cpt_lbpid = rsp->chan_bpid[0] & 0x1FF;
90 : : }
91 : :
92 : : /* CPT to NIX BP on all channels */
93 [ # # # # ]: 0 : if (!roc_feature_nix_has_rxchan_multi_bpid() || !nix->cpt_nixbpid ||
94 : 0 : !roc_nix_inl_inb_is_enabled(roc_nix))
95 : 0 : goto exit;
96 : :
97 : : mbox_put(mbox);
98 [ # # ]: 0 : for (i = 0; i < nix->rx_chan_cnt; i++) {
99 : 0 : rc = roc_nix_chan_bpid_set(roc_nix, i, nix->cpt_nixbpid, enable, false);
100 [ # # ]: 0 : if (rc)
101 : : break;
102 : : }
103 : : return rc;
104 : 0 : exit:
105 : : mbox_put(mbox);
106 : 0 : return rc;
107 : : }
108 : :
109 : : static int
110 : 0 : nix_fc_cq_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
111 : : {
112 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
113 : : struct dev *dev = &nix->dev;
114 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
115 : : struct nix_aq_enq_rsp *rsp;
116 : : int rc;
117 : :
118 [ # # ]: 0 : if (roc_model_is_cn9k()) {
119 : : struct nix_aq_enq_req *aq;
120 : :
121 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
122 [ # # ]: 0 : if (!aq) {
123 : : rc = -ENOSPC;
124 : 0 : goto exit;
125 : : }
126 : :
127 : 0 : aq->qidx = fc_cfg->cq_cfg.rq;
128 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
129 : 0 : aq->op = NIX_AQ_INSTOP_READ;
130 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
131 : : struct nix_cn10k_aq_enq_req *aq;
132 : :
133 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
134 [ # # ]: 0 : if (!aq) {
135 : : rc = -ENOSPC;
136 : 0 : goto exit;
137 : : }
138 : :
139 : 0 : aq->qidx = fc_cfg->cq_cfg.rq;
140 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
141 : 0 : aq->op = NIX_AQ_INSTOP_READ;
142 : : } else {
143 : : struct nix_cn20k_aq_enq_req *aq;
144 : :
145 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
146 [ # # ]: 0 : if (!aq) {
147 : : rc = -ENOSPC;
148 : 0 : goto exit;
149 : : }
150 : :
151 : 0 : aq->qidx = fc_cfg->cq_cfg.rq;
152 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
153 : 0 : aq->op = NIX_AQ_INSTOP_READ;
154 : : }
155 : :
156 : : rc = mbox_process_msg(mbox, (void *)&rsp);
157 [ # # ]: 0 : if (rc)
158 : 0 : goto exit;
159 : :
160 : 0 : fc_cfg->cq_cfg.cq_drop = rsp->cq.drop;
161 : 0 : fc_cfg->cq_cfg.cq_bp = rsp->cq.bp;
162 : 0 : fc_cfg->cq_cfg.enable = rsp->cq.bp_ena;
163 : 0 : fc_cfg->type = ROC_NIX_FC_CQ_CFG;
164 : :
165 : 0 : exit:
166 : : mbox_put(mbox);
167 : 0 : return rc;
168 : : }
169 : :
170 : : static int
171 : 0 : nix_fc_rq_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
172 : : {
173 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
174 : : struct npa_cn20k_aq_enq_req *npa_req_cn20k;
175 : : struct npa_cn20k_aq_enq_rsp *npa_rsp_cn20k;
176 : : struct dev *dev = &nix->dev;
177 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
178 : : struct nix_aq_enq_rsp *rsp;
179 : : struct npa_aq_enq_req *npa_req;
180 : : struct npa_aq_enq_rsp *npa_rsp;
181 : : int rc;
182 : :
183 [ # # ]: 0 : if (roc_model_is_cn9k()) {
184 : : struct nix_aq_enq_req *aq;
185 : :
186 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
187 [ # # ]: 0 : if (!aq) {
188 : : rc = -ENOSPC;
189 : 0 : goto exit;
190 : : }
191 : :
192 : 0 : aq->qidx = fc_cfg->rq_cfg.rq;
193 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
194 : 0 : aq->op = NIX_AQ_INSTOP_READ;
195 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
196 : : struct nix_cn10k_aq_enq_req *aq;
197 : :
198 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
199 [ # # ]: 0 : if (!aq) {
200 : : rc = -ENOSPC;
201 : 0 : goto exit;
202 : : }
203 : :
204 : 0 : aq->qidx = fc_cfg->rq_cfg.rq;
205 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
206 : 0 : aq->op = NIX_AQ_INSTOP_READ;
207 : : } else {
208 : : struct nix_cn20k_aq_enq_req *aq;
209 : :
210 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
211 [ # # ]: 0 : if (!aq) {
212 : : rc = -ENOSPC;
213 : 0 : goto exit;
214 : : }
215 : :
216 : 0 : aq->qidx = fc_cfg->rq_cfg.rq;
217 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
218 : 0 : aq->op = NIX_AQ_INSTOP_READ;
219 : : }
220 : :
221 : : rc = mbox_process_msg(mbox, (void *)&rsp);
222 [ # # ]: 0 : if (rc)
223 : 0 : goto exit;
224 : :
225 [ # # ]: 0 : if (roc_model_is_cn20k()) {
226 : 0 : npa_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
227 [ # # ]: 0 : if (!npa_req_cn20k) {
228 : : rc = -ENOSPC;
229 : 0 : goto exit;
230 : : }
231 : :
232 : 0 : npa_req_cn20k->aura_id = rsp->rq.lpb_aura;
233 : 0 : npa_req_cn20k->ctype = NPA_AQ_CTYPE_AURA;
234 : 0 : npa_req_cn20k->op = NPA_AQ_INSTOP_READ;
235 : :
236 : : rc = mbox_process_msg(mbox, (void *)&npa_rsp_cn20k);
237 [ # # ]: 0 : if (rc)
238 : 0 : goto exit;
239 : :
240 : 0 : fc_cfg->cq_cfg.cq_drop = npa_rsp_cn20k->aura.bp;
241 : 0 : fc_cfg->cq_cfg.enable = npa_rsp_cn20k->aura.bp_ena;
242 : 0 : fc_cfg->type = ROC_NIX_FC_RQ_CFG;
243 : : } else {
244 : 0 : npa_req = mbox_alloc_msg_npa_aq_enq(mbox);
245 [ # # ]: 0 : if (!npa_req) {
246 : : rc = -ENOSPC;
247 : 0 : goto exit;
248 : : }
249 : :
250 : 0 : npa_req->aura_id = rsp->rq.lpb_aura;
251 : 0 : npa_req->ctype = NPA_AQ_CTYPE_AURA;
252 : 0 : npa_req->op = NPA_AQ_INSTOP_READ;
253 : :
254 : : rc = mbox_process_msg(mbox, (void *)&npa_rsp);
255 [ # # ]: 0 : if (rc)
256 : 0 : goto exit;
257 : :
258 : 0 : fc_cfg->cq_cfg.cq_drop = npa_rsp->aura.bp;
259 : 0 : fc_cfg->cq_cfg.enable = npa_rsp->aura.bp_ena;
260 : 0 : fc_cfg->type = ROC_NIX_FC_RQ_CFG;
261 : : }
262 : :
263 : 0 : exit:
264 : : mbox_put(mbox);
265 : 0 : return rc;
266 : : }
267 : :
268 : : static int
269 : 0 : nix_fc_cq_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
270 : : {
271 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
272 : : struct dev *dev = &nix->dev;
273 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
274 : : int rc;
275 : :
276 [ # # ]: 0 : if (roc_model_is_cn9k()) {
277 : : struct nix_aq_enq_req *aq;
278 : :
279 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
280 [ # # ]: 0 : if (!aq) {
281 : : rc = -ENOSPC;
282 : 0 : goto exit;
283 : : }
284 : :
285 : 0 : aq->qidx = fc_cfg->cq_cfg.rq;
286 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
287 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
288 : :
289 [ # # ]: 0 : if (fc_cfg->cq_cfg.enable) {
290 : 0 : aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
291 : 0 : aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
292 : 0 : aq->cq.bp = fc_cfg->cq_cfg.cq_bp;
293 : 0 : aq->cq_mask.bp = ~(aq->cq_mask.bp);
294 : : }
295 : :
296 : 0 : aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
297 : 0 : aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
298 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
299 : : struct nix_cn10k_aq_enq_req *aq;
300 : :
301 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
302 [ # # ]: 0 : if (!aq) {
303 : : rc = -ENOSPC;
304 : 0 : goto exit;
305 : : }
306 : :
307 : 0 : aq->qidx = fc_cfg->cq_cfg.rq;
308 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
309 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
310 : :
311 [ # # ]: 0 : if (fc_cfg->cq_cfg.enable) {
312 : 0 : aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
313 : 0 : aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
314 : 0 : aq->cq.bp = fc_cfg->cq_cfg.cq_bp;
315 : 0 : aq->cq_mask.bp = ~(aq->cq_mask.bp);
316 : : }
317 : :
318 : 0 : aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
319 : 0 : aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
320 : : } else {
321 : : struct nix_cn20k_aq_enq_req *aq;
322 : :
323 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
324 [ # # ]: 0 : if (!aq) {
325 : : rc = -ENOSPC;
326 : 0 : goto exit;
327 : : }
328 : :
329 : 0 : aq->qidx = fc_cfg->cq_cfg.rq;
330 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
331 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
332 : :
333 [ # # ]: 0 : if (fc_cfg->cq_cfg.enable) {
334 : 0 : aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
335 : 0 : aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
336 : 0 : aq->cq.bp = fc_cfg->cq_cfg.cq_bp;
337 : 0 : aq->cq_mask.bp = ~(aq->cq_mask.bp);
338 : : }
339 : :
340 : 0 : aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
341 : 0 : aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
342 : : }
343 : :
344 : 0 : rc = mbox_process(mbox);
345 : 0 : exit:
346 : : mbox_put(mbox);
347 : 0 : return rc;
348 : : }
349 : :
350 : : static int
351 : 0 : nix_fc_rq_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
352 : : {
353 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
354 : : uint64_t pool_drop_pct, spb_pool_drop_pct;
355 : : struct roc_nix_fc_cfg tmp;
356 : : struct roc_nix_rq *rq;
357 : : int rc;
358 : :
359 : 0 : rq = nix->rqs[fc_cfg->rq_cfg.rq];
360 : :
361 [ # # ]: 0 : if (rq->sso_ena) {
362 : 0 : pool_drop_pct = fc_cfg->rq_cfg.pool_drop_pct;
363 : : /* Use default value for zero pct */
364 [ # # # # ]: 0 : if (fc_cfg->rq_cfg.enable && !pool_drop_pct)
365 : : pool_drop_pct = ROC_NIX_AURA_THRESH;
366 : :
367 : 0 : roc_nix_fc_npa_bp_cfg(roc_nix, fc_cfg->rq_cfg.pool, fc_cfg->rq_cfg.enable,
368 : 0 : roc_nix->force_rx_aura_bp, fc_cfg->rq_cfg.tc, pool_drop_pct);
369 : :
370 [ # # ]: 0 : if (rq->spb_ena) {
371 : 0 : spb_pool_drop_pct = fc_cfg->rq_cfg.spb_pool_drop_pct;
372 : : /* Use default value for zero pct */
373 [ # # ]: 0 : if (!spb_pool_drop_pct)
374 : : spb_pool_drop_pct = ROC_NIX_AURA_THRESH;
375 : :
376 : 0 : roc_nix_fc_npa_bp_cfg(roc_nix, fc_cfg->rq_cfg.spb_pool,
377 : 0 : fc_cfg->rq_cfg.enable, roc_nix->force_rx_aura_bp,
378 : 0 : fc_cfg->rq_cfg.tc, spb_pool_drop_pct);
379 : : }
380 : :
381 [ # # # # ]: 0 : if (roc_nix->local_meta_aura_ena && roc_nix->meta_aura_handle)
382 : 0 : roc_nix_fc_npa_bp_cfg(roc_nix, roc_nix->meta_aura_handle,
383 : 0 : fc_cfg->rq_cfg.enable, roc_nix->force_rx_aura_bp,
384 : 0 : fc_cfg->rq_cfg.tc, pool_drop_pct);
385 : : }
386 : :
387 : : /* Copy RQ config to CQ config as they are occupying same area */
388 : : memset(&tmp, 0, sizeof(tmp));
389 : 0 : tmp.type = ROC_NIX_FC_CQ_CFG;
390 : 0 : tmp.cq_cfg.rq = fc_cfg->rq_cfg.rq;
391 : 0 : tmp.cq_cfg.tc = fc_cfg->rq_cfg.tc;
392 : 0 : tmp.cq_cfg.cq_drop = fc_cfg->rq_cfg.cq_drop;
393 : 0 : tmp.cq_cfg.cq_bp = fc_cfg->rq_cfg.cq_bp;
394 : 0 : tmp.cq_cfg.enable = fc_cfg->rq_cfg.enable;
395 : :
396 : 0 : rc = nix_fc_cq_config_set(roc_nix, &tmp);
397 [ # # ]: 0 : if (rc)
398 : : return rc;
399 : :
400 [ # # ]: 0 : rq->tc = fc_cfg->rq_cfg.enable ? fc_cfg->rq_cfg.tc : ROC_NIX_PFC_CLASS_INVALID;
401 [ # # ]: 0 : plt_nix_dbg("RQ %u: TC %u %s", fc_cfg->rq_cfg.rq, fc_cfg->rq_cfg.tc,
402 : : fc_cfg->rq_cfg.enable ? "enabled" : "disabled");
403 : 0 : return 0;
404 : : }
405 : :
406 : : int
407 : 0 : roc_nix_fc_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
408 : : {
409 [ # # # # : 0 : if (!roc_nix_is_pf(roc_nix) && !roc_nix_is_lbk(roc_nix) &&
# # ]
410 : 0 : !roc_nix_is_sdp(roc_nix))
411 : : return 0;
412 : :
413 [ # # ]: 0 : if (fc_cfg->type == ROC_NIX_FC_CQ_CFG)
414 : 0 : return nix_fc_cq_config_get(roc_nix, fc_cfg);
415 [ # # ]: 0 : else if (fc_cfg->type == ROC_NIX_FC_RQ_CFG)
416 : 0 : return nix_fc_rq_config_get(roc_nix, fc_cfg);
417 [ # # ]: 0 : else if (fc_cfg->type == ROC_NIX_FC_RXCHAN_CFG)
418 : 0 : return nix_fc_rxchan_bpid_get(roc_nix, fc_cfg);
419 [ # # ]: 0 : else if (fc_cfg->type == ROC_NIX_FC_TM_CFG)
420 : 0 : return nix_tm_bp_config_get(roc_nix, &fc_cfg->tm_cfg.enable);
421 : :
422 : : return -EINVAL;
423 : : }
424 : :
425 : : int
426 : 0 : roc_nix_fc_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
427 : : {
428 [ # # ]: 0 : if (fc_cfg->type == ROC_NIX_FC_CQ_CFG)
429 : 0 : return nix_fc_cq_config_set(roc_nix, fc_cfg);
430 [ # # ]: 0 : else if (fc_cfg->type == ROC_NIX_FC_RQ_CFG)
431 : 0 : return nix_fc_rq_config_set(roc_nix, fc_cfg);
432 [ # # ]: 0 : else if (fc_cfg->type == ROC_NIX_FC_RXCHAN_CFG)
433 : 0 : return nix_fc_rxchan_bpid_set(roc_nix,
434 : 0 : fc_cfg->rxchan_cfg.enable);
435 [ # # ]: 0 : else if (fc_cfg->type == ROC_NIX_FC_TM_CFG)
436 : 0 : return nix_tm_bp_config_set(roc_nix, fc_cfg->tm_cfg.sq,
437 : 0 : fc_cfg->tm_cfg.tc,
438 : 0 : fc_cfg->tm_cfg.enable);
439 : :
440 : : return -EINVAL;
441 : : }
442 : :
443 : : enum roc_nix_fc_mode
444 : 0 : roc_nix_fc_mode_get(struct roc_nix *roc_nix)
445 : : {
446 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
447 : : enum roc_nix_fc_mode mode;
448 : :
449 [ # # # # ]: 0 : if (nix->tx_pause && nix->rx_pause)
450 : : mode = ROC_NIX_FC_FULL;
451 [ # # ]: 0 : else if (nix->rx_pause)
452 : : mode = ROC_NIX_FC_RX;
453 [ # # ]: 0 : else if (nix->tx_pause)
454 : : mode = ROC_NIX_FC_TX;
455 : : else
456 : : mode = ROC_NIX_FC_NONE;
457 : 0 : return mode;
458 : : }
459 : :
460 : : int
461 : 0 : roc_nix_fc_mode_set(struct roc_nix *roc_nix, enum roc_nix_fc_mode mode)
462 : : {
463 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
464 : : struct dev *dev = &nix->dev;
465 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
466 : : struct cgx_pause_frm_cfg *req;
467 : : uint8_t tx_pause, rx_pause;
468 : : int rc = -ENOSPC;
469 : :
470 : 0 : rx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_RX);
471 : 0 : tx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_TX);
472 : :
473 : : /* Nothing much to do for LBK links */
474 [ # # ]: 0 : if (roc_nix_is_lbk(roc_nix)) {
475 : 0 : nix->rx_pause = rx_pause;
476 : 0 : nix->tx_pause = tx_pause;
477 : : rc = 0;
478 : 0 : goto exit;
479 : : }
480 : :
481 : : /* Set new config */
482 : 0 : req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
483 [ # # ]: 0 : if (req == NULL)
484 : 0 : goto exit;
485 : 0 : req->set = 1;
486 : 0 : req->rx_pause = rx_pause;
487 : 0 : req->tx_pause = tx_pause;
488 : :
489 : 0 : rc = mbox_process(mbox);
490 [ # # ]: 0 : if (rc)
491 : 0 : goto exit;
492 : :
493 : 0 : nix->rx_pause = rx_pause;
494 : 0 : nix->tx_pause = tx_pause;
495 : 0 : exit:
496 : : mbox_put(mbox);
497 : 0 : return rc;
498 : : }
499 : :
500 : : static int
501 [ # # ]: 0 : nix_rx_chan_multi_bpid_cfg(struct roc_nix *roc_nix, uint8_t chan, uint16_t bpid, uint16_t *bpid_new)
502 : : {
503 : : struct roc_nix *roc_nix_tmp, *roc_nix_pre = NULL;
504 : : struct roc_nix_list *nix_list;
505 : : uint8_t chan_pre;
506 : :
507 : : if (!roc_feature_nix_has_rxchan_multi_bpid())
508 : : return -ENOTSUP;
509 : :
510 : 0 : nix_list = roc_idev_nix_list_get();
511 [ # # ]: 0 : if (nix_list == NULL)
512 : : return -EINVAL;
513 : :
514 : : /* Find associated NIX RX channel if Aura BPID is of that of a NIX. */
515 [ # # ]: 0 : TAILQ_FOREACH(roc_nix_tmp, nix_list, next) {
516 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix_tmp);
517 : : int i;
518 : :
519 [ # # ]: 0 : for (i = 0; i < NIX_MAX_CHAN; i++) {
520 [ # # ]: 0 : if (nix->bpid[i] == bpid)
521 : : break;
522 : : }
523 : :
524 [ # # ]: 0 : if (i < NIX_MAX_CHAN) {
525 : : roc_nix_pre = roc_nix_tmp;
526 : 0 : chan_pre = i;
527 : 0 : break;
528 : : }
529 : : }
530 : :
531 : : /* Alloc and configure a new BPID if Aura BPID is that of a NIX. */
532 [ # # ]: 0 : if (roc_nix_pre) {
533 [ # # ]: 0 : if (roc_nix_bpids_alloc(roc_nix, ROC_NIX_INTF_TYPE_SSO, 1, bpid_new) <= 0)
534 : : return -ENOSPC;
535 : :
536 [ # # ]: 0 : if (roc_nix_chan_bpid_set(roc_nix_pre, chan_pre, *bpid_new, 1, false) < 0)
537 : : return -ENOSPC;
538 : :
539 [ # # ]: 0 : if (roc_nix_chan_bpid_set(roc_nix, chan, *bpid_new, 1, false) < 0)
540 : : return -ENOSPC;
541 : :
542 : 0 : return 0;
543 : : } else {
544 : 0 : return roc_nix_chan_bpid_set(roc_nix, chan, bpid, 1, false);
545 : : }
546 : :
547 : : return 0;
548 : : }
549 : :
550 : : #define NIX_BPID_INVALID 0xFFFF
551 : :
552 : : void
553 : 0 : roc_nix_fc_npa_bp_cfg(struct roc_nix *roc_nix, uint64_t pool_id, uint8_t ena, uint8_t force,
554 : : uint8_t tc, uint64_t drop_percent)
555 : : {
556 : : uint32_t aura_id = roc_npa_aura_handle_to_aura(pool_id);
557 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
558 : 0 : struct npa_lf *lf = idev_npa_obj_get();
559 : : struct npa_aura_attr *aura_attr;
560 : : uint8_t bp_thresh, bp_intf;
561 : : uint16_t bpid;
562 : : int i;
563 : :
564 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
565 : : return;
566 : :
567 [ # # ]: 0 : if (!lf)
568 : : return;
569 : :
570 : 0 : aura_attr = &lf->aura_attr[aura_id];
571 : :
572 : 0 : bp_intf = 1 << nix->is_nix1;
573 : 0 : bp_thresh = NIX_RQ_AURA_BP_THRESH(drop_percent, aura_attr->limit, aura_attr->shift);
574 : :
575 [ # # ]: 0 : bpid = (aura_attr->bp_ena & 0x1) ? aura_attr->nix0_bpid : aura_attr->nix1_bpid;
576 : : /* BP is already enabled. */
577 [ # # # # ]: 0 : if (aura_attr->bp_ena && ena) {
578 [ # # ]: 0 : if (bpid != nix->bpid[tc]) {
579 : 0 : uint16_t bpid_new = NIX_BPID_INVALID;
580 : :
581 [ # # # # ]: 0 : if (force && !nix_rx_chan_multi_bpid_cfg(roc_nix, tc, bpid, &bpid_new)) {
582 : 0 : plt_info("Setting up shared BPID on shared aura 0x%" PRIx64,
583 : : pool_id);
584 : :
585 : : /* Configure Aura with new BPID if it is allocated. */
586 [ # # ]: 0 : if (roc_npa_aura_bp_configure(pool_id, bpid_new, bp_intf, bp_thresh,
587 : : true))
588 : 0 : plt_err("Enabling backpressue failed on aura 0x%" PRIx64,
589 : : pool_id);
590 : : } else {
591 : 0 : aura_attr->ref_count++;
592 : 0 : plt_info("Ignoring port=%u tc=%u config on shared aura 0x%" PRIx64,
593 : : roc_nix->port_id, tc, pool_id);
594 : : }
595 : : } else {
596 : 0 : aura_attr->ref_count++;
597 : : }
598 : :
599 : 0 : return;
600 : : }
601 : :
602 [ # # ]: 0 : if (ena) {
603 [ # # ]: 0 : if (roc_npa_aura_bp_configure(pool_id, nix->bpid[tc], bp_intf, bp_thresh, true))
604 : 0 : plt_err("Enabling backpressue failed on aura 0x%" PRIx64, pool_id);
605 : : else
606 : 0 : aura_attr->ref_count++;
607 : : } else {
608 : 0 : bool found = !!force;
609 : :
610 : : /* Don't disable if existing BPID is not within this port's list */
611 [ # # ]: 0 : for (i = 0; i < nix->chan_cnt; i++)
612 [ # # ]: 0 : if (bpid == nix->bpid[i])
613 : : found = true;
614 [ # # ]: 0 : if (!found)
615 : : return;
616 [ # # # # ]: 0 : else if ((aura_attr->ref_count > 0) && --(aura_attr->ref_count))
617 : : return;
618 : :
619 [ # # ]: 0 : if (roc_npa_aura_bp_configure(pool_id, 0, 0, 0, false))
620 : 0 : plt_err("Disabling backpressue failed on aura 0x%" PRIx64, pool_id);
621 : : }
622 : :
623 : : return;
624 : : }
625 : :
626 : : int
627 : 0 : roc_nix_pfc_mode_set(struct roc_nix *roc_nix, struct roc_nix_pfc_cfg *pfc_cfg)
628 : : {
629 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
630 : : struct dev *dev = &nix->dev;
631 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
632 : : uint8_t tx_pause, rx_pause;
633 : : struct cgx_pfc_cfg *req;
634 : : struct cgx_pfc_rsp *rsp;
635 : : int rc = -ENOSPC;
636 : :
637 [ # # ]: 0 : if (roc_nix_is_lbk(roc_nix)) {
638 : : rc = NIX_ERR_OP_NOTSUP;
639 : 0 : goto exit;
640 : : }
641 : :
642 : 0 : rx_pause = (pfc_cfg->mode == ROC_NIX_FC_FULL) ||
643 : : (pfc_cfg->mode == ROC_NIX_FC_RX);
644 : 0 : tx_pause = (pfc_cfg->mode == ROC_NIX_FC_FULL) ||
645 : : (pfc_cfg->mode == ROC_NIX_FC_TX);
646 : :
647 : 0 : req = mbox_alloc_msg_cgx_prio_flow_ctrl_cfg(mbox);
648 [ # # ]: 0 : if (req == NULL)
649 : 0 : goto exit;
650 : :
651 : 0 : req->pfc_en = pfc_cfg->tc;
652 : 0 : req->rx_pause = rx_pause;
653 : 0 : req->tx_pause = tx_pause;
654 : :
655 : : rc = mbox_process_msg(mbox, (void *)&rsp);
656 [ # # ]: 0 : if (rc)
657 : 0 : goto exit;
658 : :
659 : 0 : nix->pfc_rx_pause = rsp->rx_pause;
660 : 0 : nix->pfc_tx_pause = rsp->tx_pause;
661 [ # # ]: 0 : if (rsp->tx_pause)
662 : 0 : nix->cev |= BIT(pfc_cfg->tc);
663 : : else
664 : 0 : nix->cev &= ~BIT(pfc_cfg->tc);
665 : :
666 : 0 : exit:
667 : : mbox_put(mbox);
668 : 0 : return rc;
669 : : }
670 : :
671 : : int
672 : 0 : roc_nix_pfc_mode_get(struct roc_nix *roc_nix, struct roc_nix_pfc_cfg *pfc_cfg)
673 : : {
674 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
675 : :
676 [ # # ]: 0 : if (roc_nix_is_lbk(roc_nix))
677 : : return NIX_ERR_OP_NOTSUP;
678 : :
679 : 0 : pfc_cfg->tc = nix->cev;
680 : :
681 [ # # # # ]: 0 : if (nix->pfc_rx_pause && nix->pfc_tx_pause)
682 : 0 : pfc_cfg->mode = ROC_NIX_FC_FULL;
683 [ # # ]: 0 : else if (nix->pfc_rx_pause)
684 : 0 : pfc_cfg->mode = ROC_NIX_FC_RX;
685 [ # # ]: 0 : else if (nix->pfc_tx_pause)
686 : 0 : pfc_cfg->mode = ROC_NIX_FC_TX;
687 : : else
688 : 0 : pfc_cfg->mode = ROC_NIX_FC_NONE;
689 : :
690 : : return 0;
691 : : }
692 : :
693 : : uint16_t
694 : 0 : roc_nix_chan_count_get(struct roc_nix *roc_nix)
695 : : {
696 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
697 : :
698 : 0 : return nix->chan_cnt;
699 : : }
700 : :
701 : : /* Allocate BPID for requested type
702 : : * Returns number of BPIDs allocated
703 : : * 0 if no BPIDs available
704 : : * -ve value on error
705 : : */
706 : : int
707 : 0 : nix_bpids_alloc(struct dev *dev, uint8_t type, uint8_t bp_cnt, uint16_t *bpids)
708 : : {
709 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
710 : : struct nix_alloc_bpid_req *req;
711 : : struct nix_bpids *rsp;
712 : : int rc = -EINVAL;
713 : :
714 : : /* Use this api for unreserved interface types */
715 [ # # # # ]: 0 : if ((type < ROC_NIX_INTF_TYPE_RSVD) || (bp_cnt > ROC_NIX_MAX_BPID_CNT) || !bpids)
716 : 0 : goto exit;
717 : :
718 : : rc = -ENOSPC;
719 : 0 : req = mbox_alloc_msg_nix_alloc_bpids(mbox);
720 [ # # ]: 0 : if (req == NULL)
721 : 0 : goto exit;
722 : 0 : req->type = type;
723 : 0 : req->bpid_cnt = bp_cnt;
724 : :
725 : : rc = mbox_process_msg(mbox, (void *)&rsp);
726 [ # # ]: 0 : if (rc)
727 : 0 : goto exit;
728 : :
729 [ # # ]: 0 : for (rc = 0; rc < rsp->bpid_cnt; rc++)
730 : 0 : bpids[rc] = rsp->bpids[rc];
731 : 0 : exit:
732 : : mbox_put(mbox);
733 : 0 : return rc;
734 : : }
735 : :
736 : : int
737 : 0 : nix_bpids_free(struct dev *dev, uint8_t bp_cnt, uint16_t *bpids)
738 : : {
739 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
740 : : struct nix_bpids *req;
741 : : int rc = -EINVAL;
742 : :
743 : : /* Use this api for unreserved interface types */
744 [ # # ]: 0 : if ((bp_cnt > ROC_NIX_MAX_BPID_CNT) || !bpids)
745 : 0 : goto exit;
746 : :
747 : : rc = -ENOSPC;
748 : 0 : req = mbox_alloc_msg_nix_free_bpids(mbox);
749 [ # # ]: 0 : if (req == NULL)
750 : 0 : goto exit;
751 [ # # ]: 0 : for (rc = 0; rc < bp_cnt; rc++)
752 : 0 : req->bpids[rc] = bpids[rc];
753 : 0 : req->bpid_cnt = rc;
754 : :
755 : 0 : rc = mbox_process(mbox);
756 : 0 : exit:
757 : : mbox_put(mbox);
758 : 0 : return rc;
759 : : }
760 : :
761 : : int
762 : 0 : roc_nix_bpids_alloc(struct roc_nix *roc_nix, uint8_t type, uint8_t bp_cnt, uint16_t *bpids)
763 : : {
764 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
765 : 0 : return nix_bpids_alloc(&nix->dev, type, bp_cnt, bpids);
766 : : }
767 : :
768 : : int
769 : 0 : roc_nix_bpids_free(struct roc_nix *roc_nix, uint8_t bp_cnt, uint16_t *bpids)
770 : : {
771 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
772 : 0 : return nix_bpids_free(&nix->dev, bp_cnt, bpids);
773 : : }
774 : :
775 : : int
776 : 0 : roc_nix_rx_chan_cfg_get(struct roc_nix *roc_nix, uint16_t chan, bool is_cpt, uint64_t *cfg)
777 : : {
778 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
779 : 0 : struct mbox *mbox = mbox_get(nix->dev.mbox);
780 : : struct nix_rx_chan_cfg *req;
781 : : struct nix_rx_chan_cfg *rsp;
782 : : int rc = -EINVAL;
783 : :
784 : 0 : req = mbox_alloc_msg_nix_rx_chan_cfg(mbox);
785 [ # # ]: 0 : if (req == NULL)
786 : 0 : goto exit;
787 [ # # ]: 0 : if (is_cpt)
788 : 0 : req->type = ROC_NIX_INTF_TYPE_CPT;
789 : 0 : req->chan = chan;
790 : 0 : req->read = 1;
791 : :
792 : : rc = mbox_process_msg(mbox, (void *)&rsp);
793 [ # # ]: 0 : if (rc)
794 : 0 : goto exit;
795 : 0 : *cfg = rsp->val;
796 : 0 : exit:
797 : : mbox_put(mbox);
798 : 0 : return rc;
799 : : }
800 : :
801 : : int
802 : 0 : roc_nix_rx_chan_cfg_set(struct roc_nix *roc_nix, uint16_t chan, bool is_cpt, uint64_t val)
803 : : {
804 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
805 : 0 : struct mbox *mbox = mbox_get(nix->dev.mbox);
806 : : struct nix_rx_chan_cfg *req;
807 : : int rc = -EINVAL;
808 : :
809 : 0 : req = mbox_alloc_msg_nix_rx_chan_cfg(mbox);
810 [ # # ]: 0 : if (req == NULL)
811 : 0 : goto exit;
812 [ # # ]: 0 : if (is_cpt)
813 : 0 : req->type = ROC_NIX_INTF_TYPE_CPT;
814 : 0 : req->chan = chan;
815 : 0 : req->val = val;
816 : 0 : req->read = 0;
817 : :
818 : 0 : rc = mbox_process(mbox);
819 : 0 : exit:
820 : : mbox_put(mbox);
821 : 0 : return rc;
822 : : }
823 : :
824 : : #define NIX_BPID1_ENA 15
825 : : #define NIX_BPID2_ENA 14
826 : : #define NIX_BPID3_ENA 13
827 : :
828 : : #define NIX_BPID1_OFF 20
829 : : #define NIX_BPID2_OFF 32
830 : : #define NIX_BPID3_OFF 44
831 : :
832 : : int
833 [ # # ]: 0 : roc_nix_chan_bpid_set(struct roc_nix *roc_nix, uint16_t chan, uint64_t bpid, int ena, bool cpt_chan)
834 : : {
835 : : uint64_t cfg;
836 : : int rc;
837 : :
838 : : if (!roc_feature_nix_has_rxchan_multi_bpid())
839 : : return -ENOTSUP;
840 : :
841 : 0 : rc = roc_nix_rx_chan_cfg_get(roc_nix, chan, cpt_chan, &cfg);
842 [ # # ]: 0 : if (rc)
843 : : return rc;
844 : :
845 [ # # ]: 0 : if (ena) {
846 [ # # ]: 0 : if ((((cfg >> NIX_BPID1_OFF) & GENMASK_ULL(8, 0)) == bpid) ||
847 [ # # ]: 0 : (((cfg >> NIX_BPID2_OFF) & GENMASK_ULL(8, 0)) == bpid) ||
848 [ # # ]: 0 : (((cfg >> NIX_BPID3_OFF) & GENMASK_ULL(8, 0)) == bpid))
849 : : return 0;
850 : :
851 [ # # ]: 0 : if (!(cfg & BIT_ULL(NIX_BPID1_ENA))) {
852 : 0 : cfg &= ~GENMASK_ULL(NIX_BPID1_OFF + 8, NIX_BPID1_OFF);
853 : 0 : cfg |= (((uint64_t)bpid << NIX_BPID1_OFF) | BIT_ULL(NIX_BPID1_ENA));
854 [ # # ]: 0 : } else if (!(cfg & BIT_ULL(NIX_BPID2_ENA))) {
855 : 0 : cfg &= ~GENMASK_ULL(NIX_BPID2_OFF + 8, NIX_BPID2_OFF);
856 : 0 : cfg |= (((uint64_t)bpid << NIX_BPID2_OFF) | BIT_ULL(NIX_BPID2_ENA));
857 [ # # ]: 0 : } else if (!(cfg & BIT_ULL(NIX_BPID3_ENA))) {
858 : 0 : cfg &= ~GENMASK_ULL(NIX_BPID3_OFF + 8, NIX_BPID3_OFF);
859 : 0 : cfg |= (((uint64_t)bpid << NIX_BPID3_OFF) | BIT_ULL(NIX_BPID3_ENA));
860 : : } else {
861 : 0 : plt_nix_dbg("Exceed maximum BPIDs");
862 : 0 : return -ENOSPC;
863 : : }
864 : : } else {
865 [ # # ]: 0 : if (((cfg >> NIX_BPID1_OFF) & GENMASK_ULL(8, 0)) == bpid) {
866 : 0 : cfg &= ~(GENMASK_ULL(NIX_BPID1_OFF + 8, NIX_BPID1_OFF) |
867 : : BIT_ULL(NIX_BPID1_ENA));
868 [ # # ]: 0 : } else if (((cfg >> NIX_BPID2_OFF) & GENMASK_ULL(8, 0)) == bpid) {
869 : 0 : cfg &= ~(GENMASK_ULL(NIX_BPID2_OFF + 8, NIX_BPID2_OFF) |
870 : : BIT_ULL(NIX_BPID2_ENA));
871 [ # # ]: 0 : } else if (((cfg >> NIX_BPID3_OFF) & GENMASK_ULL(8, 0)) == bpid) {
872 : 0 : cfg &= ~(GENMASK_ULL(NIX_BPID3_OFF + 8, NIX_BPID3_OFF) |
873 : : BIT_ULL(NIX_BPID3_ENA));
874 : : } else {
875 : 0 : plt_nix_dbg("BPID not found");
876 : 0 : return -EINVAL;
877 : : }
878 : : }
879 : 0 : return roc_nix_rx_chan_cfg_set(roc_nix, chan, cpt_chan, cfg);
880 : : }
|