common/cnxk: allow building for generic arm64
[dpdk.git] / drivers / common / cnxk / roc_nix_fc.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 static inline struct mbox *
9 get_mbox(struct roc_nix *roc_nix)
10 {
11         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
12         struct dev *dev = &nix->dev;
13
14         return dev->mbox;
15 }
16
17 static int
18 nix_fc_rxchan_bpid_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
19 {
20         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
21
22         if (nix->chan_cnt != 0)
23                 fc_cfg->rxchan_cfg.enable = true;
24         else
25                 fc_cfg->rxchan_cfg.enable = false;
26
27         fc_cfg->type = ROC_NIX_FC_RXCHAN_CFG;
28
29         return 0;
30 }
31
32 static int
33 nix_fc_rxchan_bpid_set(struct roc_nix *roc_nix, bool enable)
34 {
35         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
36         struct mbox *mbox = get_mbox(roc_nix);
37         struct nix_bp_cfg_req *req;
38         struct nix_bp_cfg_rsp *rsp;
39         int rc = -ENOSPC, i;
40
41         if (enable) {
42                 req = mbox_alloc_msg_nix_bp_enable(mbox);
43                 if (req == NULL)
44                         return rc;
45
46                 req->chan_base = 0;
47                 if (roc_nix_is_lbk(roc_nix) || roc_nix_is_sdp(roc_nix))
48                         req->chan_cnt = NIX_LBK_MAX_CHAN;
49                 else
50                         req->chan_cnt = NIX_CGX_MAX_CHAN;
51
52                 req->bpid_per_chan = true;
53
54                 rc = mbox_process_msg(mbox, (void *)&rsp);
55                 if (rc || (req->chan_cnt != rsp->chan_cnt))
56                         goto exit;
57
58                 nix->chan_cnt = rsp->chan_cnt;
59                 for (i = 0; i < rsp->chan_cnt; i++)
60                         nix->bpid[i] = rsp->chan_bpid[i] & 0x1FF;
61         } else {
62                 req = mbox_alloc_msg_nix_bp_disable(mbox);
63                 if (req == NULL)
64                         return rc;
65                 req->chan_base = 0;
66                 req->chan_cnt = nix->chan_cnt;
67
68                 rc = mbox_process(mbox);
69                 if (rc)
70                         goto exit;
71
72                 memset(nix->bpid, 0, sizeof(uint16_t) * NIX_MAX_CHAN);
73                 nix->chan_cnt = 0;
74         }
75
76         if (roc_model_is_cn9k())
77                 goto exit;
78
79         /* Enable backpressure on CPT if inline inb is enabled */
80         if (enable && roc_nix_inl_inb_is_enabled(roc_nix)) {
81                 req = mbox_alloc_msg_nix_cpt_bp_enable(mbox);
82                 if (req == NULL)
83                         return rc;
84                 req->chan_base = 0;
85                 req->chan_cnt = 1;
86                 req->bpid_per_chan = 0;
87
88                 rc = mbox_process_msg(mbox, (void *)&rsp);
89                 if (rc)
90                         goto exit;
91         } else {
92                 req = mbox_alloc_msg_nix_cpt_bp_disable(mbox);
93                 if (req == NULL)
94                         return rc;
95                 req->chan_base = 0;
96                 req->chan_cnt = 1;
97                 req->bpid_per_chan = 0;
98
99                 rc = mbox_process_msg(mbox, (void *)&rsp);
100                 if (rc)
101                         goto exit;
102         }
103
104 exit:
105         return rc;
106 }
107
108 static int
109 nix_fc_cq_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
110 {
111         struct mbox *mbox = get_mbox(roc_nix);
112         struct nix_aq_enq_rsp *rsp;
113         int rc;
114
115         if (roc_model_is_cn9k()) {
116                 struct nix_aq_enq_req *aq;
117
118                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
119                 if (!aq)
120                         return -ENOSPC;
121
122                 aq->qidx = fc_cfg->cq_cfg.rq;
123                 aq->ctype = NIX_AQ_CTYPE_CQ;
124                 aq->op = NIX_AQ_INSTOP_READ;
125         } else {
126                 struct nix_cn10k_aq_enq_req *aq;
127
128                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
129                 if (!aq)
130                         return -ENOSPC;
131
132                 aq->qidx = fc_cfg->cq_cfg.rq;
133                 aq->ctype = NIX_AQ_CTYPE_CQ;
134                 aq->op = NIX_AQ_INSTOP_READ;
135         }
136
137         rc = mbox_process_msg(mbox, (void *)&rsp);
138         if (rc)
139                 goto exit;
140
141         fc_cfg->cq_cfg.cq_drop = rsp->cq.bp;
142         fc_cfg->cq_cfg.enable = rsp->cq.bp_ena;
143         fc_cfg->type = ROC_NIX_FC_CQ_CFG;
144
145 exit:
146         return rc;
147 }
148
149 static int
150 nix_fc_cq_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
151 {
152         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
153         struct mbox *mbox = get_mbox(roc_nix);
154
155         if (roc_model_is_cn9k()) {
156                 struct nix_aq_enq_req *aq;
157
158                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
159                 if (!aq)
160                         return -ENOSPC;
161
162                 aq->qidx = fc_cfg->cq_cfg.rq;
163                 aq->ctype = NIX_AQ_CTYPE_CQ;
164                 aq->op = NIX_AQ_INSTOP_WRITE;
165
166                 if (fc_cfg->cq_cfg.enable) {
167                         aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
168                         aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
169                         aq->cq.bp = fc_cfg->cq_cfg.cq_drop;
170                         aq->cq_mask.bp = ~(aq->cq_mask.bp);
171                 }
172
173                 aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
174                 aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
175         } else {
176                 struct nix_cn10k_aq_enq_req *aq;
177
178                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
179                 if (!aq)
180                         return -ENOSPC;
181
182                 aq->qidx = fc_cfg->cq_cfg.rq;
183                 aq->ctype = NIX_AQ_CTYPE_CQ;
184                 aq->op = NIX_AQ_INSTOP_WRITE;
185
186                 if (fc_cfg->cq_cfg.enable) {
187                         aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
188                         aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
189                         aq->cq.bp = fc_cfg->cq_cfg.cq_drop;
190                         aq->cq_mask.bp = ~(aq->cq_mask.bp);
191                 }
192
193                 aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
194                 aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
195         }
196
197         return mbox_process(mbox);
198 }
199
200 int
201 roc_nix_fc_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
202 {
203         if (!roc_nix_is_pf(roc_nix) && !roc_nix_is_lbk(roc_nix) &&
204             !roc_nix_is_sdp(roc_nix))
205                 return 0;
206
207         if (fc_cfg->type == ROC_NIX_FC_CQ_CFG)
208                 return nix_fc_cq_config_get(roc_nix, fc_cfg);
209         else if (fc_cfg->type == ROC_NIX_FC_RXCHAN_CFG)
210                 return nix_fc_rxchan_bpid_get(roc_nix, fc_cfg);
211         else if (fc_cfg->type == ROC_NIX_FC_TM_CFG)
212                 return nix_tm_bp_config_get(roc_nix, &fc_cfg->tm_cfg.enable);
213
214         return -EINVAL;
215 }
216
217 int
218 roc_nix_fc_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
219 {
220         if (!roc_nix_is_pf(roc_nix) && !roc_nix_is_lbk(roc_nix) &&
221             !roc_nix_is_sdp(roc_nix))
222                 return 0;
223
224         if (fc_cfg->type == ROC_NIX_FC_CQ_CFG)
225                 return nix_fc_cq_config_set(roc_nix, fc_cfg);
226         else if (fc_cfg->type == ROC_NIX_FC_RXCHAN_CFG)
227                 return nix_fc_rxchan_bpid_set(roc_nix,
228                                               fc_cfg->rxchan_cfg.enable);
229         else if (fc_cfg->type == ROC_NIX_FC_TM_CFG)
230                 return nix_tm_bp_config_set(roc_nix, fc_cfg->tm_cfg.sq,
231                                             fc_cfg->tm_cfg.tc,
232                                             fc_cfg->tm_cfg.enable);
233
234         return -EINVAL;
235 }
236
237 enum roc_nix_fc_mode
238 roc_nix_fc_mode_get(struct roc_nix *roc_nix)
239 {
240         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
241         struct mbox *mbox = get_mbox(roc_nix);
242         struct cgx_pause_frm_cfg *req, *rsp;
243         enum roc_nix_fc_mode mode;
244         int rc = -ENOSPC;
245
246         /* Flow control on LBK link is always available */
247         if (roc_nix_is_lbk(roc_nix)) {
248                 if (nix->tx_pause && nix->rx_pause)
249                         return ROC_NIX_FC_FULL;
250                 else if (nix->rx_pause)
251                         return ROC_NIX_FC_RX;
252                 else if (nix->tx_pause)
253                         return ROC_NIX_FC_TX;
254                 else
255                         return ROC_NIX_FC_NONE;
256         }
257
258         req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
259         if (req == NULL)
260                 return rc;
261         req->set = 0;
262
263         rc = mbox_process_msg(mbox, (void *)&rsp);
264         if (rc)
265                 goto exit;
266
267         if (rsp->rx_pause && rsp->tx_pause)
268                 mode = ROC_NIX_FC_FULL;
269         else if (rsp->rx_pause)
270                 mode = ROC_NIX_FC_RX;
271         else if (rsp->tx_pause)
272                 mode = ROC_NIX_FC_TX;
273         else
274                 mode = ROC_NIX_FC_NONE;
275
276         nix->rx_pause = rsp->rx_pause;
277         nix->tx_pause = rsp->tx_pause;
278         return mode;
279
280 exit:
281         return ROC_NIX_FC_NONE;
282 }
283
284 int
285 roc_nix_fc_mode_set(struct roc_nix *roc_nix, enum roc_nix_fc_mode mode)
286 {
287         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
288         struct mbox *mbox = get_mbox(roc_nix);
289         struct cgx_pause_frm_cfg *req;
290         uint8_t tx_pause, rx_pause;
291         int rc = -ENOSPC;
292
293         rx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_RX);
294         tx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_TX);
295
296         /* Nothing much to do for LBK links */
297         if (roc_nix_is_lbk(roc_nix)) {
298                 nix->rx_pause = rx_pause;
299                 nix->tx_pause = tx_pause;
300                 return 0;
301         }
302
303         req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
304         if (req == NULL)
305                 return rc;
306         req->set = 1;
307         req->rx_pause = rx_pause;
308         req->tx_pause = tx_pause;
309
310         rc = mbox_process(mbox);
311         if (rc)
312                 goto exit;
313
314         nix->rx_pause = rx_pause;
315         nix->tx_pause = tx_pause;
316
317 exit:
318         return rc;
319 }
320
321 void
322 rox_nix_fc_npa_bp_cfg(struct roc_nix *roc_nix, uint64_t pool_id, uint8_t ena,
323                       uint8_t force)
324 {
325         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
326         struct npa_lf *lf = idev_npa_obj_get();
327         struct npa_aq_enq_req *req;
328         struct npa_aq_enq_rsp *rsp;
329         struct mbox *mbox;
330         uint32_t limit;
331         int rc;
332
333         if (roc_nix_is_sdp(roc_nix))
334                 return;
335
336         if (!lf)
337                 return;
338         mbox = lf->mbox;
339
340         req = mbox_alloc_msg_npa_aq_enq(mbox);
341         if (req == NULL)
342                 return;
343
344         req->aura_id = roc_npa_aura_handle_to_aura(pool_id);
345         req->ctype = NPA_AQ_CTYPE_AURA;
346         req->op = NPA_AQ_INSTOP_READ;
347
348         rc = mbox_process_msg(mbox, (void *)&rsp);
349         if (rc)
350                 return;
351
352         limit = rsp->aura.limit;
353         /* BP is already enabled. */
354         if (rsp->aura.bp_ena) {
355                 uint16_t bpid;
356                 bool nix1;
357
358                 nix1 = !!(rsp->aura.bp_ena & 0x2);
359                 if (nix1)
360                         bpid = rsp->aura.nix1_bpid;
361                 else
362                         bpid = rsp->aura.nix0_bpid;
363
364                 /* If BP ids don't match disable BP. */
365                 if (((nix1 != nix->is_nix1) || (bpid != nix->bpid[0])) &&
366                     !force) {
367                         req = mbox_alloc_msg_npa_aq_enq(mbox);
368                         if (req == NULL)
369                                 return;
370
371                         req->aura_id = roc_npa_aura_handle_to_aura(pool_id);
372                         req->ctype = NPA_AQ_CTYPE_AURA;
373                         req->op = NPA_AQ_INSTOP_WRITE;
374
375                         req->aura.bp_ena = 0;
376                         req->aura_mask.bp_ena = ~(req->aura_mask.bp_ena);
377
378                         mbox_process(mbox);
379                 }
380                 return;
381         }
382
383         /* BP was previously enabled but now disabled skip. */
384         if (rsp->aura.bp)
385                 return;
386
387         req = mbox_alloc_msg_npa_aq_enq(mbox);
388         if (req == NULL)
389                 return;
390
391         req->aura_id = roc_npa_aura_handle_to_aura(pool_id);
392         req->ctype = NPA_AQ_CTYPE_AURA;
393         req->op = NPA_AQ_INSTOP_WRITE;
394
395         if (ena) {
396                 if (nix->is_nix1) {
397                         req->aura.nix1_bpid = nix->bpid[0];
398                         req->aura_mask.nix1_bpid = ~(req->aura_mask.nix1_bpid);
399                 } else {
400                         req->aura.nix0_bpid = nix->bpid[0];
401                         req->aura_mask.nix0_bpid = ~(req->aura_mask.nix0_bpid);
402                 }
403                 req->aura.bp = NIX_RQ_AURA_THRESH(
404                         limit > 128 ? 256 : limit); /* 95% of size*/
405                 req->aura_mask.bp = ~(req->aura_mask.bp);
406         }
407
408         req->aura.bp_ena = (!!ena << nix->is_nix1);
409         req->aura_mask.bp_ena = ~(req->aura_mask.bp_ena);
410
411         mbox_process(mbox);
412 }
413
414 int
415 roc_nix_pfc_mode_set(struct roc_nix *roc_nix, struct roc_nix_pfc_cfg *pfc_cfg)
416 {
417         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
418         struct mbox *mbox = get_mbox(roc_nix);
419         uint8_t tx_pause, rx_pause;
420         struct cgx_pfc_cfg *req;
421         struct cgx_pfc_rsp *rsp;
422         int rc = -ENOSPC;
423
424         if (roc_nix_is_lbk(roc_nix))
425                 return NIX_ERR_OP_NOTSUP;
426
427         rx_pause = (pfc_cfg->mode == ROC_NIX_FC_FULL) ||
428                    (pfc_cfg->mode == ROC_NIX_FC_RX);
429         tx_pause = (pfc_cfg->mode == ROC_NIX_FC_FULL) ||
430                    (pfc_cfg->mode == ROC_NIX_FC_TX);
431
432         req = mbox_alloc_msg_cgx_prio_flow_ctrl_cfg(mbox);
433         if (req == NULL)
434                 goto exit;
435
436         req->pfc_en = pfc_cfg->tc;
437         req->rx_pause = rx_pause;
438         req->tx_pause = tx_pause;
439
440         rc = mbox_process_msg(mbox, (void *)&rsp);
441         if (rc)
442                 goto exit;
443
444         nix->rx_pause = rsp->rx_pause;
445         nix->tx_pause = rsp->tx_pause;
446         if (rsp->tx_pause)
447                 nix->cev |= BIT(pfc_cfg->tc);
448         else
449                 nix->cev &= ~BIT(pfc_cfg->tc);
450
451 exit:
452         return rc;
453 }
454
455 int
456 roc_nix_pfc_mode_get(struct roc_nix *roc_nix, struct roc_nix_pfc_cfg *pfc_cfg)
457 {
458         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
459
460         if (roc_nix_is_lbk(roc_nix))
461                 return NIX_ERR_OP_NOTSUP;
462
463         pfc_cfg->tc = nix->cev;
464
465         if (nix->rx_pause && nix->tx_pause)
466                 pfc_cfg->mode = ROC_NIX_FC_FULL;
467         else if (nix->rx_pause)
468                 pfc_cfg->mode = ROC_NIX_FC_RX;
469         else if (nix->tx_pause)
470                 pfc_cfg->mode = ROC_NIX_FC_TX;
471         else
472                 pfc_cfg->mode = ROC_NIX_FC_NONE;
473
474         return 0;
475 }
476
477 uint16_t
478 roc_nix_chan_count_get(struct roc_nix *roc_nix)
479 {
480         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
481
482         return nix->chan_cnt;
483 }