From: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
To: dev@dpdk.org
Cc: bruce.richardson@intel.com, anatoly.burakov@intel.com
Subject: [PATCH 5/6] net/ice: enable PFC support
Date: Thu, 7 Aug 2025 12:22:36 +0000 [thread overview]
Message-ID: <20250807122238.334177-6-vladimir.medvedkin@intel.com> (raw)
In-Reply-To: <20250807122238.334177-1-vladimir.medvedkin@intel.com>
This patch add support for Priority Flow Control (PFC)
Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
---
drivers/net/intel/ice/ice_ethdev.c | 125 ++++++++++++++++++++++++++++-
1 file changed, 124 insertions(+), 1 deletion(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 8aabf21bf6..b3be2e7c7e 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -99,6 +99,11 @@ static struct proto_xtr_ol_flag ice_proto_xtr_ol_flag_params[] = {
#define ICE_COMMS_PKG_NAME "ICE COMMS Package"
#define ICE_MAX_RES_DESC_NUM 1024
+#define ICE_MAC_E810_MAX_WATERMARK 143744U
+#define ICE_MAC_E830_MAX_WATERMARK 259103U
+#define ICE_MAC_TC_MAX_WATERMARK (((hw)->mac_type == ICE_MAC_E830) ? \
+ ICE_MAC_E830_MAX_WATERMARK : ICE_MAC_E810_MAX_WATERMARK)
+
static int ice_dev_configure(struct rte_eth_dev *dev);
static int ice_dev_start(struct rte_eth_dev *dev);
static int ice_dev_stop(struct rte_eth_dev *dev);
@@ -195,6 +200,7 @@ static int ice_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa);
static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev,
size_t *no_of_elements);
static int ice_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info);
+static int ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf);
static const struct rte_pci_id pci_id_ice_map[] = {
{ RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -326,6 +332,7 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
.fec_set = ice_fec_set,
.buffer_split_supported_hdr_ptypes_get = ice_buffer_split_supported_hdr_ptypes_get,
.get_dcb_info = ice_get_dcb_info,
+ .priority_flow_ctrl_set = ice_priority_flow_ctrl_set,
};
/* store statistics names and its offset in stats structure */
@@ -2831,17 +2838,33 @@ ice_dev_stop(struct rte_eth_dev *dev)
static void
ice_deinit_dcb(struct rte_eth_dev *dev)
{
+ struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ice_port_info *port_info = hw->port_info;
struct ice_qos_cfg *qos_cfg = &port_info->qos_cfg;
struct ice_dcbx_cfg *local_dcb_conf = &qos_cfg->local_dcbx_cfg;
+ int i, ret, cgd_idx;
+ uint16_t max_frame_size;
u8 max_tcs = local_dcb_conf->etscfg.maxtcs;
- int ret;
+ u8 tc;
if (!(dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_DCB_FLAG ||
dev->data->dev_conf.txmode.mq_mode == RTE_ETH_MQ_TX_DCB))
return;
+ for (i = 0; i < max_tcs; i++) {
+ tc = ice_get_tc_by_up(hw, i);
+ cgd_idx = ice_get_cgd_idx(hw, tc);
+ wr32(hw, GLRPB_TCHW(cgd_idx), ICE_MAC_TC_MAX_WATERMARK);
+ wr32(hw, GLRPB_TCLW(cgd_idx), ICE_MAC_TC_MAX_WATERMARK);
+ }
+ max_frame_size = pf->dev_data->mtu ?
+ pf->dev_data->mtu + ICE_ETH_OVERHEAD : ICE_FRAME_SIZE_MAX;
+ ret = ice_aq_set_mac_cfg(hw, max_frame_size, UINT8_MAX, UINT16_MAX,
+ INT16_MAX + 1, false, NULL);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Failed to set mac config on DCB deinit");
+
memset(local_dcb_conf, 0, sizeof(*local_dcb_conf));
local_dcb_conf->etscfg.maxtcs = max_tcs;
local_dcb_conf->etscfg.tcbwtable[0] = 100;
@@ -3880,6 +3903,106 @@ ice_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info)
return 0;
}
+static int
+ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf)
+{
+ struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
+ struct ice_port_info *port_info = hw->port_info;
+ struct ice_qos_cfg *qos_cfg = &port_info->qos_cfg;
+ struct ice_dcbx_cfg *dcb_conf = &qos_cfg->local_dcbx_cfg;
+ int ret;
+
+ dcb_conf->pfc_mode = ICE_QOS_MODE_VLAN;
+ dcb_conf->pfc.willing = 0;
+ /** pfccap should alreeady be set by DCB config, check if zero */
+ if (dcb_conf->pfc.pfccap == 0) {
+ PMD_DRV_LOG(ERR, "DCB is not configured on the port, can not set PFC");
+ return -EINVAL;
+ }
+
+ ret = ice_aq_set_pfc_mode(hw, ICE_AQC_PFC_VLAN_BASED_PFC, NULL);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to enable PFC in VLAN mode");
+ return ret;
+ }
+
+ u8 tc = ice_get_tc_by_up(hw, pfc_conf->priority);
+
+ switch (pfc_conf->fc.mode) {
+ case (RTE_ETH_FC_NONE):
+ dcb_conf->pfc.pfcena &= ~(1 << tc);
+ dcb_conf->pfc.pfcena_asym_rx &= ~(1 << tc);
+ dcb_conf->pfc.pfcena_asym_tx &= ~(1 << tc);
+ break;
+ case (RTE_ETH_FC_RX_PAUSE):
+ dcb_conf->pfc.pfcena &= ~(1 << tc);
+ dcb_conf->pfc.pfcena_asym_rx |= (1 << tc);
+ dcb_conf->pfc.pfcena_asym_tx &= ~(1 << tc);
+ break;
+ case (RTE_ETH_FC_TX_PAUSE):
+ dcb_conf->pfc.pfcena &= ~(1 << tc);
+ dcb_conf->pfc.pfcena_asym_rx &= ~(1 << tc);
+ dcb_conf->pfc.pfcena_asym_tx |= (1 << tc);
+ break;
+ case (RTE_ETH_FC_FULL):
+ dcb_conf->pfc.pfcena |= (1 << tc);
+ dcb_conf->pfc.pfcena_asym_rx &= ~(1 << tc);
+ dcb_conf->pfc.pfcena_asym_tx &= ~(1 << tc);
+ break;
+ }
+
+ ret = ice_set_dcb_cfg(port_info);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to configure DCB for PF");
+ return ret;
+ }
+
+ /* Update high and low watermarks */
+ u32 high_watermark = pfc_conf->fc.high_water;
+ if (high_watermark > ICE_MAC_TC_MAX_WATERMARK)
+ high_watermark = ICE_MAC_TC_MAX_WATERMARK;
+
+ u32 low_watermark = pfc_conf->fc.low_water;
+ if (low_watermark > ICE_MAC_TC_MAX_WATERMARK)
+ low_watermark = ICE_MAC_TC_MAX_WATERMARK;
+
+ int cgd_idx = ice_get_cgd_idx(hw, tc);
+
+ if (high_watermark)
+ wr32(hw, GLRPB_TCHW(cgd_idx), high_watermark);
+ if (low_watermark)
+ wr32(hw, GLRPB_TCLW(cgd_idx), low_watermark);
+
+ /* Update pause quanta */
+ uint16_t max_frame_size = pf->dev_data->mtu ?
+ pf->dev_data->mtu + ICE_ETH_OVERHEAD :
+ ICE_FRAME_SIZE_MAX;
+ ret = ice_aq_set_mac_cfg(hw, max_frame_size, 1 << tc, pfc_conf->fc.pause_time,
+ (pfc_conf->fc.pause_time + 1) / 2, false, NULL);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Can not update MAC configuration");
+ return ret;
+ }
+
+ /* Update forwarding of the non FC MAC control frames settings */
+ if ((hw)->mac_type == ICE_MAC_E830) {
+#define E830_MAC_COMMAND_CONFIG(pi) (((pi)->phy.link_info.link_speed == ICE_AQ_LINK_SPEED_200GB) ? \
+ E830_PRTMAC_200G_COMMAND_CONFIG : E830_PRTMAC_COMMAND_CONFIG)
+
+ u32 mac_config = rd32(hw, E830_MAC_COMMAND_CONFIG(port_info));
+
+ if (pfc_conf->fc.mac_ctrl_frame_fwd)
+ mac_config |= E830_PRTMAC_COMMAND_CONFIG_CNTL_FRM_ENA_M;
+ else
+ mac_config &= ~E830_PRTMAC_COMMAND_CONFIG_CNTL_FRM_ENA_M;
+
+ wr32(hw, E830_MAC_COMMAND_CONFIG(port_info), mac_config);
+ }
+
+ return 0;
+}
+
static void
__vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
int base_queue, int nb_queue)
--
2.43.0
next prev parent reply other threads:[~2025-08-07 12:23 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-07 12:22 [PATCH 0/6] Enable DCB/PFC support for ICE PMD Vladimir Medvedkin
2025-08-07 12:22 ` [PATCH 1/6] net/ice/base: add utility functions Vladimir Medvedkin
2025-08-07 12:22 ` [PATCH 2/6] net/ice/base: make set MAC config TC aware Vladimir Medvedkin
2025-08-07 12:22 ` [PATCH 3/6] net/ice/base: add supports for assymetric PFC Vladimir Medvedkin
2025-08-07 12:22 ` [PATCH 4/6] net/ice: enable DCB support Vladimir Medvedkin
2025-08-07 12:22 ` Vladimir Medvedkin [this message]
2025-08-07 12:22 ` [PATCH 6/6] net/ice: add PFC statistics Vladimir Medvedkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250807122238.334177-6-vladimir.medvedkin@intel.com \
--to=vladimir.medvedkin@intel.com \
--cc=anatoly.burakov@intel.com \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).