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