struct roc_nix *nix = &dev->nix;
struct roc_nix_fc_cfg fc_cfg;
struct roc_nix_cq *cq;
+ struct roc_nix_rq *rq;
memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
+ rq = &dev->rqs[qid];
cq = &dev->cqs[qid];
- fc_cfg.type = ROC_NIX_FC_CQ_CFG;
- fc_cfg.cq_cfg.enable = enable;
- /* Map all CQs to last channel */
- fc_cfg.cq_cfg.tc = roc_nix_chan_count_get(nix) - 1;
- fc_cfg.cq_cfg.rq = qid;
- fc_cfg.cq_cfg.cq_drop = cq->drop_thresh;
+ fc_cfg.type = ROC_NIX_FC_RQ_CFG;
+ fc_cfg.rq_cfg.enable = enable;
+ fc_cfg.rq_cfg.tc = 0;
+ fc_cfg.rq_cfg.rq = qid;
+ fc_cfg.rq_cfg.pool = rq->aura_handle;
+ fc_cfg.rq_cfg.cq_drop = cq->drop_thresh;
return roc_nix_fc_config_set(nix, &fc_cfg);
}
uint8_t rx_pause, tx_pause;
int rc, i;
- if (roc_nix_is_vf_or_sdp(nix) && !roc_nix_is_lbk(nix)) {
- plt_err("Flow control configuration is not allowed on VFs");
- return -ENOTSUP;
- }
+ if (roc_nix_is_sdp(nix))
+ return 0;
if (fc_conf->high_water || fc_conf->low_water || fc_conf->pause_time ||
fc_conf->mac_ctrl_frame_fwd || fc_conf->autoneg) {
return -EINVAL;
}
- if (fc_conf->mode == fc->mode)
- return 0;
rx_pause = (fc_conf->mode == RTE_ETH_FC_FULL) ||
(fc_conf->mode == RTE_ETH_FC_RX_PAUSE);
tx_pause = (fc_conf->mode == RTE_ETH_FC_FULL) ||
(fc_conf->mode == RTE_ETH_FC_TX_PAUSE);
+ if (fc_conf->mode == fc->mode) {
+ fc->rx_pause = rx_pause;
+ fc->tx_pause = tx_pause;
+ return 0;
+ }
+
/* Check if TX pause frame is already enabled or not */
if (fc->tx_pause ^ tx_pause) {
if (roc_model_is_cn96_ax() && data->dev_started) {
memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
rxq = ((struct cnxk_eth_rxq_sp *)data->rx_queues[i]) -
1;
+ rxq->tx_pause = !!tx_pause;
rc = nix_fc_cq_config_set(dev, rxq->qid, !!tx_pause);
if (rc)
return rc;
fc->rx_pause = rx_pause;
fc->tx_pause = tx_pause;
fc->mode = fc_conf->mode;
-
return rc;
}
int
cnxk_nix_priority_flow_ctrl_queue_info_get(struct rte_eth_dev *eth_dev,
- struct rte_eth_pfc_queue_info *pfc_info)
+ struct rte_eth_pfc_queue_info *pfc_info)
{
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
int
cnxk_nix_priority_flow_ctrl_queue_config(struct rte_eth_dev *eth_dev,
- struct rte_eth_pfc_queue_conf *pfc_conf)
+ struct rte_eth_pfc_queue_conf *pfc_conf)
{
- struct cnxk_pfc_cfg conf;
- int rc;
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *nix = &dev->nix;
+ enum rte_eth_fc_mode mode;
+ uint8_t en, tc;
+ uint16_t qid;
+ int rc = 0;
- memset(&conf, 0, sizeof(struct cnxk_pfc_cfg));
+ if (dev->fc_cfg.mode != RTE_ETH_FC_NONE) {
+ plt_err("Disable Flow Control before configuring PFC");
+ return -ENOTSUP;
+ }
- conf.fc_cfg.mode = pfc_conf->mode;
+ if (roc_nix_is_sdp(nix)) {
+ plt_err("Prio flow ctrl config is not allowed on SDP");
+ return -ENOTSUP;
+ }
- conf.pause_time = pfc_conf->tx_pause.pause_time;
- conf.rx_tc = pfc_conf->tx_pause.tc;
- conf.rx_qid = pfc_conf->tx_pause.rx_qid;
+ mode = pfc_conf->mode;
- conf.tx_tc = pfc_conf->rx_pause.tc;
- conf.tx_qid = pfc_conf->rx_pause.tx_qid;
+ /* Perform Tx pause configuration on RQ */
+ qid = pfc_conf->tx_pause.rx_qid;
+ if (qid < eth_dev->data->nb_rx_queues) {
+ en = (mode == RTE_ETH_FC_FULL) || (mode == RTE_ETH_FC_TX_PAUSE);
+ tc = pfc_conf->tx_pause.tc;
+ rc = nix_priority_flow_ctrl_rq_conf(eth_dev, qid, en, tc);
+ }
- rc = nix_priority_flow_ctrl_configure(eth_dev, &conf);
- if (rc)
- return rc;
+ /* Perform Rx pause configuration on SQ */
+ qid = pfc_conf->rx_pause.tx_qid;
+ if (qid < eth_dev->data->nb_tx_queues) {
+ en = (mode == RTE_ETH_FC_FULL) || (mode == RTE_ETH_FC_RX_PAUSE);
+ tc = pfc_conf->rx_pause.tc;
+ rc |= nix_priority_flow_ctrl_sq_conf(eth_dev, qid, en, tc);
+ }
return rc;
}
}
int
-nix_priority_flow_ctrl_configure(struct rte_eth_dev *eth_dev,
- struct cnxk_pfc_cfg *conf)
+nix_priority_flow_ctrl_rq_conf(struct rte_eth_dev *eth_dev, uint16_t qid,
+ uint8_t tx_pause, uint8_t tc)
{
- enum roc_nix_fc_mode mode_map[] = {ROC_NIX_FC_NONE, ROC_NIX_FC_RX,
- ROC_NIX_FC_TX, ROC_NIX_FC_FULL};
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
struct rte_eth_dev_data *data = eth_dev->data;
struct cnxk_pfc_cfg *pfc = &dev->pfc_cfg;
struct roc_nix_pfc_cfg pfc_cfg;
struct roc_nix_fc_cfg fc_cfg;
struct cnxk_eth_rxq_sp *rxq;
- struct cnxk_eth_txq_sp *txq;
- uint8_t rx_pause, tx_pause;
- enum rte_eth_fc_mode mode;
+ enum roc_nix_fc_mode mode;
+ struct roc_nix_rq *rq;
struct roc_nix_cq *cq;
- struct roc_nix_sq *sq;
int rc;
- if (roc_nix_is_vf_or_sdp(nix)) {
- plt_err("Prio flow ctrl config is not allowed on VF and SDP");
- return -ENOTSUP;
- }
-
if (roc_model_is_cn96_ax() && data->dev_started) {
/* On Ax, CQ should be in disabled state
* while setting flow control configuration.
return 0;
}
- if (dev->pfc_tc_sq_map[conf->tx_tc] != 0xFFFF &&
- dev->pfc_tc_sq_map[conf->tx_tc] != conf->tx_qid) {
- plt_err("Same TC can not be configured on multiple SQs");
- return -ENOTSUP;
- }
+ if (data->rx_queues == NULL)
+ return -EINVAL;
- mode = conf->fc_cfg.mode;
- rx_pause = (mode == RTE_ETH_FC_FULL) || (mode == RTE_ETH_FC_RX_PAUSE);
- tx_pause = (mode == RTE_ETH_FC_FULL) || (mode == RTE_ETH_FC_TX_PAUSE);
+ if (qid >= eth_dev->data->nb_rx_queues)
+ return -ENOTSUP;
- if (data->rx_queues == NULL || data->tx_queues == NULL) {
- rc = 0;
- goto exit;
- }
+ /* Configure RQ */
+ rxq = ((struct cnxk_eth_rxq_sp *)data->rx_queues[qid]) - 1;
+ rq = &dev->rqs[qid];
+ cq = &dev->cqs[qid];
- /* Configure CQs */
memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
- rxq = ((struct cnxk_eth_rxq_sp *)data->rx_queues[conf->rx_qid]) - 1;
- cq = &dev->cqs[rxq->qid];
- fc_cfg.type = ROC_NIX_FC_CQ_CFG;
- fc_cfg.cq_cfg.tc = conf->rx_tc;
- fc_cfg.cq_cfg.enable = !!tx_pause;
- fc_cfg.cq_cfg.rq = cq->qid;
- fc_cfg.cq_cfg.cq_drop = cq->drop_thresh;
+ fc_cfg.type = ROC_NIX_FC_RQ_CFG;
+ fc_cfg.rq_cfg.tc = tc;
+ fc_cfg.rq_cfg.enable = !!tx_pause;
+ fc_cfg.rq_cfg.rq = rq->qid;
+ fc_cfg.rq_cfg.pool = rxq->qconf.mp->pool_id;
+ fc_cfg.rq_cfg.cq_drop = cq->drop_thresh;
rc = roc_nix_fc_config_set(nix, &fc_cfg);
if (rc)
- goto exit;
+ return rc;
- /* Check if RX pause frame is enabled or not */
- if (pfc->fc_cfg.rx_pause ^ rx_pause) {
- if (conf->tx_qid >= eth_dev->data->nb_tx_queues)
- goto exit;
+ if (rxq->tx_pause != tx_pause) {
+ if (tx_pause)
+ pfc->tx_pause_en++;
+ else
+ pfc->tx_pause_en--;
+ }
+
+ rxq->tx_pause = !!tx_pause;
+ rxq->tc = tc;
+ /* Skip if PFC already enabled in mac */
+ if (pfc->tx_pause_en > 1)
+ return 0;
+
+ /* Configure MAC block */
+ pfc->class_en = pfc->tx_pause_en ? 0xFF : 0x0;
+
+ if (pfc->rx_pause_en)
+ mode = pfc->tx_pause_en ? ROC_NIX_FC_FULL : ROC_NIX_FC_RX;
+ else
+ mode = pfc->tx_pause_en ? ROC_NIX_FC_TX : ROC_NIX_FC_NONE;
+
+ memset(&pfc_cfg, 0, sizeof(struct roc_nix_pfc_cfg));
+ pfc_cfg.mode = mode;
+ pfc_cfg.tc = pfc->class_en;
+ return roc_nix_pfc_mode_set(nix, &pfc_cfg);
+}
+
+int
+nix_priority_flow_ctrl_sq_conf(struct rte_eth_dev *eth_dev, uint16_t qid,
+ uint8_t rx_pause, uint8_t tc)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct rte_eth_dev_data *data = eth_dev->data;
+ struct cnxk_pfc_cfg *pfc = &dev->pfc_cfg;
+ struct roc_nix *nix = &dev->nix;
+ struct roc_nix_fc_cfg fc_cfg;
+ struct cnxk_eth_txq_sp *txq;
+ struct roc_nix_sq *sq;
+ int rc;
+
+ if (data->tx_queues == NULL)
+ return -EINVAL;
+
+ if (qid >= eth_dev->data->nb_tx_queues)
+ return -ENOTSUP;
+
+ if (dev->pfc_tc_sq_map[tc] != 0xFFFF &&
+ dev->pfc_tc_sq_map[tc] != qid) {
+ plt_err("Same TC can not be configured on multiple SQs");
+ return -ENOTSUP;
+ }
+
+ /* Check if RX pause frame is enabled or not */
+ if (!pfc->rx_pause_en) {
if ((roc_nix_tm_tree_type_get(nix) == ROC_NIX_TM_DEFAULT) &&
eth_dev->data->nb_tx_queues > 1) {
/*
}
}
- txq = ((struct cnxk_eth_txq_sp *)data->tx_queues[conf->tx_qid]) - 1;
+ txq = ((struct cnxk_eth_txq_sp *)data->tx_queues[qid]) - 1;
sq = &dev->sqs[txq->qid];
memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
fc_cfg.type = ROC_NIX_FC_TM_CFG;
fc_cfg.tm_cfg.sq = sq->qid;
- fc_cfg.tm_cfg.tc = conf->tx_tc;
+ fc_cfg.tm_cfg.tc = tc;
fc_cfg.tm_cfg.enable = !!rx_pause;
rc = roc_nix_fc_config_set(nix, &fc_cfg);
if (rc)
return rc;
- dev->pfc_tc_sq_map[conf->tx_tc] = sq->qid;
-
- /* Configure MAC block */
- if (tx_pause)
- pfc->class_en |= BIT(conf->rx_tc);
- else
- pfc->class_en &= ~BIT(conf->rx_tc);
-
- if (pfc->class_en)
- mode = RTE_ETH_FC_FULL;
-
- memset(&pfc_cfg, 0, sizeof(struct roc_nix_pfc_cfg));
- pfc_cfg.mode = mode_map[mode];
- pfc_cfg.tc = pfc->class_en;
- rc = roc_nix_pfc_mode_set(nix, &pfc_cfg);
- if (rc)
- return rc;
-
- pfc->fc_cfg.rx_pause = rx_pause;
- pfc->fc_cfg.tx_pause = tx_pause;
- pfc->fc_cfg.mode = mode;
-
+ dev->pfc_tc_sq_map[tc] = sq->qid;
exit:
return rc;
}