2022-09-06 04:00:10 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright(C) 2021 Marvell.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "roc_api.h"
|
|
|
|
#include "roc_priv.h"
|
|
|
|
|
|
|
|
static inline struct mbox *
|
|
|
|
get_mbox(struct roc_nix *roc_nix)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct dev *dev = &nix->dev;
|
|
|
|
|
|
|
|
return dev->mbox;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
nix_fc_rxchan_bpid_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
|
|
|
|
if (nix->chan_cnt != 0)
|
|
|
|
fc_cfg->rxchan_cfg.enable = true;
|
|
|
|
else
|
|
|
|
fc_cfg->rxchan_cfg.enable = false;
|
|
|
|
|
|
|
|
fc_cfg->type = ROC_NIX_FC_RXCHAN_CFG;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
nix_fc_rxchan_bpid_set(struct roc_nix *roc_nix, bool enable)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
struct nix_bp_cfg_req *req;
|
|
|
|
struct nix_bp_cfg_rsp *rsp;
|
2023-09-13 12:21:49 +00:00
|
|
|
int rc = -ENOSPC, i;
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
if (enable) {
|
|
|
|
req = mbox_alloc_msg_nix_bp_enable(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return rc;
|
2023-09-13 12:21:49 +00:00
|
|
|
|
2022-09-06 04:00:10 +00:00
|
|
|
req->chan_base = 0;
|
2023-09-13 12:21:49 +00:00
|
|
|
if (roc_nix_is_lbk(roc_nix) || roc_nix_is_sdp(roc_nix))
|
|
|
|
req->chan_cnt = NIX_LBK_MAX_CHAN;
|
|
|
|
else
|
|
|
|
req->chan_cnt = NIX_CGX_MAX_CHAN;
|
|
|
|
|
|
|
|
req->bpid_per_chan = true;
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
2023-09-13 12:21:49 +00:00
|
|
|
if (rc || (req->chan_cnt != rsp->chan_cnt)) {
|
|
|
|
rc = -EIO;
|
2022-09-06 04:00:10 +00:00
|
|
|
goto exit;
|
2023-09-13 12:21:49 +00:00
|
|
|
}
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
nix->chan_cnt = rsp->chan_cnt;
|
2023-09-13 12:21:49 +00:00
|
|
|
for (i = 0; i < rsp->chan_cnt; i++)
|
|
|
|
nix->bpid[i] = rsp->chan_bpid[i] & 0x1FF;
|
2022-09-06 04:00:10 +00:00
|
|
|
} else {
|
|
|
|
req = mbox_alloc_msg_nix_bp_disable(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return rc;
|
|
|
|
req->chan_base = 0;
|
2023-09-13 12:21:49 +00:00
|
|
|
req->chan_cnt = nix->chan_cnt;
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
rc = mbox_process(mbox);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
memset(nix->bpid, 0, sizeof(uint16_t) * NIX_MAX_CHAN);
|
|
|
|
nix->chan_cnt = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (roc_model_is_cn9k())
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
/* Enable backpressure on CPT if inline inb is enabled */
|
2023-09-13 12:21:49 +00:00
|
|
|
if (enable && roc_nix_inl_inb_is_enabled(roc_nix) &&
|
|
|
|
!roc_errata_cpt_hang_on_x2p_bp()) {
|
2022-09-06 04:00:10 +00:00
|
|
|
req = mbox_alloc_msg_nix_cpt_bp_enable(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return rc;
|
|
|
|
req->chan_base = 0;
|
|
|
|
req->chan_cnt = 1;
|
|
|
|
req->bpid_per_chan = 0;
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
nix_fc_cq_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
struct nix_aq_enq_rsp *rsp;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (roc_model_is_cn9k()) {
|
|
|
|
struct nix_aq_enq_req *aq;
|
|
|
|
|
|
|
|
aq = mbox_alloc_msg_nix_aq_enq(mbox);
|
|
|
|
if (!aq)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
aq->qidx = fc_cfg->cq_cfg.rq;
|
|
|
|
aq->ctype = NIX_AQ_CTYPE_CQ;
|
|
|
|
aq->op = NIX_AQ_INSTOP_READ;
|
|
|
|
} else {
|
|
|
|
struct nix_cn10k_aq_enq_req *aq;
|
|
|
|
|
|
|
|
aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
|
|
|
|
if (!aq)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
aq->qidx = fc_cfg->cq_cfg.rq;
|
|
|
|
aq->ctype = NIX_AQ_CTYPE_CQ;
|
|
|
|
aq->op = NIX_AQ_INSTOP_READ;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
fc_cfg->cq_cfg.cq_drop = rsp->cq.bp;
|
|
|
|
fc_cfg->cq_cfg.enable = rsp->cq.bp_ena;
|
|
|
|
fc_cfg->type = ROC_NIX_FC_CQ_CFG;
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
static int
|
|
|
|
nix_fc_rq_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
struct nix_aq_enq_rsp *rsp;
|
|
|
|
struct npa_aq_enq_req *npa_req;
|
|
|
|
struct npa_aq_enq_rsp *npa_rsp;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (roc_model_is_cn9k()) {
|
|
|
|
struct nix_aq_enq_req *aq;
|
|
|
|
|
|
|
|
aq = mbox_alloc_msg_nix_aq_enq(mbox);
|
|
|
|
if (!aq)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
aq->qidx = fc_cfg->rq_cfg.rq;
|
|
|
|
aq->ctype = NIX_AQ_CTYPE_RQ;
|
|
|
|
aq->op = NIX_AQ_INSTOP_READ;
|
|
|
|
} else {
|
|
|
|
struct nix_cn10k_aq_enq_req *aq;
|
|
|
|
|
|
|
|
aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
|
|
|
|
if (!aq)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
aq->qidx = fc_cfg->rq_cfg.rq;
|
|
|
|
aq->ctype = NIX_AQ_CTYPE_RQ;
|
|
|
|
aq->op = NIX_AQ_INSTOP_READ;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
npa_req = mbox_alloc_msg_npa_aq_enq(mbox);
|
|
|
|
if (!npa_req)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
npa_req->aura_id = rsp->rq.lpb_aura;
|
|
|
|
npa_req->ctype = NPA_AQ_CTYPE_AURA;
|
|
|
|
npa_req->op = NPA_AQ_INSTOP_READ;
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&npa_rsp);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
fc_cfg->cq_cfg.cq_drop = npa_rsp->aura.bp;
|
|
|
|
fc_cfg->cq_cfg.enable = npa_rsp->aura.bp_ena;
|
|
|
|
fc_cfg->type = ROC_NIX_FC_RQ_CFG;
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2022-09-06 04:00:10 +00:00
|
|
|
static int
|
|
|
|
nix_fc_cq_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
|
|
|
|
if (roc_model_is_cn9k()) {
|
|
|
|
struct nix_aq_enq_req *aq;
|
|
|
|
|
|
|
|
aq = mbox_alloc_msg_nix_aq_enq(mbox);
|
|
|
|
if (!aq)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
aq->qidx = fc_cfg->cq_cfg.rq;
|
|
|
|
aq->ctype = NIX_AQ_CTYPE_CQ;
|
|
|
|
aq->op = NIX_AQ_INSTOP_WRITE;
|
|
|
|
|
|
|
|
if (fc_cfg->cq_cfg.enable) {
|
2023-09-13 12:21:49 +00:00
|
|
|
aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
|
2022-09-06 04:00:10 +00:00
|
|
|
aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
|
|
|
|
aq->cq.bp = fc_cfg->cq_cfg.cq_drop;
|
|
|
|
aq->cq_mask.bp = ~(aq->cq_mask.bp);
|
|
|
|
}
|
|
|
|
|
|
|
|
aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
|
|
|
|
aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
|
|
|
|
} else {
|
|
|
|
struct nix_cn10k_aq_enq_req *aq;
|
|
|
|
|
|
|
|
aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
|
|
|
|
if (!aq)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
aq->qidx = fc_cfg->cq_cfg.rq;
|
|
|
|
aq->ctype = NIX_AQ_CTYPE_CQ;
|
|
|
|
aq->op = NIX_AQ_INSTOP_WRITE;
|
|
|
|
|
|
|
|
if (fc_cfg->cq_cfg.enable) {
|
2023-09-13 12:21:49 +00:00
|
|
|
aq->cq.bpid = nix->bpid[fc_cfg->cq_cfg.tc];
|
2022-09-06 04:00:10 +00:00
|
|
|
aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
|
|
|
|
aq->cq.bp = fc_cfg->cq_cfg.cq_drop;
|
|
|
|
aq->cq_mask.bp = ~(aq->cq_mask.bp);
|
|
|
|
}
|
|
|
|
|
|
|
|
aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
|
|
|
|
aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mbox_process(mbox);
|
|
|
|
}
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
static int
|
|
|
|
nix_fc_rq_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
|
|
|
struct roc_nix_fc_cfg tmp;
|
|
|
|
int sso_ena = 0;
|
|
|
|
|
|
|
|
/* Check whether RQ is connected to SSO or not */
|
|
|
|
sso_ena = roc_nix_rq_is_sso_enable(roc_nix, fc_cfg->rq_cfg.rq);
|
|
|
|
if (sso_ena < 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (sso_ena)
|
|
|
|
roc_nix_fc_npa_bp_cfg(roc_nix, fc_cfg->rq_cfg.pool,
|
|
|
|
fc_cfg->rq_cfg.enable, true,
|
|
|
|
fc_cfg->rq_cfg.tc);
|
|
|
|
|
|
|
|
/* Copy RQ config to CQ config as they are occupying same area */
|
|
|
|
memset(&tmp, 0, sizeof(tmp));
|
|
|
|
tmp.type = ROC_NIX_FC_CQ_CFG;
|
|
|
|
tmp.cq_cfg.rq = fc_cfg->rq_cfg.rq;
|
|
|
|
tmp.cq_cfg.tc = fc_cfg->rq_cfg.tc;
|
|
|
|
tmp.cq_cfg.cq_drop = fc_cfg->rq_cfg.cq_drop;
|
|
|
|
tmp.cq_cfg.enable = fc_cfg->rq_cfg.enable;
|
|
|
|
|
|
|
|
return nix_fc_cq_config_set(roc_nix, &tmp);
|
|
|
|
}
|
|
|
|
|
2022-09-06 04:00:10 +00:00
|
|
|
int
|
|
|
|
roc_nix_fc_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
2023-09-13 12:21:49 +00:00
|
|
|
if (!roc_nix_is_pf(roc_nix) && !roc_nix_is_lbk(roc_nix) &&
|
|
|
|
!roc_nix_is_sdp(roc_nix))
|
2022-09-06 04:00:10 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (fc_cfg->type == ROC_NIX_FC_CQ_CFG)
|
|
|
|
return nix_fc_cq_config_get(roc_nix, fc_cfg);
|
2023-09-13 12:21:49 +00:00
|
|
|
else if (fc_cfg->type == ROC_NIX_FC_RQ_CFG)
|
|
|
|
return nix_fc_rq_config_get(roc_nix, fc_cfg);
|
2022-09-06 04:00:10 +00:00
|
|
|
else if (fc_cfg->type == ROC_NIX_FC_RXCHAN_CFG)
|
|
|
|
return nix_fc_rxchan_bpid_get(roc_nix, fc_cfg);
|
|
|
|
else if (fc_cfg->type == ROC_NIX_FC_TM_CFG)
|
|
|
|
return nix_tm_bp_config_get(roc_nix, &fc_cfg->tm_cfg.enable);
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
roc_nix_fc_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
|
|
|
|
{
|
|
|
|
if (fc_cfg->type == ROC_NIX_FC_CQ_CFG)
|
|
|
|
return nix_fc_cq_config_set(roc_nix, fc_cfg);
|
2023-09-13 12:21:49 +00:00
|
|
|
else if (fc_cfg->type == ROC_NIX_FC_RQ_CFG)
|
|
|
|
return nix_fc_rq_config_set(roc_nix, fc_cfg);
|
2022-09-06 04:00:10 +00:00
|
|
|
else if (fc_cfg->type == ROC_NIX_FC_RXCHAN_CFG)
|
|
|
|
return nix_fc_rxchan_bpid_set(roc_nix,
|
|
|
|
fc_cfg->rxchan_cfg.enable);
|
|
|
|
else if (fc_cfg->type == ROC_NIX_FC_TM_CFG)
|
2023-09-13 12:21:49 +00:00
|
|
|
return nix_tm_bp_config_set(roc_nix, fc_cfg->tm_cfg.sq,
|
|
|
|
fc_cfg->tm_cfg.tc,
|
|
|
|
fc_cfg->tm_cfg.enable, false);
|
2022-09-06 04:00:10 +00:00
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum roc_nix_fc_mode
|
|
|
|
roc_nix_fc_mode_get(struct roc_nix *roc_nix)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
struct cgx_pause_frm_cfg *req, *rsp;
|
|
|
|
enum roc_nix_fc_mode mode;
|
|
|
|
int rc = -ENOSPC;
|
|
|
|
|
|
|
|
/* Flow control on LBK link is always available */
|
|
|
|
if (roc_nix_is_lbk(roc_nix)) {
|
|
|
|
if (nix->tx_pause && nix->rx_pause)
|
|
|
|
return ROC_NIX_FC_FULL;
|
|
|
|
else if (nix->rx_pause)
|
|
|
|
return ROC_NIX_FC_RX;
|
|
|
|
else if (nix->tx_pause)
|
|
|
|
return ROC_NIX_FC_TX;
|
|
|
|
else
|
|
|
|
return ROC_NIX_FC_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return rc;
|
|
|
|
req->set = 0;
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
if (rsp->rx_pause && rsp->tx_pause)
|
|
|
|
mode = ROC_NIX_FC_FULL;
|
|
|
|
else if (rsp->rx_pause)
|
|
|
|
mode = ROC_NIX_FC_RX;
|
|
|
|
else if (rsp->tx_pause)
|
|
|
|
mode = ROC_NIX_FC_TX;
|
|
|
|
else
|
|
|
|
mode = ROC_NIX_FC_NONE;
|
|
|
|
|
|
|
|
nix->rx_pause = rsp->rx_pause;
|
|
|
|
nix->tx_pause = rsp->tx_pause;
|
|
|
|
return mode;
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return ROC_NIX_FC_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
roc_nix_fc_mode_set(struct roc_nix *roc_nix, enum roc_nix_fc_mode mode)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
struct cgx_pause_frm_cfg *req;
|
|
|
|
uint8_t tx_pause, rx_pause;
|
|
|
|
int rc = -ENOSPC;
|
|
|
|
|
|
|
|
rx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_RX);
|
|
|
|
tx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_TX);
|
|
|
|
|
|
|
|
/* Nothing much to do for LBK links */
|
|
|
|
if (roc_nix_is_lbk(roc_nix)) {
|
|
|
|
nix->rx_pause = rx_pause;
|
|
|
|
nix->tx_pause = tx_pause;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return rc;
|
|
|
|
req->set = 1;
|
|
|
|
req->rx_pause = rx_pause;
|
|
|
|
req->tx_pause = tx_pause;
|
|
|
|
|
|
|
|
rc = mbox_process(mbox);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
nix->rx_pause = rx_pause;
|
|
|
|
nix->tx_pause = tx_pause;
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-09-13 12:21:49 +00:00
|
|
|
roc_nix_fc_npa_bp_cfg(struct roc_nix *roc_nix, uint64_t pool_id, uint8_t ena,
|
|
|
|
uint8_t force, uint8_t tc)
|
2022-09-06 04:00:10 +00:00
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct npa_lf *lf = idev_npa_obj_get();
|
|
|
|
struct npa_aq_enq_req *req;
|
|
|
|
struct npa_aq_enq_rsp *rsp;
|
|
|
|
struct mbox *mbox;
|
|
|
|
uint32_t limit;
|
2023-09-13 12:21:49 +00:00
|
|
|
uint64_t shift;
|
2022-09-06 04:00:10 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (roc_nix_is_sdp(roc_nix))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!lf)
|
|
|
|
return;
|
|
|
|
mbox = lf->mbox;
|
|
|
|
|
|
|
|
req = mbox_alloc_msg_npa_aq_enq(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
req->aura_id = roc_npa_aura_handle_to_aura(pool_id);
|
|
|
|
req->ctype = NPA_AQ_CTYPE_AURA;
|
|
|
|
req->op = NPA_AQ_INSTOP_READ;
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
|
|
|
if (rc)
|
|
|
|
return;
|
|
|
|
|
|
|
|
limit = rsp->aura.limit;
|
2023-09-13 12:21:49 +00:00
|
|
|
shift = rsp->aura.shift;
|
|
|
|
|
2022-09-06 04:00:10 +00:00
|
|
|
/* BP is already enabled. */
|
2023-09-13 12:21:49 +00:00
|
|
|
if (rsp->aura.bp_ena && ena) {
|
2022-09-06 04:00:10 +00:00
|
|
|
uint16_t bpid;
|
|
|
|
bool nix1;
|
|
|
|
|
|
|
|
nix1 = !!(rsp->aura.bp_ena & 0x2);
|
|
|
|
if (nix1)
|
|
|
|
bpid = rsp->aura.nix1_bpid;
|
|
|
|
else
|
|
|
|
bpid = rsp->aura.nix0_bpid;
|
|
|
|
|
|
|
|
/* If BP ids don't match disable BP. */
|
2023-09-13 12:21:49 +00:00
|
|
|
if (((nix1 != nix->is_nix1) || (bpid != nix->bpid[tc])) &&
|
2022-09-06 04:00:10 +00:00
|
|
|
!force) {
|
|
|
|
req = mbox_alloc_msg_npa_aq_enq(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return;
|
|
|
|
|
2023-09-13 12:21:49 +00:00
|
|
|
plt_info("Disabling BP/FC on aura 0x%" PRIx64
|
|
|
|
" as it shared across ports or tc",
|
|
|
|
pool_id);
|
2022-09-06 04:00:10 +00:00
|
|
|
req->aura_id = roc_npa_aura_handle_to_aura(pool_id);
|
|
|
|
req->ctype = NPA_AQ_CTYPE_AURA;
|
|
|
|
req->op = NPA_AQ_INSTOP_WRITE;
|
|
|
|
|
|
|
|
req->aura.bp_ena = 0;
|
|
|
|
req->aura_mask.bp_ena = ~(req->aura_mask.bp_ena);
|
|
|
|
|
|
|
|
mbox_process(mbox);
|
|
|
|
}
|
2023-09-13 12:21:49 +00:00
|
|
|
|
|
|
|
if ((nix1 != nix->is_nix1) || (bpid != nix->bpid[tc]))
|
|
|
|
plt_info("Ignoring aura 0x%" PRIx64 "->%u bpid mapping",
|
|
|
|
pool_id, nix->bpid[tc]);
|
2022-09-06 04:00:10 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BP was previously enabled but now disabled skip. */
|
2023-09-13 12:21:49 +00:00
|
|
|
if (rsp->aura.bp && ena)
|
2022-09-06 04:00:10 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
req = mbox_alloc_msg_npa_aq_enq(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
req->aura_id = roc_npa_aura_handle_to_aura(pool_id);
|
|
|
|
req->ctype = NPA_AQ_CTYPE_AURA;
|
|
|
|
req->op = NPA_AQ_INSTOP_WRITE;
|
|
|
|
|
|
|
|
if (ena) {
|
|
|
|
if (nix->is_nix1) {
|
2023-09-13 12:21:49 +00:00
|
|
|
req->aura.nix1_bpid = nix->bpid[tc];
|
2022-09-06 04:00:10 +00:00
|
|
|
req->aura_mask.nix1_bpid = ~(req->aura_mask.nix1_bpid);
|
|
|
|
} else {
|
2023-09-13 12:21:49 +00:00
|
|
|
req->aura.nix0_bpid = nix->bpid[tc];
|
2022-09-06 04:00:10 +00:00
|
|
|
req->aura_mask.nix0_bpid = ~(req->aura_mask.nix0_bpid);
|
|
|
|
}
|
2023-09-13 12:21:49 +00:00
|
|
|
req->aura.bp = NIX_RQ_AURA_THRESH(limit >> shift);
|
|
|
|
req->aura_mask.bp = ~(req->aura_mask.bp);
|
|
|
|
} else {
|
|
|
|
req->aura.bp = 0;
|
2022-09-06 04:00:10 +00:00
|
|
|
req->aura_mask.bp = ~(req->aura_mask.bp);
|
|
|
|
}
|
|
|
|
|
|
|
|
req->aura.bp_ena = (!!ena << nix->is_nix1);
|
|
|
|
req->aura_mask.bp_ena = ~(req->aura_mask.bp_ena);
|
|
|
|
|
|
|
|
mbox_process(mbox);
|
|
|
|
}
|
2023-09-13 12:21:49 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
roc_nix_pfc_mode_set(struct roc_nix *roc_nix, struct roc_nix_pfc_cfg *pfc_cfg)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
struct mbox *mbox = get_mbox(roc_nix);
|
|
|
|
uint8_t tx_pause, rx_pause;
|
|
|
|
struct cgx_pfc_cfg *req;
|
|
|
|
struct cgx_pfc_rsp *rsp;
|
|
|
|
int rc = -ENOSPC;
|
|
|
|
|
|
|
|
if (roc_nix_is_lbk(roc_nix))
|
|
|
|
return NIX_ERR_OP_NOTSUP;
|
|
|
|
|
|
|
|
rx_pause = (pfc_cfg->mode == ROC_NIX_FC_FULL) ||
|
|
|
|
(pfc_cfg->mode == ROC_NIX_FC_RX);
|
|
|
|
tx_pause = (pfc_cfg->mode == ROC_NIX_FC_FULL) ||
|
|
|
|
(pfc_cfg->mode == ROC_NIX_FC_TX);
|
|
|
|
|
|
|
|
req = mbox_alloc_msg_cgx_prio_flow_ctrl_cfg(mbox);
|
|
|
|
if (req == NULL)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
req->pfc_en = pfc_cfg->tc;
|
|
|
|
req->rx_pause = rx_pause;
|
|
|
|
req->tx_pause = tx_pause;
|
|
|
|
|
|
|
|
rc = mbox_process_msg(mbox, (void *)&rsp);
|
|
|
|
if (rc)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
nix->rx_pause = rsp->rx_pause;
|
|
|
|
nix->tx_pause = rsp->tx_pause;
|
|
|
|
if (rsp->tx_pause)
|
|
|
|
nix->cev |= BIT(pfc_cfg->tc);
|
|
|
|
else
|
|
|
|
nix->cev &= ~BIT(pfc_cfg->tc);
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
roc_nix_pfc_mode_get(struct roc_nix *roc_nix, struct roc_nix_pfc_cfg *pfc_cfg)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
|
|
|
|
if (roc_nix_is_lbk(roc_nix))
|
|
|
|
return NIX_ERR_OP_NOTSUP;
|
|
|
|
|
|
|
|
pfc_cfg->tc = nix->cev;
|
|
|
|
|
|
|
|
if (nix->rx_pause && nix->tx_pause)
|
|
|
|
pfc_cfg->mode = ROC_NIX_FC_FULL;
|
|
|
|
else if (nix->rx_pause)
|
|
|
|
pfc_cfg->mode = ROC_NIX_FC_RX;
|
|
|
|
else if (nix->tx_pause)
|
|
|
|
pfc_cfg->mode = ROC_NIX_FC_TX;
|
|
|
|
else
|
|
|
|
pfc_cfg->mode = ROC_NIX_FC_NONE;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t
|
|
|
|
roc_nix_chan_count_get(struct roc_nix *roc_nix)
|
|
|
|
{
|
|
|
|
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
|
|
|
|
|
|
|
|
return nix->chan_cnt;
|
|
|
|
}
|