* [PATCH v5 15/21] net/txgbe: fix FEC mode configuration on 25G NIC
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
The 25G NIC offers off, RS, Base-R, and auto FEC modes. When
reconfiguring the PHY, the FEC mode must match on both sides;
otherwise, the link cannot come up. The current driver fails to
maintain this requirement, causing link instability.
Add proper FEC mode handling during PHY reconfiguration to
guarantee link establishment.
Fixes: fb6eb170dfa2 ("net/txgbe: add basic link configuration for Amber-Lite")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_aml.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/txgbe/base/txgbe_aml.c b/drivers/net/txgbe/base/txgbe_aml.c
index 5d449a0bd9..ac80d85f08 100644
--- a/drivers/net/txgbe/base/txgbe_aml.c
+++ b/drivers/net/txgbe/base/txgbe_aml.c
@@ -282,6 +282,14 @@ s32 txgbe_setup_phy_link_aml(struct txgbe_hw *hw,
!(hw->fec_mode & hw->cur_fec_link)))
goto out;
+ if (speed == TXGBE_LINK_SPEED_25GB_FULL &&
+ link_speed == TXGBE_LINK_SPEED_25GB_FULL) {
+ txgbe_e56_fec_polling(hw, &link_up);
+
+ if (link_up)
+ goto out;
+ }
+
rte_spinlock_lock(&hw->phy_lock);
ret_status = txgbe_set_link_to_amlite(hw, speed);
rte_spinlock_unlock(&hw->phy_lock);
@@ -360,7 +368,10 @@ static s32 txgbe_setup_mac_link_multispeed_fiber_aml(struct txgbe_hw *hw,
/* If we already have link at this speed, just jump out */
txgbe_e56_check_phy_link(hw, &link_speed, &link_up);
- if (link_speed == TXGBE_LINK_SPEED_25GB_FULL && link_up)
+ hw->cur_fec_link = txgbe_phy_fec_get(hw);
+
+ if (link_speed == TXGBE_LINK_SPEED_25GB_FULL && link_up &&
+ hw->fec_mode & hw->cur_fec_link)
goto out;
/* Allow module to change analog characteristics (10G -> 25G) */
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 16/21] net/txgbe: fix SFP module identification
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
Some optical modules were not correctly recognized due to ambiguous
classification in the original detection flow. Rework the module
identification logic to cover all module types. Also narrow the
I2C lock scope to avoid potential race conditions during module
access.
Fixes: ab191e6d9189 ("net/txgbe: support new SFP/QSFP modules")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_hw.c | 2 -
drivers/net/txgbe/base/txgbe_phy.c | 341 ++++++++++------------------
drivers/net/txgbe/base/txgbe_phy.h | 18 +-
drivers/net/txgbe/base/txgbe_type.h | 2 +
4 files changed, 134 insertions(+), 229 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index 8b7cbd592a..c84656e206 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -2909,8 +2909,6 @@ s32 txgbe_init_ops_generic(struct txgbe_hw *hw)
phy->read_i2c_eeprom = txgbe_read_i2c_eeprom;
phy->write_i2c_eeprom = txgbe_write_i2c_eeprom;
phy->identify_sfp = txgbe_identify_module;
- phy->read_i2c_byte_unlocked = txgbe_read_i2c_byte_unlocked;
- phy->write_i2c_byte_unlocked = txgbe_write_i2c_byte_unlocked;
phy->check_overtemp = txgbe_check_overtemp;
phy->reset = txgbe_reset_phy;
phy->set_link_hostif = txgbe_hic_ephy_set_link;
diff --git a/drivers/net/txgbe/base/txgbe_phy.c b/drivers/net/txgbe/base/txgbe_phy.c
index f3e3491b30..727c9d2986 100644
--- a/drivers/net/txgbe/base/txgbe_phy.c
+++ b/drivers/net/txgbe/base/txgbe_phy.c
@@ -830,6 +830,10 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
return TXGBE_ERR_SFP_NOT_PRESENT;
}
+ err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ if (err)
+ return -EBUSY;
+
err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_IDENTIFIER,
&identifier);
if (err != 0) {
@@ -839,11 +843,13 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
hw->phy.id = 0;
hw->phy.type = txgbe_phy_unknown;
}
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return TXGBE_ERR_SFP_NOT_PRESENT;
}
if (identifier != TXGBE_SFF_IDENTIFIER_SFP) {
hw->phy.type = txgbe_phy_sfp_unsupported;
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return TXGBE_ERR_SFP_NOT_SUPPORTED;
}
@@ -888,7 +894,42 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
* 11 SFP_1g_sx_CORE0 - chip-specific
* 12 SFP_1g_sx_CORE1 - chip-specific
*/
- if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE) {
+ if (cable_tech & TXGBE_SFF_CABLE_DA_PASSIVE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type = txgbe_sfp_type_da_cu_core0;
+ else
+ hw->phy.sfp_type = txgbe_sfp_type_da_cu_core1;
+
+ if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
+ hw->dac_sfp = true;
+ }
+
+ if (comp_copper_len == TXGBE_SFF_COPPER_1M)
+ hw->bypass_ctle = true;
+ else
+ hw->bypass_ctle = false;
+
+ if (comp_codes_25g == TXGBE_SFF_25GBASECR_91FEC ||
+ comp_codes_25g == TXGBE_SFF_25GBASECR_74FEC ||
+ comp_codes_25g == TXGBE_SFF_25GBASECR_NOFEC) {
+ hw->phy.fiber_suppport_speed =
+ TXGBE_LINK_SPEED_25GB_FULL |
+ TXGBE_LINK_SPEED_10GB_FULL;
+ } else {
+ hw->phy.fiber_suppport_speed |=
+ TXGBE_LINK_SPEED_10GB_FULL;
+ }
+ } else if (comp_codes_25g == TXGBE_SFF_25GAUI_C2M_AOC_BER_5 ||
+ comp_codes_25g == TXGBE_SFF_25GAUI_C2M_ACC_BER_5 ||
+ comp_codes_25g == TXGBE_SFF_25GAUI_C2M_AOC_BER_12 ||
+ comp_codes_25g == TXGBE_SFF_25GAUI_C2M_ACC_BER_12) {
+ hw->dac_sfp = false;
+ hw->phy.sfp_type = (hw->bus.lan_id == 0
+ ? txgbe_sfp_type_25g_aoc_core0
+ : txgbe_sfp_type_25g_aoc_core1);
+ } else if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE) {
+ hw->dac_sfp = false;
err = hw->phy.read_i2c_eeprom(hw,
TXGBE_SFF_CABLE_SPEC_COMP, &cable_spec);
if (err != 0)
@@ -1005,6 +1046,7 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
/* Allow any DA cable vendor */
if (cable_tech & (TXGBE_SFF_CABLE_DA_PASSIVE |
TXGBE_SFF_CABLE_DA_ACTIVE)) {
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return 0;
}
@@ -1017,6 +1059,7 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1)) {
hw->phy.type = txgbe_phy_sfp_unsupported;
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return TXGBE_ERR_SFP_NOT_SUPPORTED;
}
@@ -1031,9 +1074,11 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1)) {
DEBUGOUT("SFP+ module not supported");
hw->phy.type = txgbe_phy_sfp_unsupported;
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return TXGBE_ERR_SFP_NOT_SUPPORTED;
}
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return err;
}
@@ -1046,28 +1091,13 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
{
s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
- u32 vendor_oui = 0;
- enum txgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
- u8 identifier = 0;
- u8 comp_codes_1g = 0;
- u8 comp_codes_10g = 0;
- u8 oui_bytes[3] = {0, 0, 0};
- u16 enforce_sfp = 0;
- u8 connector = 0;
- u8 cable_length = 0;
- u8 device_tech = 0;
- bool active_cable = false;
+ u8 identifier = 0, transceiver_type = 0;
u32 value;
- if (hw->phy.media_type != txgbe_media_type_fiber_qsfp) {
- hw->phy.sfp_type = txgbe_sfp_type_not_present;
- err = TXGBE_ERR_SFP_NOT_PRESENT;
- goto out;
- }
+ /* config GPIO before read i2c */
+ wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_1);
if (hw->mac.type == txgbe_mac_aml40) {
- /* config GPIO before read i2c */
- wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_1);
value = rd32(hw, TXGBE_GPIOEXT);
if (value & TXGBE_SFP1_MOD_PRST_LS) {
hw->phy.sfp_type = txgbe_sfp_type_not_present;
@@ -1075,175 +1105,68 @@ s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
}
}
- err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_IDENTIFIER,
- &identifier);
-ERR_I2C:
- if (err != 0) {
+ if (hw->phy.media_type != txgbe_media_type_fiber_qsfp) {
hw->phy.sfp_type = txgbe_sfp_type_not_present;
- hw->phy.id = 0;
- hw->phy.type = txgbe_phy_unknown;
return TXGBE_ERR_SFP_NOT_PRESENT;
}
- if (identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
- hw->phy.type = txgbe_phy_sfp_unsupported;
- err = TXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
-
- hw->phy.id = identifier;
-
- err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_QSFP_10GBE_COMP,
- &comp_codes_10g);
+ err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
if (err != 0)
- goto ERR_I2C;
+ return -EBUSY;
- err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_QSFP_1GBE_COMP,
- &comp_codes_1g);
+ err = hw->phy.read_i2c_sff8636(hw, 0, TXGBE_SFF_IDENTIFIER,
+ &identifier);
if (err != 0)
- goto ERR_I2C;
+ goto err_read_i2c_eeprom;
- if (comp_codes_10g & TXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
- hw->phy.type = txgbe_phy_qsfp_unknown_passive;
- if (hw->mac.type == txgbe_mac_aml40) {
+ if (identifier != TXGBE_SFF_IDENTIFIER_QSFP &&
+ identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
+ PMD_INIT_LOG(ERR, "port[%d] QSFP module not supported, identifier = 0x%x",
+ hw->bus.lan_id, identifier);
+ hw->phy.type = txgbe_phy_sfp_unsupported;
+ err = TXGBE_ERR_SFP_NOT_SUPPORTED;
+ } else {
+ err = hw->phy.read_i2c_sff8636(hw, 0,
+ TXGBE_ETHERNET_COMP_OFFSET,
+ &transceiver_type);
+ if (err != 0)
+ goto err_read_i2c_eeprom;
+
+ if (transceiver_type & TXGBE_SFF_ETHERNET_40G_CR4) {
if (hw->bus.lan_id == 0)
hw->phy.sfp_type = txgbe_qsfp_type_40g_cu_core0;
else
hw->phy.sfp_type = txgbe_qsfp_type_40g_cu_core1;
- } else {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type = txgbe_sfp_type_da_cu_core0;
- else
- hw->phy.sfp_type = txgbe_sfp_type_da_cu_core1;
- }
- } else if (comp_codes_10g & TXGBE_SFF_40GBASE_SR4) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type = txgbe_qsfp_type_40g_sr_core0;
- else
- hw->phy.sfp_type = txgbe_qsfp_type_40g_sr_core1;
- } else if (comp_codes_10g & TXGBE_SFF_40GBASE_LR4) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core0;
- else
- hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core1;
- } else if (comp_codes_10g & (TXGBE_SFF_10GBASESR_CAPABLE |
- TXGBE_SFF_10GBASELR_CAPABLE)) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type = txgbe_sfp_type_srlr_core0;
- else
- hw->phy.sfp_type = txgbe_sfp_type_srlr_core1;
- } else {
- if (comp_codes_10g & TXGBE_SFF_QSFP_DA_ACTIVE_CABLE)
- active_cable = true;
-
- if (!active_cable) {
- hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_QSFP_CONNECTOR,
- &connector);
-
- hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_QSFP_CABLE_LENGTH,
- &cable_length);
-
- hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_QSFP_DEVICE_TECH,
- &device_tech);
-
- if (connector ==
- TXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE &&
- cable_length > 0 &&
- ((device_tech >> 4) ==
- TXGBE_SFF_QSFP_TRANSMITTER_850NM_VCSEL))
- active_cable = true;
+ hw->phy.fiber_suppport_speed =
+ TXGBE_LINK_SPEED_40GB_FULL |
+ TXGBE_LINK_SPEED_10GB_FULL;
}
- if (active_cable) {
- hw->phy.type = txgbe_phy_qsfp_unknown_active;
+ if (transceiver_type & TXGBE_SFF_ETHERNET_40G_SR4) {
if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- txgbe_sfp_type_da_act_lmt_core0;
+ hw->phy.sfp_type = txgbe_qsfp_type_40g_sr_core0;
else
- hw->phy.sfp_type =
- txgbe_sfp_type_da_act_lmt_core1;
- } else {
- /* unsupported module type */
- hw->phy.type = txgbe_phy_sfp_unsupported;
- err = TXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
+ hw->phy.sfp_type = txgbe_qsfp_type_40g_sr_core1;
}
- }
-
- if (hw->phy.sfp_type != stored_sfp_type)
- hw->phy.sfp_setup_needed = true;
-
- /* Determine if the QSFP+ PHY is dual speed or not. */
- hw->phy.multispeed_fiber = false;
- if (((comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE) &&
- (comp_codes_10g & TXGBE_SFF_10GBASESR_CAPABLE)) ||
- ((comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE) &&
- (comp_codes_10g & TXGBE_SFF_10GBASELR_CAPABLE)))
- hw->phy.multispeed_fiber = true;
-
- /* Determine PHY vendor for optical modules */
- if (comp_codes_10g & (TXGBE_SFF_10GBASESR_CAPABLE |
- TXGBE_SFF_10GBASELR_CAPABLE)) {
- err = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
- &oui_bytes[0]);
-
- if (err != 0)
- goto ERR_I2C;
-
- err = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
- &oui_bytes[1]);
-
- if (err != 0)
- goto ERR_I2C;
- err = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
- &oui_bytes[2]);
-
- if (err != 0)
- goto ERR_I2C;
-
- vendor_oui =
- ((oui_bytes[0] << 24) |
- (oui_bytes[1] << 16) |
- (oui_bytes[2] << 8));
-
- if (vendor_oui == TXGBE_SFF_VENDOR_OUI_INTEL)
- hw->phy.type = txgbe_phy_qsfp_intel;
- else
- hw->phy.type = txgbe_phy_qsfp_unknown;
-
- hw->mac.get_device_caps(hw, &enforce_sfp);
- if (!(enforce_sfp & TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
- /* Make sure we're a supported PHY type */
- if (hw->phy.type == txgbe_phy_qsfp_intel) {
- err = 0;
- } else {
- if (hw->allow_unsupported_sfp) {
- DEBUGOUT("WARNING: Wangxun (R) Network Connections are quality tested using Wangxun (R) Ethernet Optics. "
- "Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. "
- "Wangxun Corporation is not responsible for any harm caused by using untested modules.");
- err = 0;
- } else {
- DEBUGOUT("QSFP module not supported");
- hw->phy.type =
- txgbe_phy_sfp_unsupported;
- err = TXGBE_ERR_SFP_NOT_SUPPORTED;
- }
- }
- } else {
- err = 0;
+ if (transceiver_type & TXGBE_SFF_ETHERNET_40G_LR4) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core0;
+ else
+ hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core1;
}
}
-out:
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return err;
+
+err_read_i2c_eeprom:
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ hw->phy.sfp_type = txgbe_sfp_type_not_present;
+ hw->phy.id = 0;
+ hw->phy.type = txgbe_phy_unknown;
+ return TXGBE_ERR_SFP_NOT_PRESENT;
}
/**
@@ -1278,6 +1201,28 @@ s32 txgbe_read_i2c_sff8472(struct txgbe_hw *hw, u8 byte_offset,
sff8472_data);
}
+/**
+ * txgbe_read_i2c_sff8636 - Reads 8 bit word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset at address 0xA2
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's SFF-8472 data over I2C
+ **/
+s32 txgbe_read_i2c_sff8636(struct txgbe_hw *hw, u8 page, u8 byte_offset,
+ u8 *sff8636_data)
+{
+ s32 err = hw->phy.write_i2c_byte(hw, TXGBE_SFF_QSFP_PAGE_SELECT,
+ TXGBE_I2C_EEPROM_DEV_ADDR,
+ page);
+ if (err != 0)
+ return err;
+
+ return hw->phy.read_i2c_byte(hw, byte_offset,
+ TXGBE_I2C_EEPROM_DEV_ADDR,
+ sff8636_data);
+}
+
/**
* txgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
* @hw: pointer to hardware structure
@@ -1295,7 +1240,7 @@ s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
}
/**
- * txgbe_read_i2c_byte_unlocked - Reads 8 bit word over I2C
+ * txgbe_read_i2c_byte - Reads 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to read
* @dev_addr: address to read from
@@ -1304,7 +1249,7 @@ s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
* Performs byte read operation to SFP module's EEPROM over I2C interface at
* a specified device address.
**/
-s32 txgbe_read_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
+s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data)
{
txgbe_i2c_start(hw, dev_addr);
@@ -1334,30 +1279,7 @@ s32 txgbe_read_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
}
/**
- * txgbe_read_i2c_byte - Reads 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to read
- * @dev_addr: address to read from
- * @data: value read
- *
- * Performs byte read operation to SFP module's EEPROM over I2C interface at
- * a specified device address.
- **/
-s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data)
-{
- u32 swfw_mask = hw->phy.phy_semaphore_mask;
- int err = 0;
-
- if (hw->mac.acquire_swfw_sync(hw, swfw_mask))
- return TXGBE_ERR_SWFW_SYNC;
- err = txgbe_read_i2c_byte_unlocked(hw, byte_offset, dev_addr, data);
- hw->mac.release_swfw_sync(hw, swfw_mask);
- return err;
-}
-
-/**
- * txgbe_write_i2c_byte_unlocked - Writes 8 bit word over I2C
+ * txgbe_write_i2c_byte - Writes 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to write
* @dev_addr: address to write to
@@ -1366,54 +1288,29 @@ s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
* Performs byte write operation to SFP module's EEPROM over I2C interface at
* a specified device address.
**/
-s32 txgbe_write_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
+s32 txgbe_write_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
{
txgbe_i2c_start(hw, dev_addr);
/* wait tx empty */
if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_TXEMPTY,
- TXGBE_I2CICR_TXEMPTY, NULL, 100, 100)) {
+ TXGBE_I2CICR_TXEMPTY, NULL, 100, 100))
return -TERR_TIMEOUT;
- }
- wr32(hw, TXGBE_I2CDATA, byte_offset | TXGBE_I2CDATA_STOP);
+ wr32(hw, TXGBE_I2CDATA, byte_offset);
wr32(hw, TXGBE_I2CDATA, data | TXGBE_I2CDATA_WRITE);
/* wait for write complete */
if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_RXFULL,
- TXGBE_I2CICR_RXFULL, NULL, 100, 100)) {
+ TXGBE_I2CICR_RXFULL, NULL, 100, 100))
return -TERR_TIMEOUT;
- }
+
txgbe_i2c_stop(hw);
return 0;
}
-/**
- * txgbe_write_i2c_byte - Writes 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @dev_addr: address to write to
- * @data: value to write
- *
- * Performs byte write operation to SFP module's EEPROM over I2C interface at
- * a specified device address.
- **/
-s32 txgbe_write_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
-{
- u32 swfw_mask = hw->phy.phy_semaphore_mask;
- int err = 0;
-
- if (hw->mac.acquire_swfw_sync(hw, swfw_mask))
- return TXGBE_ERR_SWFW_SYNC;
- err = txgbe_write_i2c_byte_unlocked(hw, byte_offset, dev_addr, data);
- hw->mac.release_swfw_sync(hw, swfw_mask);
-
- return err;
-}
-
/**
* txgbe_i2c_start - Sets I2C start condition
* @hw: pointer to hardware structure
diff --git a/drivers/net/txgbe/base/txgbe_phy.h b/drivers/net/txgbe/base/txgbe_phy.h
index 3fe7a34409..4da4be0d5f 100644
--- a/drivers/net/txgbe/base/txgbe_phy.h
+++ b/drivers/net/txgbe/base/txgbe_phy.h
@@ -261,7 +261,9 @@
#define TXGBE_SFF_SFF_8472_COMP 0x5E
#define TXGBE_SFF_SFF_8472_OSCB 0x6E
#define TXGBE_SFF_SFF_8472_ESCB 0x76
+#define TXGBE_SFF_QSFP_PAGE_SELECT 0x7F
+#define TXGBE_SFF_IDENTIFIER_QSFP 0x0C
#define TXGBE_SFF_IDENTIFIER_QSFP_PLUS 0x0D
#define TXGBE_SFF_QSFP_VENDOR_OUI_BYTE0 0xA5
#define TXGBE_SFF_QSFP_VENDOR_OUI_BYTE1 0xA6
@@ -289,6 +291,9 @@
#define TXGBE_SFF_4x10GBASESR_CAP 0x11
#define TXGBE_SFF_40GBASEPSM4_PARALLEL 0x12
#define TXGBE_SFF_40GBASE_SWMD4_CAP 0x1f
+#define TXGBE_SFF_COPPER_5M 0x5
+#define TXGBE_SFF_COPPER_3M 0x3
+#define TXGBE_SFF_COPPER_1M 0x1
#define TXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4
#define TXGBE_SFF_25GAUI_C2M_AOC_BER_5 0x1
@@ -296,6 +301,11 @@
#define TXGBE_SFF_25GAUI_C2M_AOC_BER_12 0x18
#define TXGBE_SFF_25GAUI_C2M_ACC_BER_12 0x19
+#define TXGBE_ETHERNET_COMP_OFFSET 0x83
+#define TXGBE_SFF_ETHERNET_40G_CR4 MS(3, 0x1)
+#define TXGBE_SFF_ETHERNET_40G_SR4 MS(2, 0x1)
+#define TXGBE_SFF_ETHERNET_40G_LR4 MS(1, 0x1)
+
#define TXGBE_SFF_SOFT_RS_SELECT_MASK 0x8
#define TXGBE_SFF_SOFT_RS_SELECT_10G 0x8
#define TXGBE_SFF_SOFT_RS_SELECT_1G 0x0
@@ -493,14 +503,12 @@ s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw);
s32 txgbe_check_overtemp(struct txgbe_hw *hw);
s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
-s32 txgbe_read_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data);
s32 txgbe_write_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data);
-s32 txgbe_write_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data);
s32 txgbe_read_i2c_sff8472(struct txgbe_hw *hw, u8 byte_offset,
- u8 *sff8472_data);
+ u8 *sff8472_data);
+s32 txgbe_read_i2c_sff8636(struct txgbe_hw *hw, u8 page, u8 byte_offset,
+ u8 *sff8636_data);
s32 txgbe_read_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
u8 *eeprom_data);
s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
diff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h
index 47629aa9e0..2e2d79e0e1 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -702,6 +702,8 @@ struct txgbe_phy_info {
u8 dev_addr, u8 data);
s32 (*read_i2c_sff8472)(struct txgbe_hw *hw, u8 byte_offset,
u8 *sff8472_data);
+ s32 (*read_i2c_sff8636)(struct txgbe_hw *hw, u8 page, u8 byte_offset,
+ u8 *sff8636_data);
s32 (*read_i2c_eeprom)(struct txgbe_hw *hw, u8 byte_offset,
u8 *eeprom_data);
s32 (*write_i2c_eeprom)(struct txgbe_hw *hw, u8 byte_offset,
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 17/21] net/txgbe: fix get module info operation
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
The original I2C access flow in the module information retrieval
process was flawed. Correct the implementation to properly fetch
module info.
Fixes: abf042d32b39 ("net/txgbe: add Amber-Lite 25G/40G NICs")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_phy.h | 6 +-
drivers/net/txgbe/txgbe_ethdev.c | 118 +++++++++++++++++++++++------
2 files changed, 98 insertions(+), 26 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_phy.h b/drivers/net/txgbe/base/txgbe_phy.h
index 4da4be0d5f..581f667bdc 100644
--- a/drivers/net/txgbe/base/txgbe_phy.h
+++ b/drivers/net/txgbe/base/txgbe_phy.h
@@ -257,11 +257,15 @@
#define TXGBE_SFF_CABLE_DA_PASSIVE 0x4
#define TXGBE_SFF_CABLE_DA_ACTIVE 0x8
#define TXGBE_SFF_CABLE_SPEC_COMP 0x3C
+#define TXGBE_SFF_DDM_IMPLEMENTED 0x40
#define TXGBE_SFF_SFF_8472_SWAP 0x5C
#define TXGBE_SFF_SFF_8472_COMP 0x5E
#define TXGBE_SFF_SFF_8472_OSCB 0x6E
#define TXGBE_SFF_SFF_8472_ESCB 0x76
-#define TXGBE_SFF_QSFP_PAGE_SELECT 0x7F
+#define TXGBE_SFF_SFF_REVISION_ADDR 0x01
+#define TXGBE_SFF_QSFP_PAGE_SELECT 0x7F
+
+#define TXGBE_MODULE_QSFP_MAX_LEN 640
#define TXGBE_SFF_IDENTIFIER_QSFP 0x0C
#define TXGBE_SFF_IDENTIFIER_QSFP_PLUS 0x0D
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index f1119cf6f8..84c0a856e5 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -5348,41 +5348,109 @@ txgbe_get_module_info(struct rte_eth_dev *dev,
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
uint32_t status;
uint8_t sff8472_rev, addr_mode;
+ uint8_t identifier;
+ uint8_t sff8636_rev;
bool page_swap = false;
+ uint32_t value;
- /* Check whether we support SFF-8472 or not */
- status = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_SFF_8472_COMP,
- &sff8472_rev);
- if (status != 0)
- return -EIO;
+ if (hw->mac.type == txgbe_mac_aml40) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_PRST_LS) {
+ PMD_DRV_LOG(WARNING, "QSFP module not present, cannot get module info.");
+ return -EINVAL;
+ }
+ }
- /* addressing mode is not supported */
- status = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_SFF_8472_SWAP,
- &addr_mode);
+ if (hw->mac.type == txgbe_mac_aml) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_ABS_LS) {
+ PMD_DRV_LOG(WARNING, "SFP module not present, cannot get module info.");
+ return -EINVAL;
+ }
+ }
+
+ status = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
if (status != 0)
- return -EIO;
+ return -EBUSY;
- if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) {
- PMD_DRV_LOG(ERR,
- "Address change required to access page 0xA2, "
- "but not supported. Please report the module "
- "type to the driver maintainers.");
- page_swap = true;
+ if (hw->mac.type == txgbe_mac_aml40) {
+ status = hw->phy.read_i2c_sff8636(hw, 0,
+ TXGBE_SFF_IDENTIFIER,
+ &identifier);
+ } else {
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_IDENTIFIER,
+ &identifier);
}
- if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap) {
- /* We have a SFP, but it does not support SFF-8472 */
- modinfo->type = RTE_ETH_MODULE_SFF_8079;
- modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
- } else {
- /* We have a SFP which supports a revision of SFF-8472. */
- modinfo->type = RTE_ETH_MODULE_SFF_8472;
- modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ if (status != 0)
+ goto ERROR_IO;
+
+ switch (identifier) {
+ case TXGBE_SFF_IDENTIFIER_SFP:
+ /* Check whether we support SFF-8472 or not */
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_SFF_8472_COMP,
+ &sff8472_rev);
+ if (status != 0)
+ goto ERROR_IO;
+
+ /* addressing mode is not supported */
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_SFF_8472_SWAP,
+ &addr_mode);
+ if (status != 0)
+ goto ERROR_IO;
+
+ if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) {
+ PMD_DRV_LOG(ERR,
+ "Address change required to access page 0xA2, "
+ "but not supported. Please report the module "
+ "type to the driver maintainers.");
+ page_swap = true;
+ }
+
+ if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap ||
+ !(addr_mode & TXGBE_SFF_DDM_IMPLEMENTED)) {
+ /* We have a SFP, but it does not support SFF-8472 */
+ modinfo->type = RTE_ETH_MODULE_SFF_8079;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
+ } else {
+ /* We have a SFP which supports a revision of SFF-8472. */
+ modinfo->type = RTE_ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ }
+ break;
+ case TXGBE_SFF_IDENTIFIER_QSFP:
+ case TXGBE_SFF_IDENTIFIER_QSFP_PLUS:
+ status = hw->phy.read_i2c_sff8636(hw, 0,
+ TXGBE_SFF_SFF_REVISION_ADDR,
+ &sff8636_rev);
+ if (status != 0)
+ goto ERROR_IO;
+ /* Check revision compliance */
+ if (sff8636_rev > 0x02) {
+ /* Module is SFF-8636 compliant */
+ modinfo->type = RTE_ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = TXGBE_MODULE_QSFP_MAX_LEN;
+ } else {
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = TXGBE_MODULE_QSFP_MAX_LEN;
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "SFF Module Type not recognized, identifier=0x%x", identifier);
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ return -EINVAL;
}
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return 0;
+
+ERROR_IO:
+ PMD_DRV_LOG(ERR, "I2C IO ERROR.");
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ return -EIO;
}
static int
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 18/21] net/txgbe: fix get EEPROM operation
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
The original I2C access flow in the module information retrieval
process was flawed. Correct the implementation to properly fetch
module info.
Fixes: abf042d32b39 ("net/txgbe: add Amber-Lite 25G/40G NICs")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/txgbe_ethdev.c | 67 ++++++++++++++++++++++++++++----
1 file changed, 60 insertions(+), 7 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 84c0a856e5..96532a015e 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -5462,23 +5462,76 @@ txgbe_get_module_eeprom(struct rte_eth_dev *dev,
uint8_t databyte = 0xFF;
uint8_t *data = info->data;
uint32_t i = 0;
+ bool is_sfp = false;
+ uint32_t value;
+ uint8_t identifier = 0;
+ uint16_t offset;
+ uint8_t page = 0;
+
+ if (hw->mac.type == txgbe_mac_aml40) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_PRST_LS)
+ return -EIO;
+ }
+
+ if (hw->mac.type == txgbe_mac_aml) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_ABS_LS)
+ return -EIO;
+ }
if (info->length == 0)
return -EINVAL;
- for (i = info->offset; i < info->offset + info->length; i++) {
- if (i < RTE_ETH_MODULE_SFF_8079_LEN)
- status = hw->phy.read_i2c_eeprom(hw, i, &databyte);
- else
- status = hw->phy.read_i2c_sff8472(hw, i, &databyte);
+ status = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ if (status)
+ return -EBUSY;
- if (status != 0)
- return -EIO;
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_IDENTIFIER,
+ &identifier);
+ if (status != 0)
+ goto ERROR_IO;
+
+ if (identifier == TXGBE_SFF_IDENTIFIER_SFP)
+ is_sfp = true;
+ memset(data, 0, info->length);
+
+ for (i = info->offset; i < info->offset + info->length; i++) {
+ if (is_sfp) {
+ if (i < RTE_ETH_MODULE_SFF_8079_LEN)
+ status = hw->phy.read_i2c_eeprom(hw, i,
+ &databyte);
+ else
+ status = hw->phy.read_i2c_sff8472(hw, i,
+ &databyte);
+
+ if (status != 0)
+ goto ERROR_IO;
+ } else {
+ offset = i;
+ while (offset >= RTE_ETH_MODULE_SFF_8436_LEN) {
+ offset -= RTE_ETH_MODULE_SFF_8436_LEN / 2;
+ page++;
+ }
+ if (page == 0 || !(data[0x2] & 0x4)) {
+ status = hw->phy.read_i2c_sff8636(hw, page, offset,
+ &databyte);
+ if (status != 0)
+ goto ERROR_IO;
+ }
+ }
data[i - info->offset] = databyte;
}
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return 0;
+
+ERROR_IO:
+ PMD_DRV_LOG(ERR, "I2C IO ERROR.");
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ return -EIO;
}
bool
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 19/21] net/txgbe: fix to reset Tx write-back pointer
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
The write-back pointer was not reset when the Tx queue was reset. This
leads to the wrong Tx desc free logic. Move the resetting of pointer into
txq->ops->reset(txq).
Fixes: 8ada71d0bb7f ("net/txgbe: add Tx head write-back mode for Amber-Lite")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 45 +++++++++++++----------
drivers/net/txgbe/txgbe_rxtx.h | 1 +
drivers/net/txgbe/txgbe_rxtx_vec_common.h | 7 ++++
3 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index ea4947201e..d27f2915f8 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -2311,6 +2311,12 @@ txgbe_reset_tx_queue(struct txgbe_tx_queue *txq)
txq->tx_next_dd = (uint16_t)(txq->tx_free_thresh - 1);
txq->tx_tail = 0;
+ /* Zero out headwb_mem memory */
+ if (txq->headwb_mem) {
+ for (i = 0; i < txq->headwb_size; i++)
+ txq->headwb_mem[i] = 0;
+ }
+
/*
* Always allow 1 descriptor to be un-allocated to avoid
* a H/W race condition
@@ -2410,7 +2416,7 @@ txgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
return tx_offload_capa;
}
-static int
+static void
txgbe_setup_headwb_resources(struct rte_eth_dev *dev,
void *tx_queue,
unsigned int socket_id)
@@ -2418,33 +2424,33 @@ txgbe_setup_headwb_resources(struct rte_eth_dev *dev,
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
const struct rte_memzone *headwb;
struct txgbe_tx_queue *txq = tx_queue;
- u8 i, headwb_size = 0;
+ u8 headwb_size = 0;
- if (hw->mac.type != txgbe_mac_aml && hw->mac.type != txgbe_mac_aml40) {
- txq->headwb_mem = NULL;
- return 0;
- }
+ if (hw->mac.type != txgbe_mac_aml && hw->mac.type != txgbe_mac_aml40)
+ goto out;
+
+ if (!hw->devarg.tx_headwb)
+ goto out;
- headwb_size = hw->devarg.tx_headwb_size;
+ headwb_size = txq->headwb_size;
headwb = rte_eth_dma_zone_reserve(dev, "tx_headwb_mem", txq->queue_id,
sizeof(u32) * headwb_size,
TXGBE_ALIGN, socket_id);
if (headwb == NULL) {
- DEBUGOUT("Fail to setup headwb resources: no mem");
- txgbe_tx_queue_release(txq);
- return -ENOMEM;
+ PMD_DRV_LOG(INFO,
+ "Failed to allocate headwb memory for Tx queue %u, change to SP mode",
+ txq->queue_id);
+ goto out;
}
txq->headwb = headwb;
txq->headwb_dma = TMZ_PADDR(headwb);
txq->headwb_mem = (uint32_t *)TMZ_VADDR(headwb);
+ return;
- /* Zero out headwb_mem memory */
- for (i = 0; i < headwb_size; i++)
- txq->headwb_mem[i] = 0;
-
- return 0;
+out:
+ txq->headwb_mem = NULL;
}
int __rte_cold
@@ -2540,6 +2546,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
txq->offloads = offloads;
txq->ops = &def_txq_ops;
txq->tx_deferred_start = tx_conf->tx_deferred_start;
+ txq->headwb_size = hw->devarg.tx_headwb_size;
#ifdef RTE_LIB_SECURITY
txq->using_ipsec = !!(dev->data->dev_conf.txmode.offloads &
RTE_ETH_TX_OFFLOAD_SECURITY);
@@ -2575,8 +2582,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
/* set up scalar TX function as appropriate */
txgbe_set_tx_function(dev, txq);
- if (hw->devarg.tx_headwb)
- err = txgbe_setup_headwb_resources(dev, txq, socket_id);
+ txgbe_setup_headwb_resources(dev, txq, socket_id);
txq->ops->reset(txq);
txq->desc_error = 0;
@@ -4753,15 +4759,14 @@ txgbe_dev_tx_init(struct rte_eth_dev *dev)
wr32(hw, TXGBE_TXRP(txq->reg_idx), 0);
wr32(hw, TXGBE_TXWP(txq->reg_idx), 0);
- if ((hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) &&
- hw->devarg.tx_headwb) {
+ if (txq->headwb_mem) {
uint32_t txdctl;
wr32(hw, TXGBE_PX_TR_HEAD_ADDRL(txq->reg_idx),
(uint32_t)(txq->headwb_dma & BIT_MASK32));
wr32(hw, TXGBE_PX_TR_HEAD_ADDRH(txq->reg_idx),
(uint32_t)(txq->headwb_dma >> 32));
- if (hw->devarg.tx_headwb_size == 16)
+ if (txq->headwb_size == 16)
txdctl = TXGBE_PX_TR_CFG_HEAD_WB |
TXGBE_PX_TR_CFG_HEAD_WB_64BYTE;
else
diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
index 43c818cfbf..5d2e33a8d4 100644
--- a/drivers/net/txgbe/txgbe_rxtx.h
+++ b/drivers/net/txgbe/txgbe_rxtx.h
@@ -416,6 +416,7 @@ struct txgbe_tx_queue {
uint64_t desc_error;
bool resetting;
const struct rte_memzone *headwb;
+ uint16_t headwb_size;
uint64_t headwb_dma;
volatile uint32_t *headwb_mem;
};
diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_common.h b/drivers/net/txgbe/txgbe_rxtx_vec_common.h
index 3671326084..3696c3557b 100644
--- a/drivers/net/txgbe/txgbe_rxtx_vec_common.h
+++ b/drivers/net/txgbe/txgbe_rxtx_vec_common.h
@@ -251,6 +251,13 @@ _txgbe_reset_tx_queue_vec(struct txgbe_tx_queue *txq)
txq->tx_next_dd = (uint16_t)(txq->tx_free_thresh - 1);
txq->tx_tail = 0;
+
+ /* Zero out headwb_mem memory */
+ if (txq->headwb_mem) {
+ for (i = 0; i < txq->headwb_size; i++)
+ txq->headwb_mem[i] = 0;
+ }
+
/*
* Always allow 1 descriptor to be un-allocated to avoid
* a H/W race condition
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 20/21] net/txgbe: fix to enable Tx desc check
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
Now lib security is enabled by default, and cannot be disabled if the
driver is intended to be used. So Tdm_desc_chk is always unable to enable.
Remove this restriction, and just enable the corresponding queue check.
Fixes: 0eabdfcd4af4 ("net/txgbe: enable Tx descriptor error interrupt")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index d27f2915f8..9c3b403ba5 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -4759,6 +4759,12 @@ txgbe_dev_tx_init(struct rte_eth_dev *dev)
wr32(hw, TXGBE_TXRP(txq->reg_idx), 0);
wr32(hw, TXGBE_TXWP(txq->reg_idx), 0);
+#ifdef RTE_LIBRTE_SECURITY
+ if (!txq->using_ipsec)
+#endif
+ wr32m(hw, TXGBE_TDM_DESC_CHK(txq->reg_idx / 32),
+ RTE_BIT32(txq->reg_idx % 32), RTE_BIT32(txq->reg_idx % 32));
+
if (txq->headwb_mem) {
uint32_t txdctl;
@@ -4776,11 +4782,6 @@ txgbe_dev_tx_init(struct rte_eth_dev *dev)
}
}
-#ifndef RTE_LIB_SECURITY
- for (i = 0; i < 4; i++)
- wr32(hw, TXGBE_TDM_DESC_CHK(i), 0xFFFFFFFF);
-#endif
-
/* Device configured with multiple TX queues. */
txgbe_dev_mq_tx_configure(dev);
}
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 21/21] net/txgbe: fix temperature track for AML NIC
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
Previously, temperature tracking for the amlite NIC was handled by
firmware together with the hardware setup. However, the firmware-based
PHY configuration has proven to be unstable.
Re-add the temperature tracking function directly in the driver and
invoke it periodically to ensure the PHY remains calibrated. According
to the hardware recommendation, the tracking sequence should be run at
least every 100 ms to keep temperature drift within 5 °C. Considering
the software and hardware overhead, a 2-second interval is used as a
practical trade-off that still meets stability requirements while
minimizing performance impact.
The periodic tracking is implemented using a timer in the driver, and
the sequence itself is the same as the one originally performed during
link setup.
Fixes: fb6eb170dfa2 ("net/txgbe: add basic link configuration for Amber-Lite")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/txgbe_ethdev.c | 44 +++++++++++++++++++++++++++++++-
drivers/net/txgbe/txgbe_ethdev.h | 1 +
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 96532a015e..155d8f08ba 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -2011,8 +2011,10 @@ txgbe_dev_start(struct rte_eth_dev *dev)
txgbe_filter_restore(dev);
hw->bp_event_interval = 100 * 1000;
- if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40)
+ if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
rte_eal_alarm_set(hw->bp_event_interval, txgbe_dev_e56_check_bp_event, dev);
+ rte_eal_alarm_set(1000 * 1000 * 2, txgbe_dev_check_aml_temp_event, dev);
+ }
if (tm_conf->root && !tm_conf->committed)
PMD_DRV_LOG(WARNING,
@@ -2060,6 +2062,7 @@ txgbe_dev_stop(struct rte_eth_dev *dev)
if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
rte_eal_alarm_cancel(txgbe_dev_e56_check_bp_event, dev);
+ rte_eal_alarm_cancel(txgbe_dev_check_aml_temp_event, dev);
rte_eal_alarm_cancel(txgbe_dev_setup_link_alarm_handler_aml, hw);
}
@@ -2932,6 +2935,45 @@ txgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
return NULL;
}
+void txgbe_dev_check_aml_temp_event(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ uint32_t link_speed = 0, val = 0;
+ s32 status = 0;
+ int temp;
+
+ if (hw == NULL)
+ return;
+
+ status = txgbe_e56_get_temp(hw, &temp);
+ if (status)
+ temp = DEFAULT_TEMP;
+
+ if (!(temp - hw->temperature > 4 ||
+ hw->temperature - temp > 4))
+ goto out;
+
+ hw->temperature = temp;
+ val = rd32(hw, TXGBE_PORT);
+ if (val & TXGBE_AMLITE_LED_LINK_40G)
+ link_speed = TXGBE_LINK_SPEED_40GB_FULL;
+ else if (val & TXGBE_AMLITE_LED_LINK_25G)
+ link_speed = TXGBE_LINK_SPEED_25GB_FULL;
+ else
+ link_speed = TXGBE_LINK_SPEED_10GB_FULL;
+
+ rte_spinlock_lock(&hw->phy_lock);
+ if (hw->mac.type == txgbe_mac_aml)
+ txgbe_temp_track_seq(hw, link_speed);
+ else if (hw->mac.type == txgbe_mac_aml40)
+ txgbe_temp_track_seq_40g(hw, link_speed);
+ rte_spinlock_unlock(&hw->phy_lock);
+
+out:
+ rte_eal_alarm_set(1000 * 1000 * 2, txgbe_dev_check_aml_temp_event, dev);
+}
+
void txgbe_dev_e56_check_bp_event(void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index 309db3bfe9..c32c61d8bf 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -747,5 +747,6 @@ void txgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev,
uint16_t queue, bool on);
void txgbe_config_vlan_strip_on_all_queues(struct rte_eth_dev *dev,
int mask);
+void txgbe_dev_check_aml_temp_event(void *param);
void txgbe_dev_e56_check_bp_event(void *param);
#endif /* _TXGBE_ETHDEV_H_ */
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 10/21] net/txgbe: fix a mass of unknown interrupts
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu, Ferruh Yigit
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
When RSC is enabled, Rx ring IVAR is set to configure ITR. It causes Rx
ring interrupts report on the default msix_vector. Thus a mass of unknown
interrupts occupy CPU.
Fix the issue by setting ring IVAR only when the rxq interrupt is enabled.
Fixes: be797cbf4582 ("net/txgbe: add Rx and Tx init")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 2639712336..28b06f3b93 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -4345,6 +4345,8 @@ static int
txgbe_set_rsc(struct rte_eth_dev *dev)
{
struct rte_eth_rxmode *rx_conf = &dev->data->dev_conf.rxmode;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
struct rte_eth_dev_info dev_info = { 0 };
bool rsc_capable = false;
@@ -4395,8 +4397,6 @@ txgbe_set_rsc(struct rte_eth_dev *dev)
rd32(hw, TXGBE_RXCFG(rxq->reg_idx));
uint32_t psrtype =
rd32(hw, TXGBE_POOLRSS(rxq->reg_idx));
- uint32_t eitr =
- rd32(hw, TXGBE_ITR(rxq->reg_idx));
/*
* txgbe PMD doesn't support header-split at the moment.
@@ -4415,6 +4415,9 @@ txgbe_set_rsc(struct rte_eth_dev *dev)
srrctl |= txgbe_get_rscctl_maxdesc(rxq->mb_pool);
psrtype |= TXGBE_POOLRSS_L4HDR;
+ wr32(hw, TXGBE_RXCFG(rxq->reg_idx), srrctl);
+ wr32(hw, TXGBE_POOLRSS(rxq->reg_idx), psrtype);
+
/*
* RSC: Set ITR interval corresponding to 2K ints/s.
*
@@ -4428,19 +4431,20 @@ txgbe_set_rsc(struct rte_eth_dev *dev)
* For a sparse streaming case this setting will yield
* at most 500us latency for a single RSC aggregation.
*/
- eitr &= ~TXGBE_ITR_IVAL_MASK;
- eitr |= TXGBE_ITR_IVAL_10G(TXGBE_QUEUE_ITR_INTERVAL_DEFAULT);
- eitr |= TXGBE_ITR_WRDSA;
+ if (rte_intr_dp_is_en(intr_handle)) {
+ uint32_t eitr = rd32(hw, TXGBE_ITR(rxq->reg_idx));
- wr32(hw, TXGBE_RXCFG(rxq->reg_idx), srrctl);
- wr32(hw, TXGBE_POOLRSS(rxq->reg_idx), psrtype);
- wr32(hw, TXGBE_ITR(rxq->reg_idx), eitr);
+ eitr &= ~TXGBE_ITR_IVAL_MASK;
+ eitr |= TXGBE_ITR_IVAL_10G(TXGBE_QUEUE_ITR_INTERVAL_DEFAULT);
+ eitr |= TXGBE_ITR_WRDSA;
+ wr32(hw, TXGBE_ITR(rxq->reg_idx), eitr);
- /*
- * RSC requires the mapping of the queue to the
- * interrupt vector.
- */
- txgbe_set_ivar_map(hw, 0, rxq->reg_idx, i);
+ /*
+ * RSC requires the mapping of the queue to the
+ * interrupt vector.
+ */
+ txgbe_set_ivar_map(hw, 0, rxq->reg_idx, i);
+ }
}
dev->data->lro = 1;
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v5 11/21] net/txgbe: fix traffic class priority configuration
From: Zaiyu Wang @ 2026-05-27 13:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu, Ferruh Yigit
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
After applying the following testpmd command, 802.1Q packets with specific
priorities were not properly directed to the corresponding traffic classes:
port config 0 dcb vt off 4 pfc off
The old driver had two issues:
1. The hardware uses a 4-bit mapping register per traffic class for
priority-to-TC mapping, but the driver incorrectly configured it
as 3 bits.
2. The DCB TX configuration mistakenly wrote to the RX register.
Fix both issues, ensuring that tc-prio mapping works as expected.
Additionally, remove the stale and inconsistent TXGBE_DCBUP2TC_DEC macro as
it has no callers.
Fixes: 8bdc7882f376 ("net/txgbe: support DCB")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_dcb_hw.c | 2 +-
drivers/net/txgbe/base/txgbe_regs.h | 6 ++----
drivers/net/txgbe/txgbe_rxtx.c | 7 ++-----
3 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_dcb_hw.c b/drivers/net/txgbe/base/txgbe_dcb_hw.c
index 75c91a6b6a..79e1da447b 100644
--- a/drivers/net/txgbe/base/txgbe_dcb_hw.c
+++ b/drivers/net/txgbe/base/txgbe_dcb_hw.c
@@ -154,7 +154,7 @@ s32 txgbe_dcb_config_tx_data_arbiter_raptor(struct txgbe_hw *hw, u16 *refill,
for (i = 0; i < TXGBE_DCB_UP_MAX; i++)
reg |= TXGBE_DCBUP2TC_MAP(i, map[i]);
- wr32(hw, TXGBE_PBRXUP2TC, reg);
+ wr32(hw, TXGBE_PBTXUP2TC, reg);
/* Configure traffic class credits and priority */
for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index 22c46e3d56..4aa62919b4 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -503,10 +503,8 @@
#define TXGBE_PBRXCTL 0x019000
#define TXGBE_PBRXCTL_ST MS(0, 0x1)
#define TXGBE_PBRXCTL_ENA MS(31, 0x1)
-#define TXGBE_PBRXUP2TC 0x019008
#define TXGBE_PBTXUP2TC 0x01C800
-#define TXGBE_DCBUP2TC_MAP(tc, v) LS(v, 3 * (tc), 0x7)
-#define TXGBE_DCBUP2TC_DEC(tc, r) RS(r, 3 * (tc), 0x7)
+#define TXGBE_DCBUP2TC_MAP(tc, v) LS(v, 4 * (tc), 0x7)
#define TXGBE_PBRXSIZE(tc) (0x019020 + (tc) * 4)
#define TXGBE_PBRXSIZE_KB(v) LS(v, 10, 0x3FF)
@@ -1705,7 +1703,7 @@ enum txgbe_5tuple_protocol {
#define TXGBE_RDM_PF_HIDE(_i) (0x12090 + ((_i) * 4))
#define TXGBE_RPUP2TC 0x019008
-#define TXGBE_RPUP2TC_UP_SHIFT 3
+#define TXGBE_RPUP2TC_UP_SHIFT 4
#define TXGBE_RPUP2TC_UP_MASK 0x7
#define TXGBE_RDM_DCACHE_CTL 0x0120A8
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 28b06f3b93..ea4947201e 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -3376,11 +3376,8 @@ txgbe_vmdq_dcb_configure(struct rte_eth_dev *dev)
queue_mapping = 0;
for (i = 0; i < RTE_ETH_DCB_NUM_USER_PRIORITIES; i++)
- /*
- * mapping is done with 3 bits per priority,
- * so shift by i*3 each time
- */
- queue_mapping |= ((cfg->dcb_tc[i] & 0x07) << (i * 3));
+ queue_mapping |= ((cfg->dcb_tc[i] & TXGBE_RPUP2TC_UP_MASK) <<
+ (i * TXGBE_RPUP2TC_UP_SHIFT));
wr32(hw, TXGBE_RPUP2TC, queue_mapping);
--
2.21.0.windows.1
^ permalink raw reply related
* Re: [PATCH v5 03/27] net/intel/common: add common flow action parsing
From: Bruce Richardson @ 2026-05-27 13:25 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev
In-Reply-To: <00d686796ef0440ca63220d468ed3d15ccf4894a.1779717943.git.anatoly.burakov@intel.com>
On Mon, May 25, 2026 at 03:06:22PM +0100, Anatoly Burakov wrote:
> Currently, each driver has their own code for action parsing, which results
> in a lot of duplication and subtle mismatches in behavior between drivers.
>
> Add common infrastructure, based on the following assumptions:
>
> - All drivers support at most 4 actions at once, but usually less
> - Not every action is supported by all drivers
> - We can check a few common things to filter out obviously wrong actions
> - Driver performs semantic checks on all valid actions
>
> So, the intention is to reject everything we can reasonably reject at the
> outset without knowing anything about the drivers, parametrize what is
> trivial to parametrize, and leave the rest for the driver to implement.
>
> While we're at it, also add logging infrastructure for Intel common code,
> using the new component name defines that are automatically passed to each
> DPDK driver as it is being built.
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
<snip>
> +
> +static inline int
> +__flow_action_check_rss(const struct rte_flow_action_rss *rss,
> + const struct ci_flow_actions_check_param *param,
> + struct rte_flow_error *error)
> +{
> + uint32_t qnum, q;
> +
> + qnum = rss->queue_num;
> +
> + /* either we have both queues and queue number, or we have neither */
> + if ((qnum == 0) != (rss->queue == NULL)) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
> + "If queue number is specified, queue array must also be specified");
> + }
> + /* check if queues are monotonic */
> + for (q = 1; q < qnum; q++) {
> + if (rss->queue[q] < rss->queue[q - 1]) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
> + "RSS queues must be in ascending order");
> + }
> + /* if user has requested contiguousness, check that as well */
> + if (param == NULL || !param->rss_queues_contig)
> + continue;
> + if (rss->queue[q] != rss->queue[0] + q) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
> + "RSS queues must be contiguous");
> + }
> + }
> + /* if user has requested to check for queue contiguousness, do it */
> + if (param != NULL && param->rss_queues_contig) {
> + }
> +
Empty block, and I don't see it filled in later patches. Is this for future
use, or just an oversight? I see the check for contiguity done in the loop
above.
^ permalink raw reply
* Re: [PATCH v3 4/5] net/iavf: accept up to 32k unicast MAC addresses
From: David Marchand @ 2026-05-27 13:25 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, rjarry, cfontain, Vladimir Medvedkin
In-Reply-To: <20260512164154.00d109c5@stephen-xps.local>
On Tue, 12 May 2026 at 16:42, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Sun, 10 May 2026 19:03:04 +0200
> David Marchand <david.marchand@redhat.com> wrote:
>
> > E810 hardware provides 32k switch lookups.
> > Thanks to this, it is possible to allow a lot more secondary mac
> > addresses than what is possible today.
> >
> > In practice, the maximum number of macs available per port may be lower
> > and depends on usage by other (trusted?) VFs on the same PF.
> > There is no way to figure out this limit but to try adding a mac address
> > and get an error from the PF driver.
> >
> > Mailbox exchanges are limited to IAVF_AQ_BUF_SZ, segment messages
> > accordingly.
> >
> > Signed-off
>
> AI review feedback; nothing major but worth a look
In the first revision, it was interesting, but now, that's a lot of noise.
>
> Series: ethdev: VMDq cleanup and iavf: 32k MACs / duplicate install fix
> Tree: dpdk main (DPDK 26.07)
>
> Patch 2 - ethdev: skip VMDq pools unless configured
> Info
> Doxygen of rte_eth_dev_mac_addr_add() is not updated to describe the
> new constraint that pool must be 0 when VMDq is not configured. The
> function-level @param documentation and @return list should mention
> that -EINVAL is now returned when VMDq is disabled and pool != 0.
* @param pool
* VMDq pool index to associate address with (if VMDq is enabled).
If VMDq is
* not enabled, this should be set to 0.
It has been documented since the start that a 0 pool should be passed.
I can update the return code EINVAL.
>
> Subtle behavior change: when VMDq is not configured, mac_pool_sel[index]
> is no longer set to RTE_BIT64(0) on add. Before this patch every added
> MAC ended up with bit 0 set; afterwards the array stays at 0. This is
> consistent with the new restore path (which now uses the VMDq flag
> rather than walking pool_mask in the !vmdq case), but the change in
> observable state of dev->data->mac_pool_sel[] could surprise an out-of-
> tree consumer. Worth a sentence in the API change note.
This is really internal stuff, only drivers would access this, and we
don't care about such out of tree consumer.
>
> Patch 4 - net/iavf: accept up to 32k unicast MAC addresses
> Info
> Release notes wording: "secondary MAC addresses from 64 to 32k" is
> slightly imprecise. IAVF_NUM_MACADDR_MAX (64) was the total cap including
> the primary MAC; IAVF_UC_MACADDR_MAX (32768) is also a total cap
> including index 0. Either drop "secondary" or say "secondary MAC
> addresses from 63 to 32767".
>
> iavf_add_del_uc_addr_bulk() returns an int but the only caller
> (iavf_add_del_all_mac_addr) discards it. The pre-existing function was
> already void so this is no regression, but having the helper return an
> error code that is unconditionally dropped is misleading. Either
> propagate the error to the caller (and make iavf_add_del_all_mac_addr
> return int) or make the helper void.
>
> eth_dev_mac_restore() now iterates dev_info->max_mac_addrs which for
> iavf becomes 32768. With patch 5 applied this path is skipped via
> get_restore_flags, but any driver that increases max_mac_addrs into the
> thousands without setting RTE_ETH_RESTORE_MAC_ADDR off will pay a 32k
> rte_is_zero_ether_addr() scan on every dev_start. Not a bug here, but
> worth keeping in mind.
>
> sizeof(struct virtchnl_ether_addr_list) already accounts for the
> embedded list[1] slot, so
> in_args_size = sizeof(struct virtchnl_ether_addr_list) +
> sizeof(struct virtchnl_ether_addr) * list->num_elements
> overcounts by sizeof(struct virtchnl_ether_addr). This matches what
> iavf_add_del_eth_addr() already does, and the buffer is sized to hold
> it, so it's not a bug -- noting it for completeness.
Those points do reflect the pre-existing implementations, but that's
it, I won't fix all bugs in the world... for now.
> Patch 5 - net/iavf: fix duplicate MAC addresses install
> Info
> Recovery edge case: if iavf_add_del_eth_addr() for the primary fails
> during the first iavf_dev_start(), mac_primary_set stays false. On a
> subsequent VF reset, iavf_dev_start() (called from iavf_handle_hw_reset)
> will re-attempt the primary add, and the new
> iavf_add_del_all_mac_addr() call right after will add the primary again
> via VIRTCHNL_ETHER_ADDR_PRIMARY. This re-introduces a single-MAC
> double-install in a narrow failure path. Could be avoided by skipping
> the primary in iavf_add_del_all_mac_addr() when mac_primary_set is
> already true, or by having iavf_dev_start() skip the primary add when
> in_reset_recovery is set.
>
> No release notes entry. With Fixes: + Cc: stable this is acceptable as
> a bug fix, but the patch also introduces a new dev_op
> (get_restore_flags) for the driver and changes when MC addresses are
> re-pushed (only on VF reset, not on every dev_start). A one-line note
> in the iavf section of the release notes would help users tracking
> behaviour changes between stop/start cycles.
Mac addresses are installed only once and restored on reset, that's all we need.
IOW, this patch should have no visible impact on an application, and
nothing to write about in the RN.
--
David Marchand
^ permalink raw reply
* Re: [PATCH v5 04/27] net/intel/common: add common flow attr validation
From: Bruce Richardson @ 2026-05-27 13:28 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev
In-Reply-To: <d75e9a02b40ccfe8fd2e00977ee99e9be95ca9ad.1779717944.git.anatoly.burakov@intel.com>
On Mon, May 25, 2026 at 03:06:23PM +0100, Anatoly Burakov wrote:
> There are a lot of commonalities between what kinds of flow attr each Intel
> driver supports. Add a helper function that will validate attr based on
> common requirements and (optional) parameter checks.
>
> Things we check for:
> - Rejecting NULL attr (obviously)
> - Default to ingress flows
> - Transfer, group, priority, and egress are not allowed unless requested
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
> drivers/net/intel/common/flow_check.h | 69 +++++++++++++++++++++++++++
> 1 file changed, 69 insertions(+)
>
> diff --git a/drivers/net/intel/common/flow_check.h b/drivers/net/intel/common/flow_check.h
> index 74fb28ae3d..0572028664 100644
> --- a/drivers/net/intel/common/flow_check.h
> +++ b/drivers/net/intel/common/flow_check.h
> @@ -54,6 +54,7 @@ ci_flow_action_type_in_list(const enum rte_flow_action_type type,
> /* Forward declarations */
> struct ci_flow_actions;
> struct ci_flow_actions_check_param;
> +struct ci_flow_attr_check_param;
>
> static inline const char *
> ci_flow_action_type_to_str(enum rte_flow_action_type type)
> @@ -271,6 +272,74 @@ ci_flow_check_actions(const struct rte_flow_action *actions,
> return parsed_actions->count == 0 ? -EINVAL : 0;
> }
>
> +/**
> + * Parameter structure for attr check.
> + */
> +struct ci_flow_attr_check_param {
> + bool allow_priority; /**< True if priority attribute is allowed. */
> + bool allow_transfer; /**< True if transfer attribute is allowed. */
> + bool allow_group; /**< True if group attribute is allowed. */
> + bool expect_egress; /**< True if egress attribute is expected. */
> +};
> +
> +/**
> + * Validate rte_flow_attr structure against specified constraints.
> + *
> + * @param attr Pointer to rte_flow_attr structure to validate.
> + * @param attr_param Pointer to ci_flow_attr_check_param structure specifying constraints.
> + * @param error Pointer to rte_flow_error structure for error reporting.
> + *
> + * @return 0 on success, negative errno on failure.
> + */
> +static inline int
> +ci_flow_check_attr(const struct rte_flow_attr *attr,
> + const struct ci_flow_attr_check_param *attr_param,
> + struct rte_flow_error *error)
> +{
> + if (attr == NULL) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR, attr,
> + "NULL attribute");
> + }
> +
> + /* Direction must be either ingress or egress */
> + if (attr->ingress == attr->egress) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR, attr,
> + "Either ingress or egress must be set");
> + }
> +
> + /* Expect ingress by default */
> + if (attr->egress && (attr_param == NULL || !attr_param->expect_egress)) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr,
> + "Egress not supported");
> + }
I think "allow_egress" is possibly a better name here. "expect_egress"
implies that egress must be present, but the logic here seems to be only
allowing egress if the flag is provided.
> +
> + /* May not be supported */
> + if (attr->transfer && (attr_param == NULL || !attr_param->allow_transfer)) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr,
> + "Transfer not supported");
> + }
> +
> + /* May not be supported */
> + if (attr->group && (attr_param == NULL || !attr_param->allow_group)) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr,
> + "Group not supported");
> + }
> +
> + /* May not be supported */
> + if (attr->priority && (attr_param == NULL || !attr_param->allow_priority)) {
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, attr,
> + "Priority not supported");
> + }
> +
> + return 0;
> +}
> +
> #ifdef __cplusplus
> }
> #endif
> --
> 2.47.3
>
^ permalink raw reply
* Re: [RFC 2/3] lib: add fastmem library
From: Stephen Hemminger @ 2026-05-27 14:22 UTC (permalink / raw)
To: Mattias Rönnblom
Cc: dev, Morten Brørup, Konstantin Ananyev,
Mattias Rönnblom, Yogaraj Baskaravel
In-Reply-To: <20260525103642.55255-3-hofors@lysator.liu.se>
On Mon, 25 May 2026 12:36:41 +0200
Mattias Rönnblom <hofors@lysator.liu.se> wrote:
> +
> +static __rte_always_inline struct fastmem_cache *
> +cache_get(struct fastmem_socket_state *socket, unsigned int class_idx,
> + unsigned int lcore_id)
Do not use always_inline. With current compilers using always inline
makes the optimizer generate worse code. The only exceptions would
be where inline is required to make assembly work or you have good benchmark
data that proves that always_inline generates > 1% performance gain.
To much of DPDK use __rte_always_inline as "cargo cult" it is faster setting.
^ permalink raw reply
* Re: [PATCH v5 00/27] Add common flow attr/action parsing infrastructure to Intel PMD's
From: Bruce Richardson @ 2026-05-27 14:40 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev
In-Reply-To: <cover.1779717943.git.anatoly.burakov@intel.com>
On Mon, May 25, 2026 at 03:06:19PM +0100, Anatoly Burakov wrote:
> This patchset introduces common flow attr/action checking infrastructure to
> some Intel PMD's (IXGBE, I40E, IAVF, and ICE). The aim is to reduce code
> duplication, simplify implementation of new parsers/verification of existing
> ones, and make action/attr handling more consistent across drivers.
>
> v5:
> - Add missing patch for component/class name compile time constant
> - Fixed missing RSS queue contiguousness checks
>
> v4:
> - First few commits were integrated as part of a different patchset
> - Added more logging to common infrastructure
> - RSS validation now allows discontiguous queue lists by default
> - Fixed some checks being too stringent and failing common validation
>
> v3:
> - Rebase on latest next-net-intel
> - Added 4 new commits that have to do with not using `rte_eth_dev` in rte_flow
> - Converted the remaining commits to use adapter structures everywhere
> - Minor fixes in how return values are handled
> - Fixed incorrect check in i40e RSS validation
>
> v2:
> - Rebase on latest main
> - Now depends on series 37585 [1]
>
> [1] https://patches.dpdk.org/project/dpdk/list/?series=37585
>
While I haven't worked through the details patch-by-patch, the whole
concept seems good, and the implementation parts I have looked at seem
fine. Any new versions should be applicable ok to main, since the net and
net-intel trees have now been pulled, which means we'll get a good AI
review too. For now, LGTM
Series-Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> Anatoly Burakov (21):
> eal/common: add token concatenation macro
> net/intel/common: add common flow action parsing
> net/intel/common: add common flow attr validation
> net/ixgbe: use common checks in ethertype filter
> net/ixgbe: use common checks in syn filter
> net/ixgbe: use common checks in L2 tunnel filter
> net/ixgbe: use common checks in ntuple filter
> net/ixgbe: use common checks in security filter
> net/ixgbe: use common checks in FDIR filters
> net/ixgbe: use common checks in RSS filter
> net/i40e: use common flow attribute checks
> net/i40e: refactor RSS flow parameter checks
> net/i40e: use common action checks for ethertype
> net/i40e: use common action checks for FDIR
> net/i40e: use common action checks for tunnel
> net/iavf: use common flow attribute checks
> net/iavf: use common action checks for IPsec
> net/iavf: use common action checks for hash
> net/iavf: use common action checks for FDIR
> net/iavf: use common action checks for fsub
> net/iavf: use common action checks for flow query
>
> Bruce Richardson (1):
> build: add build defines for component name and class
>
> Vladimir Medvedkin (5):
> net/ice: use common flow attribute checks
> net/ice: use common action checks for hash
> net/ice: use common action checks for FDIR
> net/ice: use common action checks for switch
> net/ice: use common action checks for ACL
>
> drivers/meson.build | 2 +
> drivers/net/intel/common/flow_check.h | 347 ++++++
> drivers/net/intel/common/log.h | 40 +
> drivers/net/intel/i40e/i40e_ethdev.h | 1 -
> drivers/net/intel/i40e/i40e_flow.c | 433 +++-----
> drivers/net/intel/i40e/i40e_hash.c | 438 +++++---
> drivers/net/intel/i40e/i40e_hash.h | 2 +-
> drivers/net/intel/iavf/iavf_fdir.c | 368 +++---
> drivers/net/intel/iavf/iavf_fsub.c | 262 ++---
> drivers/net/intel/iavf/iavf_generic_flow.c | 107 +-
> drivers/net/intel/iavf/iavf_generic_flow.h | 2 +-
> drivers/net/intel/iavf/iavf_hash.c | 153 +--
> drivers/net/intel/iavf/iavf_ipsec_crypto.c | 43 +-
> drivers/net/intel/ice/ice_acl_filter.c | 146 ++-
> drivers/net/intel/ice/ice_fdir_filter.c | 384 ++++---
> drivers/net/intel/ice/ice_generic_flow.c | 59 +-
> drivers/net/intel/ice/ice_generic_flow.h | 2 +-
> drivers/net/intel/ice/ice_hash.c | 189 ++--
> drivers/net/intel/ice/ice_switch_filter.c | 389 +++----
> drivers/net/intel/ixgbe/ixgbe_flow.c | 1166 +++++++-------------
> lib/eal/include/rte_common.h | 4 +
> lib/meson.build | 2 +
> 22 files changed, 2271 insertions(+), 2268 deletions(-)
> create mode 100644 drivers/net/intel/common/flow_check.h
> create mode 100644 drivers/net/intel/common/log.h
>
> --
> 2.47.3
>
^ permalink raw reply
* [PATCH] ethdev: promote experimental API's to stable
From: Stephen Hemminger @ 2026-05-27 14:44 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon, Andrew Rybchenko
Several API's in ethdev have been marked as experimental
(some as old as 19.11). There is no firm policy but any API
that has been experimental for since the last LTS is good candidate
to be stable.
APIs added in 25.11 or later are left as experimental for
another release cycle.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/guides/rel_notes/release_26_07.rst | 55 ++++++
lib/ethdev/rte_ethdev.c | 88 +++++-----
lib/ethdev/rte_ethdev.h | 233 -------------------------
lib/ethdev/rte_ethdev_cman.c | 8 +-
4 files changed, 103 insertions(+), 281 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 1eac84895b..d1b1c0abc5 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -111,6 +111,61 @@ API Changes
Also, make sure to start the actual text at the margin.
=======================================================
+* **ethdev: promoted several APIs from experimental to stable.**
+
+ The following ethdev APIs are no longer marked experimental:
+
+ * ``rte_eth_buffer_split_get_supported_hdr_ptypes``
+ * ``rte_eth_cman_config_get``
+ * ``rte_eth_cman_config_init``
+ * ``rte_eth_cman_config_set``
+ * ``rte_eth_cman_info_get``
+ * ``rte_eth_dev_capability_name``
+ * ``rte_eth_dev_conf_get``
+ * ``rte_eth_dev_count_aggr_ports``
+ * ``rte_eth_dev_get_module_eeprom``
+ * ``rte_eth_dev_get_module_info``
+ * ``rte_eth_dev_get_reg_info_ext``
+ * ``rte_eth_dev_hairpin_capability_get``
+ * ``rte_eth_dev_map_aggr_tx_affinity``
+ * ``rte_eth_dev_priority_flow_ctrl_queue_configure``
+ * ``rte_eth_dev_priority_flow_ctrl_queue_info_get``
+ * ``rte_eth_dev_priv_dump``
+ * ``rte_eth_dev_rss_algo_name``
+ * ``rte_eth_fec_get``
+ * ``rte_eth_fec_get_capability``
+ * ``rte_eth_fec_set``
+ * ``rte_eth_find_rss_algo``
+ * ``rte_eth_get_monitor_addr``
+ * ``rte_eth_hairpin_bind``
+ * ``rte_eth_hairpin_get_peer_ports``
+ * ``rte_eth_hairpin_unbind``
+ * ``rte_eth_ip_reassembly_capability_get``
+ * ``rte_eth_ip_reassembly_conf_get``
+ * ``rte_eth_ip_reassembly_conf_set``
+ * ``rte_eth_link_speed_to_str``
+ * ``rte_eth_link_to_str``
+ * ``rte_eth_macaddrs_get``
+ * ``rte_eth_read_clock``
+ * ``rte_eth_recycle_mbufs``
+ * ``rte_eth_recycle_rx_queue_info_get``
+ * ``rte_eth_representor_info_get``
+ * ``rte_eth_rx_avail_thresh_query``
+ * ``rte_eth_rx_avail_thresh_set``
+ * ``rte_eth_rx_descriptor_dump``
+ * ``rte_eth_rx_hairpin_queue_setup``
+ * ``rte_eth_rx_queue_is_valid``
+ * ``rte_eth_speed_lanes_get``
+ * ``rte_eth_speed_lanes_get_capability``
+ * ``rte_eth_speed_lanes_set``
+ * ``rte_eth_timesync_adjust_freq``
+ * ``rte_eth_tx_descriptor_dump``
+ * ``rte_eth_tx_hairpin_queue_setup``
+ * ``rte_eth_tx_queue_count``
+ * ``rte_eth_tx_queue_is_valid``
+ * ``rte_eth_xstats_query_state``
+ * ``rte_eth_xstats_set_counter``
+
ABI Changes
-----------
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 2edc7a362e..9ba84a6e5e 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -839,7 +839,7 @@ eth_dev_validate_tx_queue(const struct rte_eth_dev *dev, uint16_t tx_queue_id)
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_rx_queue_is_valid, 23.07)
+RTE_EXPORT_SYMBOL(rte_eth_rx_queue_is_valid)
int
rte_eth_rx_queue_is_valid(uint16_t port_id, uint16_t queue_id)
{
@@ -851,7 +851,7 @@ rte_eth_rx_queue_is_valid(uint16_t port_id, uint16_t queue_id)
return eth_dev_validate_rx_queue(dev, queue_id);
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_tx_queue_is_valid, 23.07)
+RTE_EXPORT_SYMBOL(rte_eth_tx_queue_is_valid)
int
rte_eth_tx_queue_is_valid(uint16_t port_id, uint16_t queue_id)
{
@@ -1171,7 +1171,7 @@ eth_dev_offload_names(uint64_t bitmask, char *buf, size_t size,
return buf;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_capability_name, 21.11)
+RTE_EXPORT_SYMBOL(rte_eth_dev_capability_name)
const char *
rte_eth_dev_capability_name(uint64_t capability)
{
@@ -1929,7 +1929,7 @@ rte_eth_dev_set_link_down(uint16_t port_id)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_speed_lanes_get, 24.11)
+RTE_EXPORT_SYMBOL(rte_eth_speed_lanes_get)
int
rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lane)
{
@@ -1943,7 +1943,7 @@ rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lane)
return eth_err(port_id, dev->dev_ops->speed_lanes_get(dev, lane));
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_speed_lanes_get_capability, 24.11)
+RTE_EXPORT_SYMBOL(rte_eth_speed_lanes_get_capability)
int
rte_eth_speed_lanes_get_capability(uint16_t port_id,
struct rte_eth_speed_lanes_capa *speed_lanes_capa,
@@ -1970,7 +1970,7 @@ rte_eth_speed_lanes_get_capability(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_speed_lanes_set, 24.11)
+RTE_EXPORT_SYMBOL(rte_eth_speed_lanes_set)
int
rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes_capa)
{
@@ -2498,7 +2498,7 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
return eth_err(port_id, ret);
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_rx_hairpin_queue_setup, 19.11)
+RTE_EXPORT_SYMBOL(rte_eth_rx_hairpin_queue_setup)
int
rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
uint16_t nb_rx_desc,
@@ -2716,7 +2716,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
tx_queue_id, nb_tx_desc, socket_id, &local_conf));
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_tx_hairpin_queue_setup, 19.11)
+RTE_EXPORT_SYMBOL(rte_eth_tx_hairpin_queue_setup)
int
rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
uint16_t nb_tx_desc,
@@ -2816,7 +2816,7 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_hairpin_bind, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_hairpin_bind)
int
rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
{
@@ -2844,7 +2844,7 @@ rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_hairpin_unbind, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_hairpin_unbind)
int
rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
{
@@ -2872,7 +2872,7 @@ rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_hairpin_get_peer_ports, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_hairpin_get_peer_ports)
int
rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
size_t len, uint32_t direction)
@@ -3200,7 +3200,7 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_link_speed_to_str, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_link_speed_to_str)
const char *
rte_eth_link_speed_to_str(uint32_t link_speed)
{
@@ -3267,7 +3267,7 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_link_to_str, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_link_to_str)
int
rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
{
@@ -3946,7 +3946,7 @@ rte_eth_xstats_reset(uint16_t port_id)
return rte_eth_stats_reset(port_id);
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_xstats_set_counter, 25.03)
+RTE_EXPORT_SYMBOL(rte_eth_xstats_set_counter)
int
rte_eth_xstats_set_counter(uint16_t port_id, uint64_t id, int on_off)
{
@@ -3976,7 +3976,7 @@ rte_eth_xstats_set_counter(uint16_t port_id, uint64_t id, int on_off)
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_xstats_query_state, 25.03)
+RTE_EXPORT_SYMBOL(rte_eth_xstats_query_state)
int
rte_eth_xstats_query_state(uint16_t port_id, uint64_t id)
{
@@ -4145,7 +4145,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_conf_get, 21.11)
+RTE_EXPORT_SYMBOL(rte_eth_dev_conf_get)
int
rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf)
{
@@ -4306,7 +4306,7 @@ rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_macaddrs_get, 21.11)
+RTE_EXPORT_SYMBOL(rte_eth_macaddrs_get)
int
rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma,
unsigned int num)
@@ -4805,7 +4805,7 @@ validate_tx_pause_config(struct rte_eth_dev_info *dev_info, uint8_t tc_max,
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_priority_flow_ctrl_queue_info_get, 22.03)
+RTE_EXPORT_SYMBOL(rte_eth_dev_priority_flow_ctrl_queue_info_get)
int
rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id,
struct rte_eth_pfc_queue_info *pfc_queue_info)
@@ -4833,7 +4833,7 @@ rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_priority_flow_ctrl_queue_configure, 22.03)
+RTE_EXPORT_SYMBOL(rte_eth_dev_priority_flow_ctrl_queue_configure)
int
rte_eth_dev_priority_flow_ctrl_queue_configure(uint16_t port_id,
struct rte_eth_pfc_queue_conf *pfc_queue_conf)
@@ -5147,7 +5147,7 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_rss_algo_name, 23.11)
+RTE_EXPORT_SYMBOL(rte_eth_dev_rss_algo_name)
const char *
rte_eth_dev_rss_algo_name(enum rte_eth_hash_function rss_algo)
{
@@ -5162,7 +5162,7 @@ rte_eth_dev_rss_algo_name(enum rte_eth_hash_function rss_algo)
return name;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_find_rss_algo, 24.03)
+RTE_EXPORT_SYMBOL(rte_eth_find_rss_algo)
int
rte_eth_find_rss_algo(const char *name, uint32_t *algo)
{
@@ -5280,7 +5280,7 @@ rte_eth_led_off(uint16_t port_id)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_fec_get_capability, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_fec_get_capability)
int
rte_eth_fec_get_capability(uint16_t port_id,
struct rte_eth_fec_capa *speed_fec_capa,
@@ -5308,7 +5308,7 @@ rte_eth_fec_get_capability(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_fec_get, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_fec_get)
int
rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
{
@@ -5334,7 +5334,7 @@ rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_fec_set, 20.11)
+RTE_EXPORT_SYMBOL(rte_eth_fec_set)
int
rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa)
{
@@ -5694,7 +5694,7 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_rx_avail_thresh_set, 22.07)
+RTE_EXPORT_SYMBOL(rte_eth_rx_avail_thresh_set)
int rte_eth_rx_avail_thresh_set(uint16_t port_id, uint16_t queue_id,
uint8_t avail_thresh)
{
@@ -5727,7 +5727,7 @@ int rte_eth_rx_avail_thresh_set(uint16_t port_id, uint16_t queue_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_rx_avail_thresh_query, 22.07)
+RTE_EXPORT_SYMBOL(rte_eth_rx_avail_thresh_query)
int rte_eth_rx_avail_thresh_query(uint16_t port_id, uint16_t *queue_id,
uint8_t *avail_thresh)
{
@@ -6413,7 +6413,7 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_recycle_rx_queue_info_get, 23.11)
+RTE_EXPORT_SYMBOL(rte_eth_recycle_rx_queue_info_get)
int
rte_eth_recycle_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
struct rte_eth_recycle_rxq_info *recycle_rxq_info)
@@ -6504,7 +6504,7 @@ rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_get_monitor_addr, 21.02)
+RTE_EXPORT_SYMBOL(rte_eth_get_monitor_addr)
int
rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
struct rte_power_monitor_cond *pmc)
@@ -6675,7 +6675,7 @@ rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_timesync_adjust_freq, 24.11)
+RTE_EXPORT_SYMBOL(rte_eth_timesync_adjust_freq)
int
rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm)
{
@@ -6746,7 +6746,7 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_read_clock, 19.08)
+RTE_EXPORT_SYMBOL(rte_eth_read_clock)
int
rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
{
@@ -6802,7 +6802,7 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_get_reg_info_ext, 24.11)
+RTE_EXPORT_SYMBOL(rte_eth_dev_get_reg_info_ext)
int
rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
{
@@ -6909,7 +6909,7 @@ rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_get_module_info, 18.05)
+RTE_EXPORT_SYMBOL(rte_eth_dev_get_module_info)
int
rte_eth_dev_get_module_info(uint16_t port_id,
struct rte_eth_dev_module_info *modinfo)
@@ -6936,7 +6936,7 @@ rte_eth_dev_get_module_info(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_get_module_eeprom, 18.05)
+RTE_EXPORT_SYMBOL(rte_eth_dev_get_module_eeprom)
int
rte_eth_dev_get_module_eeprom(uint16_t port_id,
struct rte_dev_eeprom_info *info)
@@ -7051,7 +7051,7 @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_hairpin_capability_get, 19.11)
+RTE_EXPORT_SYMBOL(rte_eth_dev_hairpin_capability_get)
int
rte_eth_dev_hairpin_capability_get(uint16_t port_id,
struct rte_eth_hairpin_cap *cap)
@@ -7106,7 +7106,7 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_representor_info_get, 21.05)
+RTE_EXPORT_SYMBOL(rte_eth_representor_info_get)
int
rte_eth_representor_info_get(uint16_t port_id,
struct rte_eth_representor_info *info)
@@ -7162,7 +7162,7 @@ rte_eth_rx_metadata_negotiate(uint16_t port_id, uint64_t *features)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_ip_reassembly_capability_get, 22.03)
+RTE_EXPORT_SYMBOL(rte_eth_ip_reassembly_capability_get)
int
rte_eth_ip_reassembly_capability_get(uint16_t port_id,
struct rte_eth_ip_reassembly_params *reassembly_capa)
@@ -7198,7 +7198,7 @@ rte_eth_ip_reassembly_capability_get(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_ip_reassembly_conf_get, 22.03)
+RTE_EXPORT_SYMBOL(rte_eth_ip_reassembly_conf_get)
int
rte_eth_ip_reassembly_conf_get(uint16_t port_id,
struct rte_eth_ip_reassembly_params *conf)
@@ -7232,7 +7232,7 @@ rte_eth_ip_reassembly_conf_get(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_ip_reassembly_conf_set, 22.03)
+RTE_EXPORT_SYMBOL(rte_eth_ip_reassembly_conf_set)
int
rte_eth_ip_reassembly_conf_set(uint16_t port_id,
const struct rte_eth_ip_reassembly_params *conf)
@@ -7273,7 +7273,7 @@ rte_eth_ip_reassembly_conf_set(uint16_t port_id,
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_priv_dump, 22.03)
+RTE_EXPORT_SYMBOL(rte_eth_dev_priv_dump)
int
rte_eth_dev_priv_dump(uint16_t port_id, FILE *file)
{
@@ -7292,7 +7292,7 @@ rte_eth_dev_priv_dump(uint16_t port_id, FILE *file)
return eth_err(port_id, dev->dev_ops->eth_dev_priv_dump(dev, file));
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_rx_descriptor_dump, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_rx_descriptor_dump)
int
rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
uint16_t offset, uint16_t num, FILE *file)
@@ -7319,7 +7319,7 @@ rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
dev->dev_ops->eth_rx_descriptor_dump(dev, queue_id, offset, num, file));
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_tx_descriptor_dump, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_tx_descriptor_dump)
int
rte_eth_tx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
uint16_t offset, uint16_t num, FILE *file)
@@ -7346,7 +7346,7 @@ rte_eth_tx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
dev->dev_ops->eth_tx_descriptor_dump(dev, queue_id, offset, num, file));
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_buffer_split_get_supported_hdr_ptypes, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_buffer_split_get_supported_hdr_ptypes)
int
rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num)
{
@@ -7386,7 +7386,7 @@ rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes
return j;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_count_aggr_ports, 23.03)
+RTE_EXPORT_SYMBOL(rte_eth_dev_count_aggr_ports)
int rte_eth_dev_count_aggr_ports(uint16_t port_id)
{
struct rte_eth_dev *dev;
@@ -7404,7 +7404,7 @@ int rte_eth_dev_count_aggr_ports(uint16_t port_id)
return ret;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_map_aggr_tx_affinity, 23.03)
+RTE_EXPORT_SYMBOL(rte_eth_dev_map_aggr_tx_affinity)
int rte_eth_dev_map_aggr_tx_affinity(uint16_t port_id, uint16_t tx_queue_id,
uint8_t affinity)
{
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 0d8e2d0236..0381f8317a 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -1061,9 +1061,6 @@ struct rte_eth_txmode {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change without prior notice.
- *
* A structure used to configure an Rx packet segment to split.
*
* If RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT flag is set in offloads field,
@@ -1139,9 +1136,6 @@ struct rte_eth_rxseg_split {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change without prior notice.
- *
* A common structure used to describe Rx packet segment properties.
*/
union rte_eth_rxseg {
@@ -1230,9 +1224,6 @@ struct rte_eth_txconf {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* A structure used to return the Tx or Rx hairpin queue capabilities.
*/
struct rte_eth_hairpin_queue_cap {
@@ -1252,9 +1243,6 @@ struct rte_eth_hairpin_queue_cap {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* A structure used to return the hairpin capabilities that are supported.
*/
struct rte_eth_hairpin_cap {
@@ -1272,9 +1260,6 @@ struct rte_eth_hairpin_cap {
#define RTE_ETH_MAX_HAIRPIN_PEERS 32
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* A structure used to hold hairpin peer data.
*/
struct rte_eth_hairpin_peer {
@@ -1283,9 +1268,6 @@ struct rte_eth_hairpin_peer {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* A structure used to configure hairpin binding.
*/
struct rte_eth_hairpin_conf {
@@ -1426,9 +1408,6 @@ struct rte_eth_pfc_conf {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* A structure used to retrieve information of queue based PFC.
*/
struct rte_eth_pfc_queue_info {
@@ -1441,9 +1420,6 @@ struct rte_eth_pfc_queue_info {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* A structure used to configure Ethernet priority flow control parameters for
* ethdev queues.
*
@@ -1748,9 +1724,6 @@ struct rte_eth_switch_info {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change without prior notice.
- *
* Ethernet device Rx buffer segmentation capabilities.
*/
struct rte_eth_rxseg_capa {
@@ -1777,9 +1750,6 @@ enum rte_eth_representor_type {
};
/**
- * @warning
- * @b EXPERIMENTAL: this enumeration may change without prior notice.
- *
* Ethernet device error handling mode.
*/
enum rte_eth_err_handle_mode {
@@ -1918,9 +1888,6 @@ struct __rte_cache_min_aligned rte_eth_txq_info {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change without prior notice.
- *
* Ethernet device Rx queue information structure for recycling mbufs.
* Used to retrieve Rx queue information when Tx queue reusing mbufs and moving
* them into Rx mbuf ring.
@@ -2384,9 +2351,6 @@ const char *rte_eth_dev_rx_offload_name(uint64_t offload);
const char *rte_eth_dev_tx_offload_name(uint64_t offload);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Get RTE_ETH_DEV_CAPA_* flag name.
*
* @param capability
@@ -2394,7 +2358,6 @@ const char *rte_eth_dev_tx_offload_name(uint64_t offload);
* @return
* Capability name or 'UNKNOWN' if the flag cannot be recognized.
*/
-__rte_experimental
const char *rte_eth_dev_capability_name(uint64_t capability);
/**
@@ -2518,9 +2481,6 @@ int rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
struct rte_mempool *mb_pool);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Allocate and set up a hairpin receive queue for an Ethernet device.
*
* The function set up the selected queue to be used in hairpin.
@@ -2544,7 +2504,6 @@ int rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
* - (-EINVAL) if bad parameter.
* - (-ENOMEM) if unable to allocate the resources.
*/
-__rte_experimental
int rte_eth_rx_hairpin_queue_setup
(uint16_t port_id, uint16_t rx_queue_id, uint16_t nb_rx_desc,
const struct rte_eth_hairpin_conf *conf);
@@ -2602,9 +2561,6 @@ int rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
const struct rte_eth_txconf *tx_conf);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Allocate and set up a transmit hairpin queue for an Ethernet device.
*
* @param port_id
@@ -2626,15 +2582,11 @@ int rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
* - (-EINVAL) if bad parameter.
* - (-ENOMEM) if unable to allocate the resources.
*/
-__rte_experimental
int rte_eth_tx_hairpin_queue_setup
(uint16_t port_id, uint16_t tx_queue_id, uint16_t nb_tx_desc,
const struct rte_eth_hairpin_conf *conf);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Get all the hairpin peer Rx / Tx ports of the current port.
* The caller should ensure that the array is large enough to save the ports
* list.
@@ -2657,14 +2609,10 @@ int rte_eth_tx_hairpin_queue_setup
* - (-ENOTSUP) if hardware doesn't support.
* - Others detailed errors from PMDs.
*/
-__rte_experimental
int rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
size_t len, uint32_t direction);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Bind all hairpin Tx queues of one port to the Rx queues of the peer port.
* It is only allowed to call this function after all hairpin queues are
* configured properly and the devices are in started state.
@@ -2683,13 +2631,9 @@ int rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
* - (-ENOTSUP) if hardware doesn't support.
* - Others detailed errors from PMDs.
*/
-__rte_experimental
int rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Unbind all hairpin Tx queues of one port from the Rx queues of the peer port.
* This should be called before closing the Tx or Rx devices, if the bind
* function is called before.
@@ -2710,13 +2654,9 @@ int rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port);
* - (-ENOTSUP) if hardware doesn't support.
* - Others detailed errors from PMDs.
*/
-__rte_experimental
int rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Get the number of aggregated ports of the DPDK port (specified with port_id).
* It is used when multiple ports are aggregated into a single one.
*
@@ -2728,13 +2668,9 @@ int rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port);
* @return
* - (>=0) the number of aggregated port if success.
*/
-__rte_experimental
int rte_eth_dev_count_aggr_ports(uint16_t port_id);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Map a Tx queue with an aggregated port of the DPDK port (specified with port_id).
* When multiple ports are aggregated into a single one,
* it allows to choose which port to use for Tx via a queue.
@@ -2758,7 +2694,6 @@ int rte_eth_dev_count_aggr_ports(uint16_t port_id);
* @return
* Zero if successful. Non-zero otherwise.
*/
-__rte_experimental
int rte_eth_dev_map_aggr_tx_affinity(uint16_t port_id, uint16_t tx_queue_id,
uint8_t affinity);
@@ -2788,9 +2723,6 @@ int rte_eth_dev_socket_id(uint16_t port_id);
int rte_eth_dev_is_valid_port(uint16_t port_id);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice.
- *
* Check if Rx queue is valid.
* If the queue has been setup, it is considered valid.
*
@@ -2803,13 +2735,9 @@ int rte_eth_dev_is_valid_port(uint16_t port_id);
* - -EINVAL: if queue_id is out of range or queue has not been setup.
* - 0 if Rx queue is valid.
*/
-__rte_experimental
int rte_eth_rx_queue_is_valid(uint16_t port_id, uint16_t queue_id);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice.
- *
* Check if Tx queue is valid.
* If the queue has been setup, it is considered valid.
*
@@ -2822,7 +2750,6 @@ int rte_eth_rx_queue_is_valid(uint16_t port_id, uint16_t queue_id);
* - -EINVAL: if queue_id is out of range or queue has not been setup.
* - 0 if Tx queue is valid.
*/
-__rte_experimental
int rte_eth_tx_queue_is_valid(uint16_t port_id, uint16_t queue_id);
/**
@@ -3129,9 +3056,6 @@ int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link)
__rte_warn_unused_result;
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* The function converts a link_speed to a string. It handles all special
* values like unknown or none speed.
*
@@ -3141,13 +3065,9 @@ int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link)
* Link speed in textual format. It's pointer to immutable memory.
* No free is required.
*/
-__rte_experimental
const char *rte_eth_link_speed_to_str(uint32_t link_speed);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* This function converts an Ethernet link type to a string.
*
* @param link_connector
@@ -3159,9 +3079,6 @@ __rte_experimental
const char *rte_eth_link_connector_to_str(enum rte_eth_link_connector link_connector);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* The function converts a rte_eth_link struct representing a link status to
* a string.
*
@@ -3176,14 +3093,10 @@ const char *rte_eth_link_connector_to_str(enum rte_eth_link_connector link_conne
* @return
* Number of bytes written to str array or -EINVAL if bad parameter.
*/
-__rte_experimental
int rte_eth_link_to_str(char *str, size_t len,
const struct rte_eth_link *eth_link);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Get Active lanes.
*
* @param port_id
@@ -3200,13 +3113,9 @@ int rte_eth_link_to_str(char *str, size_t len,
* - (-EIO) if device is removed.
* - (-ENODEV) if *port_id* invalid.
*/
-__rte_experimental
int rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lanes);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Set speed lanes supported by the NIC.
*
* @param port_id
@@ -3224,13 +3133,9 @@ int rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lanes);
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if *lanes* count not in speeds capability list.
*/
-__rte_experimental
int rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Get speed lanes supported by the NIC.
*
* @param port_id
@@ -3249,7 +3154,6 @@ int rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes);
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if *speed_lanes* invalid
*/
-__rte_experimental
int rte_eth_speed_lanes_get_capability(uint16_t port_id,
struct rte_eth_speed_lanes_capa *speed_lanes_capa,
unsigned int num);
@@ -3447,7 +3351,6 @@ int rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
* - (-EPERM) enabling this counter is not permitted
* - (-ENOSPC) no resources
*/
-__rte_experimental
int rte_eth_xstats_set_counter(uint16_t port_id, uint64_t id, int on_off);
/**
@@ -3461,7 +3364,6 @@ int rte_eth_xstats_set_counter(uint16_t port_id, uint64_t id, int on_off);
* - (-ENOTSUP) enable/disabling is not implemented
* - (-EINVAL) xstat id is invalid
*/
-__rte_experimental
int rte_eth_xstats_query_state(uint16_t port_id, uint64_t id);
/**
@@ -3539,9 +3441,6 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
* Retrieve the Ethernet addresses of an Ethernet device.
*
* @param port_id
@@ -3558,7 +3457,6 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr *ma,
unsigned int num);
@@ -3585,9 +3483,6 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
__rte_warn_unused_result;
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Retrieve the configuration of an Ethernet device.
*
* @param port_id
@@ -3599,7 +3494,6 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_dev_conf_get(uint16_t port_id, struct rte_eth_conf *dev_conf)
__rte_warn_unused_result;
@@ -3848,9 +3742,6 @@ int rte_eth_dev_get_vlan_offload(uint16_t port_id);
int rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Set Rx queue available descriptors threshold.
*
* @param port_id
@@ -3872,14 +3763,10 @@ int rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on);
* - (-ENOTSUP) if available Rx descriptors threshold is not supported.
* - (-EIO) if device is removed.
*/
-__rte_experimental
int rte_eth_rx_avail_thresh_set(uint16_t port_id, uint16_t queue_id,
uint8_t avail_thresh);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Find Rx queue with RTE_ETH_EVENT_RX_AVAIL_THRESH event pending.
*
* @param port_id
@@ -3902,7 +3789,6 @@ int rte_eth_rx_avail_thresh_set(uint16_t port_id, uint16_t queue_id,
* - (-ENOTSUP) if operation is not supported.
* - (-EIO) if device is removed.
*/
-__rte_experimental
int rte_eth_rx_avail_thresh_query(uint16_t port_id, uint16_t *queue_id,
uint8_t *avail_thresh);
@@ -4474,9 +4360,6 @@ int rte_eth_led_on(uint16_t port_id);
int rte_eth_led_off(uint16_t port_id);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Get Forward Error Correction(FEC) capability.
*
* @param port_id
@@ -4501,15 +4384,11 @@ int rte_eth_led_off(uint16_t port_id);
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if *num* or *speed_fec_capa* invalid
*/
-__rte_experimental
int rte_eth_fec_get_capability(uint16_t port_id,
struct rte_eth_fec_capa *speed_fec_capa,
unsigned int num);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Get current Forward Error Correction(FEC) mode.
* If link is down and AUTO is enabled, AUTO is returned, otherwise,
* configured FEC mode is returned.
@@ -4526,13 +4405,9 @@ int rte_eth_fec_get_capability(uint16_t port_id,
* - (-EIO) if device is removed.
* - (-ENODEV) if *port_id* invalid.
*/
-__rte_experimental
int rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Set Forward Error Correction(FEC) mode.
*
* @param port_id
@@ -4552,7 +4427,6 @@ int rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa);
* - (-EIO) if device is removed.
* - (-ENODEV) if *port_id* invalid.
*/
-__rte_experimental
int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
/**
@@ -4629,9 +4503,6 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
uint32_t pool);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Retrieve the information for queue based PFC.
*
* @param port_id
@@ -4645,14 +4516,10 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id,
struct rte_eth_pfc_queue_info *pfc_queue_info);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Configure the queue based priority flow control for a given queue
* for Ethernet device.
*
@@ -4672,7 +4539,6 @@ int rte_eth_dev_priority_flow_ctrl_queue_info_get(uint16_t port_id,
* - (-EINVAL) if bad parameter
* - (-EIO) if flow control setup queue failure
*/
-__rte_experimental
int rte_eth_dev_priority_flow_ctrl_queue_configure(uint16_t port_id,
struct rte_eth_pfc_queue_conf *pfc_queue_conf);
@@ -4854,9 +4720,6 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
struct rte_eth_rss_conf *rss_conf);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice.
- *
* Get the name of RSS hash algorithm.
*
* @param rss_algo
@@ -4865,14 +4728,10 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
* @return
* Hash algorithm name or 'UNKNOWN' if the rss_algo cannot be recognized.
*/
-__rte_experimental
const char *
rte_eth_dev_rss_algo_name(enum rte_eth_hash_function rss_algo);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice.
- *
* Get RSS hash algorithm by its name.
*
* @param name
@@ -4885,7 +4744,6 @@ rte_eth_dev_rss_algo_name(enum rte_eth_hash_function rss_algo);
* - (0) if successful.
* - (-EINVAL) if not found.
*/
-__rte_experimental
int
rte_eth_find_rss_algo(const char *name, uint32_t *algo);
@@ -5164,9 +5022,6 @@ int rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
struct rte_eth_txq_info *qinfo);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Retrieve information about given ports's Rx queue for recycling mbufs.
*
* @param port_id
@@ -5183,7 +5038,6 @@ int rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
* - -ENOTSUP: routine is not supported by the device PMD.
* - -EINVAL: The queue_id is out of range.
*/
-__rte_experimental
int rte_eth_recycle_rx_queue_info_get(uint16_t port_id,
uint16_t queue_id,
struct rte_eth_recycle_rxq_info *recycle_rxq_info);
@@ -5231,9 +5085,6 @@ int rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
struct rte_eth_burst_mode *mode);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Retrieve the monitor condition for a given receive queue.
*
* @param port_id
@@ -5250,7 +5101,6 @@ int rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
* -EINVAL: Invalid parameters.
* -ENODEV: Invalid port ID.
*/
-__rte_experimental
int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
struct rte_power_monitor_cond *pmc);
@@ -5280,7 +5130,6 @@ int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
* - (-EIO) if device is removed.
* - others depends on the specific operations implementation.
*/
-__rte_experimental
int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
/**
@@ -5355,9 +5204,6 @@ int rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info);
int rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Retrieve the type and size of plugin module EEPROM
*
* @param port_id
@@ -5372,15 +5218,11 @@ int rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info);
* - (-EIO) if device is removed.
* - others depends on the specific operations implementation.
*/
-__rte_experimental
int
rte_eth_dev_get_module_info(uint16_t port_id, struct rte_eth_dev_module_info *modinfo)
__rte_warn_unused_result;
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Retrieve the data of plugin module EEPROM
*
* @param port_id
@@ -5396,7 +5238,6 @@ rte_eth_dev_get_module_info(uint16_t port_id, struct rte_eth_dev_module_info *mo
* - (-EIO) if device is removed.
* - others depends on the specific operations implementation.
*/
-__rte_experimental
int
rte_eth_dev_get_module_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
__rte_warn_unused_result;
@@ -5550,7 +5391,6 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
* - -EIO: if device is removed.
* - -ENOTSUP: The function is not supported by the Ethernet driver.
*/
-__rte_experimental
int rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm);
/**
@@ -5591,9 +5431,6 @@ int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice.
- *
* Read the current clock counter of an Ethernet device
*
* This returns the current raw clock value of an Ethernet device. It is
@@ -5635,7 +5472,6 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
* - -ENOTSUP: The function is not supported by the Ethernet driver.
* - -EINVAL: if bad parameter.
*/
-__rte_experimental
int
rte_eth_read_clock(uint16_t port_id, uint64_t *clock);
@@ -5726,9 +5562,6 @@ void *
rte_eth_dev_get_sec_ctx(uint16_t port_id);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Query the device hairpin capabilities.
*
* @param port_id
@@ -5740,14 +5573,10 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
* - (-ENOTSUP) if hardware doesn't support.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
struct rte_eth_hairpin_cap *cap);
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change without prior notice.
- *
* Ethernet device representor ID range entry
*/
struct rte_eth_representor_range {
@@ -5765,9 +5594,6 @@ struct rte_eth_representor_range {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change without prior notice.
- *
* Ethernet device representor information
*/
struct rte_eth_representor_info {
@@ -5801,7 +5627,6 @@ struct rte_eth_representor_info {
* - (-EIO) if device is removed.
* - (>=0) number of available representor range entries.
*/
-__rte_experimental
int rte_eth_representor_info_get(uint16_t port_id,
struct rte_eth_representor_info *info);
@@ -5881,9 +5706,6 @@ struct rte_eth_ip_reassembly_params {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
* Get IP reassembly capabilities supported by the PMD. This is the first API
* to be called for enabling the IP reassembly offload feature. PMD will return
* the maximum values of parameters that PMD can support and user can call
@@ -5900,14 +5722,10 @@ struct rte_eth_ip_reassembly_params {
* - (-EINVAL) if device is not configured or *capa* passed is NULL.
* - (0) on success.
*/
-__rte_experimental
int rte_eth_ip_reassembly_capability_get(uint16_t port_id,
struct rte_eth_ip_reassembly_params *capa);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
* Get IP reassembly configuration parameters currently set in PMD.
* The API will return error if the configuration is not already
* set using rte_eth_ip_reassembly_conf_set() before calling this API or if
@@ -5925,14 +5743,10 @@ int rte_eth_ip_reassembly_capability_get(uint16_t port_id,
* configuration is not set using rte_eth_ip_reassembly_conf_set().
* - (0) on success.
*/
-__rte_experimental
int rte_eth_ip_reassembly_conf_get(uint16_t port_id,
struct rte_eth_ip_reassembly_params *conf);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
* Set IP reassembly configuration parameters if the PMD supports IP reassembly
* offload. User should first call rte_eth_ip_reassembly_capability_get() to
* check the maximum values supported by the PMD before setting the
@@ -5958,7 +5772,6 @@ int rte_eth_ip_reassembly_conf_get(uint16_t port_id,
* successfully by the PMD.
* - (0) on success.
*/
-__rte_experimental
int rte_eth_ip_reassembly_conf_set(uint16_t port_id,
const struct rte_eth_ip_reassembly_params *conf);
@@ -5982,9 +5795,6 @@ typedef struct {
} rte_eth_ip_reassembly_dynfield_t;
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Dump private info from device to a file. Provided data and the order depends
* on the PMD.
*
@@ -5999,13 +5809,9 @@ typedef struct {
* - (-ENOTSUP) if the device does not support this function.
* - (-EIO) if device is removed.
*/
-__rte_experimental
int rte_eth_dev_priv_dump(uint16_t port_id, FILE *file);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Dump ethdev Rx descriptor info to a file.
*
* This API is used for debugging, not a dataplane API.
@@ -6025,14 +5831,10 @@ int rte_eth_dev_priv_dump(uint16_t port_id, FILE *file);
* - On success, zero.
* - On failure, a negative value.
*/
-__rte_experimental
int rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
uint16_t offset, uint16_t num, FILE *file);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Dump ethdev Tx descriptor info to a file.
*
* This API is used for debugging, not a dataplane API.
@@ -6052,7 +5854,6 @@ int rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
* - On success, zero.
* - On failure, a negative value.
*/
-__rte_experimental
int rte_eth_tx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
uint16_t offset, uint16_t num, FILE *file);
@@ -6071,9 +5872,6 @@ enum rte_eth_cman_obj {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change, or be removed, without prior notice
- *
* A structure used to retrieve information of ethdev congestion management.
*/
struct rte_eth_cman_info {
@@ -6095,9 +5893,6 @@ struct rte_eth_cman_info {
};
/**
- * @warning
- * @b EXPERIMENTAL: this structure may change, or be removed, without prior notice
- *
* A structure used to configure the ethdev congestion management.
*/
struct rte_eth_cman_config {
@@ -6139,9 +5934,6 @@ struct rte_eth_cman_config {
};
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Retrieve the information for ethdev congestion management
*
* @param port_id
@@ -6155,13 +5947,9 @@ struct rte_eth_cman_config {
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_cman_info_get(uint16_t port_id, struct rte_eth_cman_info *info);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Initialize the ethdev congestion management configuration structure with default values.
*
* @param port_id
@@ -6175,13 +5963,9 @@ int rte_eth_cman_info_get(uint16_t port_id, struct rte_eth_cman_info *info);
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *config);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Configure ethdev congestion management
*
* @param port_id
@@ -6194,13 +5978,9 @@ int rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *confi
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *config);
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Retrieve the applied ethdev congestion management parameters for the given port.
*
* @param port_id
@@ -6217,7 +5997,6 @@ int rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_cman_config_get(uint16_t port_id, struct rte_eth_cman_config *config);
#ifdef __cplusplus
@@ -6949,9 +6728,6 @@ rte_eth_tx_buffer(uint16_t port_id, uint16_t queue_id,
}
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
* Recycle used mbufs from a transmit queue of an Ethernet device, and move
* these mbufs into a mbuf ring for a receive queue of an Ethernet device.
* This can bypass mempool path to save CPU cycles.
@@ -7001,7 +6777,6 @@ rte_eth_tx_buffer(uint16_t port_id, uint16_t queue_id,
* @return
* The number of recycling mbufs.
*/
-__rte_experimental
static inline uint16_t
rte_eth_recycle_mbufs(uint16_t rx_port_id, uint16_t rx_queue_id,
uint16_t tx_port_id, uint16_t tx_queue_id,
@@ -7076,9 +6851,6 @@ rte_eth_recycle_mbufs(uint16_t rx_port_id, uint16_t rx_queue_id,
}
/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
* Get supported header protocols to split on Rx.
*
* When a packet type is announced to be split,
@@ -7103,14 +6875,10 @@ rte_eth_recycle_mbufs(uint16_t rx_port_id, uint16_t rx_queue_id,
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
-__rte_experimental
int rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num)
__rte_warn_unused_result;
/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice.
- *
* Get the number of used descriptors of a Tx queue.
*
* This function retrieves the number of used descriptors of a transmit queue.
@@ -7141,7 +6909,6 @@ int rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *pt
* If the use case only involves checking the status of a specific descriptor slot,
* opt for rte_eth_tx_descriptor_status() instead.
*/
-__rte_experimental
static inline int
rte_eth_tx_queue_count(uint16_t port_id, uint16_t queue_id)
{
diff --git a/lib/ethdev/rte_ethdev_cman.c b/lib/ethdev/rte_ethdev_cman.c
index a8460e6977..3a62432bf0 100644
--- a/lib/ethdev/rte_ethdev_cman.c
+++ b/lib/ethdev/rte_ethdev_cman.c
@@ -12,7 +12,7 @@
#include "ethdev_trace.h"
/* Get congestion management information for a port */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_cman_info_get, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_cman_info_get)
int
rte_eth_cman_info_get(uint16_t port_id, struct rte_eth_cman_info *info)
{
@@ -41,7 +41,7 @@ rte_eth_cman_info_get(uint16_t port_id, struct rte_eth_cman_info *info)
}
/* Initialize congestion management structure with default values */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_cman_config_init, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_cman_config_init)
int
rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *config)
{
@@ -70,7 +70,7 @@ rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *config)
}
/* Configure congestion management on a port */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_cman_config_set, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_cman_config_set)
int
rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *config)
{
@@ -98,7 +98,7 @@ rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *conf
}
/* Retrieve congestion management configuration of a port */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_cman_config_get, 22.11)
+RTE_EXPORT_SYMBOL(rte_eth_cman_config_get)
int
rte_eth_cman_config_get(uint16_t port_id, struct rte_eth_cman_config *config)
{
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v5 00/21] Wangxun Fixes
From: Stephen Hemminger @ 2026-05-27 15:22 UTC (permalink / raw)
To: Zaiyu Wang; +Cc: dev
In-Reply-To: <20260527130222.24348-1-zaiyuwang@trustnetic.com>
On Wed, 27 May 2026 21:02:00 +0800
Zaiyu Wang <zaiyuwang@trustnetic.com> wrote:
> This series fixes several issues found on Wangxun Emerald, Sapphire and
> Amber-lite NICs, with a focus on link-related problems.
> ---
> v5:
> - Fixed issues identified by AI review
> ---
> v4:
> - Fixed issues identified by devtools scripts
> ---
> v3:
> - Addressed Stephen's comments
> ---
> v2:
> - Fixed compilation error and code style issues
> ---
>
> Zaiyu Wang (21):
> net/txgbe: remove duplicate xstats counters
> net/ngbe: remove duplicate xstats counters
> net/ngbe: add missing CDR config for YT PHY
> net/ngbe: fix VF promiscuous and allmulticast
> net/txgbe: fix inaccuracy in Tx rate limiting
> net/txgbe: fix link status check condition
> net/txgbe: fix Tx desc free logic
> net/txgbe: fix link flow control registers for Amber-Lite
> net/txgbe: fix link flow control config for Sapphire
> net/txgbe: fix a mass of unknown interrupts
> net/txgbe: fix traffic class priority configuration
> net/txgbe: fix link stability for 25G NIC
> net/txgbe: fix link stability for 40G NIC
> net/txgbe: fix link stability for Amber-Lite backplane mode
> net/txgbe: fix FEC mode configuration on 25G NIC
> net/txgbe: fix SFP module identification
> net/txgbe: fix get module info operation
> net/txgbe: fix get EEPROM operation
> net/txgbe: fix to reset Tx write-back pointer
> net/txgbe: fix to enable Tx desc check
> net/txgbe: fix temperature track for AML NIC
>
> drivers/net/ngbe/base/ngbe_phy_yt.c | 3 +
> drivers/net/ngbe/ngbe_ethdev.c | 5 -
> drivers/net/ngbe/ngbe_ethdev_vf.c | 11 +-
> drivers/net/txgbe/base/meson.build | 2 +
> drivers/net/txgbe/base/txgbe.h | 2 +
> drivers/net/txgbe/base/txgbe_aml.c | 185 +-
> drivers/net/txgbe/base/txgbe_aml.h | 6 +-
> drivers/net/txgbe/base/txgbe_aml40.c | 114 +-
> drivers/net/txgbe/base/txgbe_aml40.h | 6 +-
> drivers/net/txgbe/base/txgbe_dcb_hw.c | 2 +-
> drivers/net/txgbe/base/txgbe_e56.c | 3773 +++++++++++++++++++++
> drivers/net/txgbe/base/txgbe_e56.h | 1753 ++++++++++
> drivers/net/txgbe/base/txgbe_e56_bp.c | 2597 ++++++++++++++
> drivers/net/txgbe/base/txgbe_e56_bp.h | 282 ++
> drivers/net/txgbe/base/txgbe_hw.c | 54 +-
> drivers/net/txgbe/base/txgbe_hw.h | 4 +-
> drivers/net/txgbe/base/txgbe_osdep.h | 4 +
> drivers/net/txgbe/base/txgbe_phy.c | 362 +-
> drivers/net/txgbe/base/txgbe_phy.h | 45 +-
> drivers/net/txgbe/base/txgbe_regs.h | 13 +-
> drivers/net/txgbe/base/txgbe_type.h | 43 +-
> drivers/net/txgbe/txgbe_ethdev.c | 458 ++-
> drivers/net/txgbe/txgbe_ethdev.h | 7 +-
> drivers/net/txgbe/txgbe_rxtx.c | 107 +-
> drivers/net/txgbe/txgbe_rxtx.h | 36 +
> drivers/net/txgbe/txgbe_rxtx_vec_common.h | 16 +-
> 26 files changed, 9445 insertions(+), 445 deletions(-)
> create mode 100644 drivers/net/txgbe/base/txgbe_e56.c
> create mode 100644 drivers/net/txgbe/base/txgbe_e56.h
> create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.c
> create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.h
>
More AI review feedback summary:
18/21 — get EEPROM (Error): page is declared once before the for loop
and never reset, so after crossing the 256-byte boundary every
subsequent iteration walks one page further into the module than it
should. Plus two related issues: data[0x2] reads the output buffer not
the module byte, and the skip branch leaves stale databyte carrying
over from the previous iteration.
20/21 — Tx desc check (Error): #ifdef RTE_LIBRTE_SECURITY uses the
pre-2020 macro name; the modern name is RTE_LIB_SECURITY (and the
surrounding code in the same file uses it correctly). The IPsec guard
is therefore always compiled out and the wr32m runs for every queue,
including IPsec ones.
16/21 & 17/21 — whitespace: \t if (tab-then-space) on two lines. Checkpatch will catch it, but worth a pass.
17/21 — TXGBE_SFF_DDM_IMPLEMENTED: value 0x40 is correct as a bit-6
mask of byte 0x5C, but it is defined next to register-offset macros
which makes it read as an offset.
14/21 — kr_read_poll macro: uses usleep() directly; everything else in the txgbe base layer uses usec_delay().
7/21 — type pun: the atomic load casts a volatile uint32_t * to
volatile uint16_t *. Works on all DPDK platforms but is
strict-aliasing-iffy; a u32 load with a u16 cast at the use site would
be cleaner.
Longer full review:
Review of [PATCH v5 00/21] net/{txgbe,ngbe} fixes from Zaiyu Wang
This revision addresses the substantive issues raised on v4:
- 07/21: Tx desc free now uses a documented helper
txgbe_tx_headwb_desc_done() that correctly handles the head==next
boundary, and switches the headwb_mem read from a plain volatile
access to rte_atomic_load_explicit(... acquire).
- 08/21: AML xon/xoff stats no longer use plain assignment. The
counter now goes through the new TXGBE_UPDATE_COUNTER_32BIT_GENERIC
macro with offset tracking, and txgbe_clear_hw_cntrs() write-clears
the AML registers and zeroes hw->last_stats on reset.
- 11/21: traffic class priority is consistent across all three
callers. TXGBE_RPUP2TC_UP_SHIFT is bumped to 4, TXGBE_DCBUP2TC_MAP
is updated to match, txgbe_vmdq_dcb_configure() uses the macros
instead of a hardcoded *3 shift, and the unused TXGBE_DCBUP2TC_DEC
is removed. The bonus fix of redirecting
txgbe_dcb_config_tx_data_arbiter_raptor() to TXGBE_PBTXUP2TC instead
of TXGBE_PBRXUP2TC is welcome.
- 12/21: txgbe_setup_phy_link_aml() now sets link_up = false before
'goto out' on TXGBE_ERR_TIMEOUT, so the out: block correctly routes
to *need_reset = true. The generic 'compare' qsort helper has been
renamed to txgbe_e56_int_cmp().
Remaining findings on v5 below.
----------------------------------------------------------------
Patch 18/21 (net/txgbe: fix get EEPROM operation)
Error: page accumulation across loop iterations in
txgbe_get_module_eeprom() will return wrong bytes for any QSFP read
that crosses the 256-byte page boundary.
+ uint8_t page = 0;
...
+ for (i = info->offset; i < info->offset + info->length; i++) {
+ if (is_sfp) {
...
+ } else {
+ offset = i;
+ while (offset >= RTE_ETH_MODULE_SFF_8436_LEN) {
+ offset -= RTE_ETH_MODULE_SFF_8436_LEN / 2;
+ page++;
+ }
+ if (page == 0 || !(data[0x2] & 0x4)) {
+ status = hw->phy.read_i2c_sff8636(hw, page, offset,
+ &databyte);
'page' is declared once before the for loop and never reset, but the
while loop only increments it. For i = 256 the math is correct
(page=0 entering, page=1 leaving, offset=128). For i = 257 the loop
enters with page=1 already set from the previous iteration and ends
with page=2, offset=129 - it should still be page=1. Every subsequent
iteration adds one more page, so the function reads bytes from
ever-higher pages instead of staying on page 1, 2, 3, ...
Reset page (and rebuild offset) at each iteration:
uint16_t addr;
uint8_t page;
for (i = info->offset; i < info->offset + info->length; i++) {
...
} else {
page = 0;
addr = i;
while (addr >= RTE_ETH_MODULE_SFF_8436_LEN) {
addr -= RTE_ETH_MODULE_SFF_8436_LEN / 2;
page++;
}
...
}
}
Two related concerns in the same block:
- The flat-memory check '!(data[0x2] & 0x4)' inspects byte 2 of the
caller's output buffer rather than module byte 2. If info->offset
> 2 the byte was never read, so the test reads the value left by
memset (zero) and always evaluates to true. Read module byte 2
explicitly before the loop and stash it in a local.
- When the skip branch is taken (paged read on flat memory), the
loop still does 'data[i - info->offset] = databyte', so the byte
written is whatever databyte held from the previous iteration.
Set databyte to 0 (or 0xff) before each iteration, or set the
output byte directly inside the skip branch.
Patch 20/21 (net/txgbe: fix to enable Tx desc check)
Error: the new IPsec guard uses the wrong macro name and is always
compiled out.
+#ifdef RTE_LIBRTE_SECURITY
+ if (!txq->using_ipsec)
+#endif
+ wr32m(hw, TXGBE_TDM_DESC_CHK(txq->reg_idx / 32),
+ RTE_BIT32(txq->reg_idx % 32), RTE_BIT32(txq->reg_idx % 32));
The DPDK build macro is RTE_LIB_SECURITY; RTE_LIBRTE_SECURITY is the
pre-2020 name and is no longer defined anywhere in the tree (the rest
of this same driver uses RTE_LIB_SECURITY in the surrounding code,
including the deleted block this patch replaces). Result: the
'if (!txq->using_ipsec)' line is never preprocessed in, the wr32m
runs for every queue unconditionally, and IPsec-enabled queues get
the desc-check bit set even though the existing intent was to skip
them.
Replace with RTE_LIB_SECURITY. Matches the existing pattern
elsewhere in txgbe_rxtx.c (txgbe_rxtx.c:64, :444, :882, ...).
Patch 16/21 (net/txgbe: fix SFP module identification)
Warning: stray space in indentation of txgbe_read_i2c_sff8636() body.
+ s32 err = hw->phy.write_i2c_byte(hw, TXGBE_SFF_QSFP_PAGE_SELECT,
+ TXGBE_I2C_EEPROM_DEV_ADDR,
+ page);
+ if (err != 0)
+ return err;
The 'if' line is indented with tab+space instead of a single tab.
checkpatch will flag this.
Info: this patch refactors away phy.read_i2c_byte_unlocked and
phy.write_i2c_byte_unlocked and merges them into the existing
phy.read_i2c_byte / phy.write_i2c_byte slots, which now no longer
acquire the swfw semaphore. Patches 17 and 18 add explicit
acquire/release around their own callers, which is correct, but it is
worth double-checking that no other in-tree caller of
phy.read_i2c_eeprom / phy.read_i2c_sff8472 / phy.read_i2c_byte runs
without holding TXGBE_MNGSEM_SWPHY after this patch. The lock change
and the callsite updates would arguably read better squashed together
or at least kept adjacent in the series.
Patch 17/21 (net/txgbe: fix get module info operation)
Warning: stray space in indentation - same checkpatch issue as above.
+ if (hw->mac.type == txgbe_mac_aml) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_ABS_LS) {
'if' is tab+space indented; should be two tabs.
Info: TXGBE_SFF_DDM_IMPLEMENTED is added next to the SFP register
offset definitions, but is then used as a bit mask of byte 0x5C:
#define TXGBE_SFF_DDM_IMPLEMENTED 0x40
#define TXGBE_SFF_SFF_8472_SWAP 0x5C
...
if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap ||
!(addr_mode & TXGBE_SFF_DDM_IMPLEMENTED)) {
The value 0x40 is correct as bit 6 of the diagnostic-monitoring-type
byte at offset 0x5C, but placing it alongside register offsets makes
the macro look like an offset. Consider moving it into a bit-mask
group or renaming the offset/mask pair to make the intent obvious
(e.g. _ADDR vs _MASK suffix).
Patch 14/21 (net/txgbe: fix link stability for Amber-Lite)
Warning: the new kr_read_poll() macro in txgbe_phy.h uses usleep()
directly, while the rest of the txgbe base layer uses the
usec_delay() abstraction (which expands to rte_delay_us_block() on
DPDK). Mixing the two is inconsistent and pulls in a POSIX dependency
in a base/ file:
+#define kr_read_poll(op, val, cond, sleep_us, \
+ times, args...) \
+({ \
...
+ usleep(__sleep_us);\
...
+})
Switch to usec_delay() to match txgbe_eeprom.c, txgbe_hw.c, and the
rest of the same file.
Patch 7/21 (net/txgbe: fix Tx desc free logic)
Info: txq->headwb_mem is declared 'volatile uint32_t *', but the new
atomic read reads it as 'volatile uint16_t *':
+ const uint16_t head = rte_atomic_load_explicit((volatile uint16_t *)txq->headwb_mem,
+ rte_memory_order_acquire);
This works on every architecture DPDK supports (lower 16 bits of an
aligned 32-bit object are accessible as a 16-bit atomic and head fits
in 16 bits), but it is a type pun on a hardware-written object and a
strict-aliasing violation in pure C. A 32-bit atomic load with an
explicit cast at use site would be cleaner:
uint32_t h = rte_atomic_load_explicit(txq->headwb_mem,
rte_memory_order_acquire);
const uint16_t head = (uint16_t)h;
Stephen Hemminger <stephen@networkplumber.org>
^ permalink raw reply
* Re: [PATCH 1/2] ethdev: fix out-of-bounds write in GENEVE option conversion
From: Stephen Hemminger @ 2026-05-27 15:38 UTC (permalink / raw)
To: James Raphael Tiovalen; +Cc: orika, thomas, andrew.rybchenko, dev, stable
In-Reply-To: <20260526181159.287633-2-jamestiotio@gmail.com>
On Wed, 27 May 2026 02:11:58 +0800
James Raphael Tiovalen <jamestiotio@gmail.com> wrote:
> rte_flow_conv_item_spec() is documented to truncate output to the
> caller-supplied buffer size. For RTE_FLOW_ITEM_TYPE_GENEVE_OPT, the
> deep-copy of the variable-length option data was gated on `size > 0`
> instead of `size >= off + tmp`, the form used by the sibling RAW
> branch. A caller passing a buffer just large enough for the header
> struct had adjacent memory clobbered by up to `option_len * 4` bytes of
> option payload.
>
> Align the GENEVE_OPT guard with the RAW one.
>
> Fixes: 841a0445442d ("ethdev: fix GENEVE option item conversion")
> Cc: stable@dpdk.org
>
> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>
> ---
Does not apply to current main branch.
There were recent fixes in this area.
Rebase and resubmit please.
^ permalink raw reply
* Re: [PATCH v2] app/test-pmd: add generic PROG action parser support
From: Stephen Hemminger @ 2026-05-27 15:41 UTC (permalink / raw)
To: Megha Ajmera; +Cc: bruce.richardson, cristian.dumitrescu, praveen.shetty, dev
In-Reply-To: <20260521101354.726240-1-megha.ajmera@intel.com>
On Thu, 21 May 2026 15:43:54 +0530
Megha Ajmera <megha.ajmera@intel.com> wrote:
> Add parser support for a generic PROG flow action in testpmd.
>
> The update adds CLI tokens and parsing logic for program name and
> argument tuples (name, size, value), enabling programmable action
> configuration through the flow command interface.
>
> Example flow rule:
> flow create 0 ingress pattern eth / end actions prog name my_prog
> argument name arg0 size 4 value 10 / end
>
> Signed-off-by: Megha Ajmera <megha.ajmera@intel.com>
> Signed-off-by: Praveen Shetty <praveen.shetty@intel.com>
> ---
Ran AI review on this manually since that gets better context.
The feedback was:
On Thu, 21 May 2026 15:43:54 +0530
Megha Ajmera <megha.ajmera@intel.com> wrote:
> Add parser support for a generic PROG flow action in testpmd.
>
> The update adds CLI tokens and parsing logic for program name and
> argument tuples (name, size, value), enabling programmable action
> configuration through the flow command interface.
Errors
1. CREATE proceeds with partially-converted action data on conversion
failure.
In cmd_flow_parsed() the CREATE case prints a warning if
convert_action_prog_to_rte_flow() returns negative, then
unconditionally calls port_flow_create(). Inside
convert_action_prog_to_rte_flow(), each per-PROG failure does
"continue" rather than aborting, so the function returns negative
while some actions[i].conf pointers have been replaced with
rte_flow_action_prog and others still point to the parser-internal
action_prog_data (a completely different layout). The PMD then
dereferences a mix of two unrelated structure types. Either abort
the create on negative ret, or make convert_action_prog_to_rte_flow()
fail-fast: free everything converted so far, restore conf pointers
(or never overwrite them until the whole pass succeeds), and return
without touching port_flow_create().
2. Argument value is sent in host byte order, but the API requires
network byte order.
The doc for struct rte_flow_action_prog_argument in
lib/ethdev/rte_flow.h says the value array must be in network byte
order. The conversion code does:
memcpy(value, &prog_data->args[j].value, args[j].size);
prog_data->args[j].value is a host-order uint64_t populated by
parse_int. For "size 4 value 10" on little-endian this produces
{0x0a,0x00,0x00,0x00}; on big-endian it produces {0x00,0x00,0x00,0x00}
-- the leading zero bytes of the 8-byte value, so the user always
sees zero. Either convert with rte_cpu_to_be_32/64 before memcpy,
or have the parser accept and store the value as a network-order
byte array of the declared size.
3. Only the CREATE path is converted; VALIDATE and the async/template
paths still pass action_prog_data to the PMD.
cmd_flow_parsed() routes the same in->args.vc.actions array to
VALIDATE (port_flow_validate), and to multiple async/template paths
(port_queue_flow_create, port_flow_template_table_create,
port_action_handle_create, etc.). None of these are converted by
this patch, so any PROG action used with "flow validate",
"flow queue ... create", indirect-action create, or pattern/action
templates passes the parser-internal action_prog_data to the PMD
with the wrong layout. Conversion needs to be factored into a
helper invoked from every code path that hands actions to the
ethdev API, not bolted onto CREATE only.
4. Unbounded scan for END in convert_action_prog_to_rte_flow().
while (actions[i].type != RTE_FLOW_ACTION_TYPE_END)
i++;
If a caller ever passes an actions array without a terminating END,
this walks off the end. The caller already knows
in->args.vc.actions_n; pass that as the bound and remove the
dual-mode behavior (count-or-not). The function is only ever called
with prog_action_count == 0, so the other branch is dead code
anyway.
5. size == 0 argument is silently accepted but violates the API.
The rte_flow_action_prog_argument doc states "its size must be
non-zero and its value must point to a valid array of size bytes".
The convert code does:
args[j].size = prog_data->args[j].size;
if (args[j].size == 0)
continue;
This leaves args[j].value == NULL while args[j].size == 0 and hands
that to the PMD. Either reject size == 0 at parse time, or treat it
as an error during conversion. Letting it through means
valid-looking input produces an API-contract violation that the PMD
has no obligation to handle.
Warnings
6. Identifiers with a leading double underscore are reserved.
__prog_argument_name_args_push, __prog_argument_size_args_push, and
__prog_argument_value_args_push use a "__" prefix. The C standard
reserves names starting with two underscores for the implementation.
Rename to e.g. prog_argument_name_args_push.
7. RTE_SET_USED on parameters that are used.
parse_vc_action_prog_argument() marks token and str as unused, then
passes both to parse_default(). parse_vc_action_prog_argument_value()
marks size as unused, then passes it to parse_vc_conf(). The v2
changelog says "Fixed compilation warning"; these spurious
RTE_SET_USED calls look like that fix. Remove them -- they mislead
future readers and can hide a real unused parameter if one is added
later.
8. Doxygen parameter name mismatch.
The comment block above convert_action_prog_to_rte_flow() documents
"@param action_count" but the actual parameter is named
prog_action_count. The same comment describes a dual-mode interface
("If 0, will count until END action") that is never exercised --
fix the name or simplify the interface.
9. No testpmd user-guide update.
This adds new CLI syntax
actions prog name <name> argument name <n> size <s> value <v>
but doc/guides/testpmd_app_ug/testpmd_funcs.rst is not updated.
Users have no documented way to learn the syntax.
10. No release notes update.
A new user-visible testpmd feature should have a one-line entry in
the current release notes.
Info
11. The static "struct arg arg[ACTION_PROG_MAX_ARGS]" arrays inside the
three __prog_argument_*_args_push helpers can simply be a single
non-static "struct arg" (or three) on the stack. push_args()
consumes the entries during the current parse_vc_conf() call;
persistent storage across CLI invocations is not needed and
obscures the lifetime.
12. action_prog_data.length is written by the COMMON_STRING parser for
the prog name field but never read afterwards (convert uses strdup,
relying on NUL termination). It is required as a destination for
the COMMON_STRING args triple, but a brief comment would prevent
the next reader from thinking it is meaningful state.
^ permalink raw reply
* Re: [PATCH 1/3] net/bonding: restore dedicated queue state on mode set error
From: Bruce Richardson @ 2026-05-27 16:19 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, stable, Chas Williams, Min Hu (Connor), Tomasz Kulasek,
Declan Doherty
In-Reply-To: <20260417165530.653328-2-stephen@networkplumber.org>
On Fri, Apr 17, 2026 at 09:51:35AM -0700, Stephen Hemminger wrote:
> The calls to enable and disable dedicated queues are missing
> proper error handling. If setting bonding mode fails,
> restore original state and propagate the error return value.
>
> Fixes: 112891cd27e5 ("net/bonding: add dedicated HW queues for LACP control")
> Cc: stable@dpdk.org
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> drivers/net/bonding/rte_eth_bond_8023ad.c | 19 ++++++++++++-------
> 1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
> index ba88f6d261..a74b0059ac 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.c
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
> @@ -1727,7 +1727,7 @@ RTE_EXPORT_SYMBOL(rte_eth_bond_8023ad_dedicated_queues_enable)
> int
> rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
> {
> - int retval = 0;
> + int ret;
Any particular reason for the variable rename? Not that it's a problem, but
it does expand the diff.
> struct rte_eth_dev *dev;
> struct bond_dev_private *internals;
>
> @@ -1744,17 +1744,20 @@ rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
> if (dev->data->dev_started)
> return -1;
>
> + uint8_t old = internals->mode4.dedicated_queues.enabled;
Should you add a check that old != 1, and just return ok if so?
> internals->mode4.dedicated_queues.enabled = 1;
> + ret = bond_ethdev_mode_set(dev, internals->mode);
> + if (ret != 0)
> + internals->mode4.dedicated_queues.enabled = old;
>
Looking through the code, for 8023ad mode, I don't see any way of failure,
so this failure handling seems pointless. The function
bond_mode_8023ad_enable() loops through all the devices in the bond but
never checks for error for any of them, so always returns zero.
What is missing here is a check that the internals->mode is actually set to
8023ad.
Similar feedback applies to the disable function below.
/Bruce
^ permalink raw reply
* Re: [PATCH 2/3] net/bonding: prevent crash on Rx/Tx from secondary process
From: Bruce Richardson @ 2026-05-27 16:24 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, stable, Chas Williams, Min Hu (Connor), Anatoly Burakov,
Qi Zhang
In-Reply-To: <20260417165530.653328-3-stephen@networkplumber.org>
On Fri, Apr 17, 2026 at 09:51:36AM -0700, Stephen Hemminger wrote:
> The bonding PMD's secondary process attach path registered the
> ethdev but never installed rx_pkt_burst or tx_pkt_burst, leaving
> both as NULL. Any rx_burst or tx_burst call from a secondary
> process therefore crashed with a NULL pointer dereference.
>
> Fully sharing bonding state across processes would be
> overly complex. Instead, install blackhole burst functions
> in the secondary so the data path is safe by default. Rx returns 0
> and Tx frees the mbufs and reports them as transmitted,
> matching /dev/null semantics so applications do not spin
> retrying. Each stub logs once at NOTICE level on first use.
>
> Also reject bond mode changes from a secondary process.
> rte_eth_bond_mode_set() is callable from secondary, and
> without this guard it would overwrite the secondary's safe
> burst stubs with real per-mode functions whose internal
> state is not valid outside the primary, reintroducing the
> crash by another path.
>
> This keeps secondary support available for the more
> common use cases of procinfo and packet capture.
>
> Bugzilla ID: 1698
> Fixes: 4852aa8f6e21 ("drivers/net: enable hotplug on secondary process")
> Cc: stable@dpdk.org
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
However, see comment below.
> drivers/net/bonding/rte_eth_bond_pmd.c | 43 +++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index 96725071da..6a42257d2b 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -56,6 +56,33 @@ get_vlan_offset(struct rte_ether_hdr *eth_hdr, uint16_t *proto)
> return vlan_offset;
> }
>
> +static uint16_t
> +bond_ethdev_rx_secondary(void *queue __rte_unused,
> + struct rte_mbuf **bufs __rte_unused, uint16_t nb_pkts __rte_unused)
> +{
> + static bool once = true;
> +
> + if (once) {
> + /* once per process is enough of a notice */
> + RTE_BOND_LOG(NOTICE, "receive not supported in secondary");
Since this does nothing, I think that an ERROR level warning is more
appropriate than notice. If not for Rx, certainly for Tx which just
silently drops packets!
> + once = false;
> + }
> + return 0;
> +}
> +
> +static uint16_t
> +bond_ethdev_tx_secondary(void *queue __rte_unused, struct rte_mbuf **bufs, uint16_t nb_pkts)
> +{
> + static bool once = true;
> +
> + if (once) {
> + RTE_BOND_LOG(NOTICE, "transmit not supported in secondary");
> + once = false;
> + }
> + rte_pktmbuf_free_bulk(bufs, nb_pkts);
> + return nb_pkts;
> +}
> +
> static uint16_t
> bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
> {
> @@ -1599,6 +1626,11 @@ bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, uint8_t mode)
> {
> struct bond_dev_private *internals;
>
> + if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
> + RTE_BOND_LOG(ERR, "Setting mode in secondary not allowed");
> + return -1;
> + }
> +
> internals = eth_dev->data->dev_private;
>
> switch (mode) {
> @@ -3799,9 +3831,18 @@ bond_probe(struct rte_vdev_device *dev)
> RTE_BOND_LOG(ERR, "Failed to probe %s", name);
> return -1;
> }
> - /* TODO: request info from primary to set up Rx and Tx */
> +
> eth_dev->dev_ops = &default_dev_ops;
> eth_dev->device = &dev->device;
> +
> + /*
> + * Propagation of bond mode would require adding
> + * MP client/server support and lots of error handling.
> + *
> + * For now just install a black hole.
> + */
> + eth_dev->tx_pkt_burst = bond_ethdev_tx_secondary;
> + eth_dev->rx_pkt_burst = bond_ethdev_rx_secondary;
> rte_eth_dev_probing_finish(eth_dev);
> return 0;
> }
> --
> 2.53.0
>
^ permalink raw reply
* Re: [PATCH 3/3] net/bonding: remove redundant function names from log
From: Bruce Richardson @ 2026-05-27 16:28 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Chas Williams, Min Hu (Connor)
In-Reply-To: <20260417165530.653328-4-stephen@networkplumber.org>
On Fri, Apr 17, 2026 at 09:51:37AM -0700, Stephen Hemminger wrote:
> The function name is already printed as part of RTE_BOND_LOG().
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> drivers/net/bonding/rte_eth_bond_api.c | 4 ++--
> drivers/net/bonding/rte_eth_bond_pmd.c | 23 ++++++++++-------------
> 2 files changed, 12 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
> index 9e5df67c18..78361e73d4 100644
> --- a/drivers/net/bonding/rte_eth_bond_api.c
> +++ b/drivers/net/bonding/rte_eth_bond_api.c
> @@ -485,8 +485,8 @@ __eth_bond_member_add_lock_free(uint16_t bonding_port_id, uint16_t member_port_i
> ret = rte_eth_dev_info_get(member_port_id, &dev_info);
> if (ret != 0) {
> RTE_BOND_LOG(ERR,
> - "%s: Error during getting device (port %u) info: %s",
> - __func__, member_port_id, strerror(-ret));
> + "Error during getting device (port %u) info: %s",
While updating, I think it would be good to update the log messages to be
more natural-sounding English. s/during getting/getting/
> + member_port_id, strerror(-ret));
>
> return ret;
> }
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index 6a42257d2b..e2819c931b 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -210,8 +210,8 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
> int ret = rte_flow_validate(member_port, &flow_attr_8023ad,
> flow_item_8023ad, actions, &error);
> if (ret < 0) {
> - RTE_BOND_LOG(ERR, "%s: %s (member_port=%d queue_id=%d)",
> - __func__, error.message, member_port,
> + RTE_BOND_LOG(ERR, "%s (member_port=%u queue_id=%u)",
> + error.message, member_port,
> internals->mode4.dedicated_queues.rx_qid);
> return -1;
> }
> @@ -219,8 +219,8 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
> ret = rte_eth_dev_info_get(member_port, &member_info);
> if (ret != 0) {
> RTE_BOND_LOG(ERR,
> - "%s: Error during getting device (port %u) info: %s",
> - __func__, member_port, strerror(-ret));
> + "Error during getting device (port %u) info: %s",
> + member_port, strerror(-ret));
>
> return ret;
> }
> @@ -228,8 +228,8 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
> if (member_info.max_rx_queues < bond_dev->data->nb_rx_queues ||
> member_info.max_tx_queues < bond_dev->data->nb_tx_queues) {
> RTE_BOND_LOG(ERR,
> - "%s: Member %d capabilities doesn't allow allocating additional queues",
> - __func__, member_port);
> + "Member %u capabilities doesn't allow allocating additional queues",
> + member_port);
> return -1;
> }
>
> @@ -249,9 +249,8 @@ bond_8023ad_slow_pkt_hw_filter_supported(uint16_t port_id) {
> ret = rte_eth_dev_info_get(bond_dev->data->port_id, &bond_info);
> if (ret != 0) {
> RTE_BOND_LOG(ERR,
> - "%s: Error during getting device (port %u) info: %s",
> - __func__, bond_dev->data->port_id,
> - strerror(-ret));
> + "Error during getting device (port %u) info: %s",
> + bond_dev->data->port_id, strerror(-ret));
>
> return ret;
> }
> @@ -2347,10 +2346,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
> ret = rte_eth_dev_info_get(member.port_id, &member_info);
> if (ret != 0) {
> RTE_BOND_LOG(ERR,
> - "%s: Error during getting device (port %u) info: %s",
> - __func__,
> - member.port_id,
> - strerror(-ret));
> + "Error during getting device (port %u) info: %s",
> + member.port_id, strerror(-ret));
>
> return ret;
> }
^ permalink raw reply
* [RFC] doc, devtools: discourage new __rte_always_inline
From: Stephen Hemminger @ 2026-05-27 16:37 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
Modern compilers at -O2 make good inlining decisions for small
static inline functions; forced inlining via __rte_always_inline
should be reserved for cases where it is required for correctness
or for documented measured performance reasons.
Document the policy in the coding style guide and add a
checkpatches.sh entry that warns when new uses of the attribute
are introduced.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
devtools/checkpatches.sh | 8 ++++++++
doc/guides/contributing/coding_style.rst | 25 +++++++++++++++++++++++-
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index f5dd77443f..2a3d364178 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -137,6 +137,14 @@ check_forbidden_additions() { # <patch>
-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
"$1" || res=1
+ # forbid new use of __rte_always_inline
+ awk -v FOLDERS="lib drivers app examples" \
+ -v EXPRESSIONS='\\<__rte_always_inline\\>' \
+ -v RET_ON_FAIL=1 \
+ -v MESSAGE='Adding __rte_always_inline; prefer plain inline' \
+ -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
+ "$1" || res=1
+
# refrain from using compiler __rte_atomic_thread_fence()
# It should be avoided on x86 for SMP case.
awk -v FOLDERS="lib drivers app examples" \
diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
index 243a3c2959..97e459853c 100644
--- a/doc/guides/contributing/coding_style.rst
+++ b/doc/guides/contributing/coding_style.rst
@@ -747,11 +747,34 @@ Static Variables and Functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* All functions and variables that are local to a file must be declared as ``static`` because it can often help the compiler to do some optimizations (such as, inlining the code).
-* Functions that should be inlined should to be declared as ``static inline`` and can be defined in a .c or a .h file.
+* Functions that should be inlined should be declared as ``static inline`` and can be defined in a .c or a .h file.
.. note::
Static functions defined in a header file must be declared as ``static inline`` in order to prevent compiler warnings about the function being unused.
+Use of ``__rte_always_inline``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``__rte_always_inline`` attribute forces the compiler to inline a function regardless of its size or call-graph heuristics.
+Prefer plain ``inline`` (or no annotation at all for static functions) and let the compiler decide.
+Modern compilers at ``-O2`` make good inlining decisions for small ``static inline`` functions in headers,
+and forced inlining can hurt performance by inflating function bodies, increasing register pressure, and overriding profile-guided optimization.
+
+``__rte_always_inline`` should only be used when one of the following applies:
+
+* The function contains ``__builtin_constant_p`` checks that gate a constant-folded fast path, and the optimization is lost if the function is not inlined into the caller.
+ Examples include byte-order helpers and length-dispatched copy/compare routines.
+
+* The function wraps inline assembly or a compiler intrinsic whose correctness depends on being inlined into the caller's register context (for example, intrinsics requiring a compile-time constant argument).
+
+* Measurement on a representative workload shows that the annotation is required to retain performance, and the reason is documented in the commit message that introduces it.
+
+Each use must be justified at the point it is introduced. Adding ``__rte_always_inline`` because nearby code uses it is not a justification;
+if the constant or intrinsic that requires inlining is several call levels up the call chain,
+restructure the code rather than annotating the entire chain.
+
+The complementary attribute ``__rte_noinline`` is useful for explicitly marking cold paths (error handling, initialization, slow-path fallbacks) where outlining the function can reduce instruction-cache pressure on the hot path.
+
Const Attribute
~~~~~~~~~~~~~~~
--
2.53.0
^ permalink raw reply related
* RE: [PATCH v4 04/27] bpf: use C11 atomics in BPF_ST_ATOMIC_REG
From: Marat Khalili @ 2026-05-27 16:52 UTC (permalink / raw)
To: Stephen Hemminger, dev@dpdk.org; +Cc: Konstantin Ananyev
In-Reply-To: <20260526232542.620966-5-stephen@networkplumber.org>
> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Wednesday 27 May 2026 00:24
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Konstantin Ananyev <konstantin.ananyev@huawei.com>;
> Marat Khalili <marat.khalili@huawei.com>
> Subject: [PATCH v4 04/27] bpf: use C11 atomics in BPF_ST_ATOMIC_REG
>
> The BPF_ST_ATOMIC_REG macro generated code with deprecated
> rte_atomicNN_add and rte_atomicNN_exchange.
>
> Replace this with the equivalent rte_stdatomic definitions.
> Use memory order seq_cst to preserve the previous behavior of
> rte_atomicNN_add() / rte_atomicNN_exchange() and matches
> the Linux kernel BPF interpreter for these opcodes.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> lib/bpf/bpf_exec.c | 13 +++++++------
> 1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/lib/bpf/bpf_exec.c b/lib/bpf/bpf_exec.c
> index 18013753b1..ee6ec7516f 100644
> --- a/lib/bpf/bpf_exec.c
> +++ b/lib/bpf/bpf_exec.c
> @@ -10,6 +10,7 @@
> #include <rte_log.h>
> #include <rte_debug.h>
> #include <rte_byteorder.h>
> +#include <rte_stdatomic.h>
>
> #include "bpf_impl.h"
>
> @@ -65,16 +66,16 @@
> (type)(reg)[(ins)->src_reg])
>
> #define BPF_ST_ATOMIC_REG(reg, ins, tp) do { \
> + RTE_ATOMIC(uint##tp##_t) *dst = (RTE_ATOMIC(uint##tp##_t) *) \
> + (uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off); \
> switch (ins->imm) { \
> case BPF_ATOMIC_ADD: \
> - rte_atomic##tp##_add((rte_atomic##tp##_t *) \
> - (uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off), \
> - (reg)[(ins)->src_reg]); \
> + rte_atomic_fetch_add_explicit(dst, \
> + (reg)[(ins)->src_reg], rte_memory_order_seq_cst); \
> break; \
> case BPF_ATOMIC_XCHG: \
> - (reg)[(ins)->src_reg] = rte_atomic##tp##_exchange((uint##tp##_t *) \
> - (uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off), \
> - (reg)[(ins)->src_reg]); \
> + (reg)[(ins)->src_reg] = rte_atomic_exchange_explicit(dst, \
> + (reg)[(ins)->src_reg], rte_memory_order_seq_cst); \
> break; \
> default: \
> /* this should be caught by validator and never reach here */ \
> --
> 2.53.0
Reviewed-by: Marat Khalili <marat.khalili@huawei.com>
nit: in the last sentence of the commit message `s` is not needed in `matches`,
and some word like `behavior` can be added for clarity after `interpreter`.
FWIW whole patchset builds on our amd64 and arm64 machines and passes our subset of tests.
^ permalink raw reply
* Re: [RFC 2/3] lib: add fastmem library
From: Mattias Rönnblom @ 2026-05-27 17:25 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, Morten Brørup, Konstantin Ananyev,
Mattias Rönnblom, Yogaraj Baskaravel
In-Reply-To: <20260527072251.7c53719d@phoenix.local>
On 5/27/26 16:22, Stephen Hemminger wrote:
> On Mon, 25 May 2026 12:36:41 +0200
> Mattias Rönnblom <hofors@lysator.liu.se> wrote:
>
>> +
>> +static __rte_always_inline struct fastmem_cache *
>> +cache_get(struct fastmem_socket_state *socket, unsigned int class_idx,
>> + unsigned int lcore_id)
>
> Do not use always_inline. With current compilers using always inline
> makes the optimizer generate worse code. The only exceptions would
> be where inline is required to make assembly work or you have good benchmark
> data that proves that always_inline generates > 1% performance gain.
>
> To much of DPDK use __rte_always_inline as "cargo cult" it is faster setting.
__rte_always_inline is still useful, but it is rare. For example, it may
be required in certain situations to force constant propagation to
actually occur.
I'm removing both inline and always_inline. Doesn't make a difference,
so noise.
^ permalink raw reply
* [RFC v3 0/3] lib/fastmem: fast small-object allocator
From: Mattias Rönnblom @ 2026-05-27 17:30 UTC (permalink / raw)
To: dev
Cc: Morten Brørup, Konstantin Ananyev, Mattias Rönnblom,
Yogaraj Baskaravel, Stephen Hemminger, Bruce Richardson,
Mattias Rönnblom
In-Reply-To: <20260526085743.64396-4-hofors@lysator.liu.se>
This RFC introduces fastmem, a general-purpose small-object allocator
for DPDK. It is intended to replace per-type mempools with a single
allocator that handles arbitrary sizes, grows on demand, and matches
mempool-level performance on the hot path.
Motivation
----------
DPDK applications commonly maintain many mempools — one per object
type (connections, sessions, timers, work items). Each must be sized
up front, wastes memory when over-provisioned, and cannot serve
objects of a different size. Fastmem eliminates this by accepting
arbitrary sizes at runtime, backed by a slab allocator that
repurposes memory across size classes as demand shifts.
Design
------
Three-layer architecture:
1. Backing memory: 128 MiB IOVA-contiguous memzones from EAL,
reserved lazily (or pre-reserved for deterministic latency).
2. Slabs: 2 MiB, 2 MiB-aligned regions carved from memzones.
The alignment enables O(1) slab lookup from any object pointer
via bitmask — no radix tree or index structure. Slabs move
freely between 18 power-of-2 size classes (8 B to 1 MiB).
3. Per-lcore caches: bounded LIFO stacks (no locks on the hot
path). Cache misses trigger bulk transfers to/from the shared
bin under a spinlock.
Key properties:
- Zero per-object metadata in the production build.
- NUMA-aware, with per-socket bins and free-slab pools.
- DMA-usable memory with O(1) virt-to-IOVA translation.
- Bulk alloc/free with all-or-nothing semantics.
- Backing memory never returned during lifetime (slabs recycled).
- Non-EAL threads supported (bypass cache, take bin lock).
- Secondary process support (lazy attach, no per-lcore caches).
API surface
-----------
rte_fastmem_init / deinit
rte_fastmem_reserve
rte_fastmem_set_limit / get_limit
rte_fastmem_alloc / alloc_socket
rte_fastmem_realloc
rte_fastmem_alloc_bulk / alloc_bulk_socket
rte_fastmem_free / free_bulk
rte_fastmem_hlookup / halloc / halloc_bulk / hfree / hfree_bulk
rte_fastmem_virt2iova
rte_fastmem_cache_flush
rte_fastmem_max_size / classes
rte_fastmem_stats / stats_class / stats_lcore / stats_lcore_class
rte_fastmem_stats_reset
All APIs are marked __rte_experimental.
Performance
-----------
The single-object hot path is roughly 2–3× the cost of mempool
and an order of magnitude faster than rte_malloc. Under
multi-lcore contention, fastmem scales similarly to mempool,
while rte_malloc collapses.
Limitations
-----------
- Maximum allocation: 1 MiB. Larger requests should use rte_malloc.
- Power-of-2 classes only; worst-case internal fragmentation ~50%.
- Backing memory not reclaimable short of deinit.
Future work
-----------
- Lcore-affine allocations (false-sharing-free by construction).
- Mempool ops driver for transparent drop-in use.
- Debug mode (cookies, double-free detection, poison-on-free).
- Telemetry integration.
- EAL integration, allowing EAL-internal subsystems to use
fastmem for their small-object allocations.
Changes in RFC v3:
- Add rte_fastmem_realloc() with full test coverage.
- Add __rte_malloc/__rte_dealloc compiler attributes; remove
incorrect __rte_alloc_size/__rte_alloc_align.
- Extract normalize_align() helper; remove redundant inline
directives.
- Merge lifecycle and functional test suites.
- Add realloc subsection to programming guide.
Changes in RFC v2:
- Fix cross-socket deinit use-after-free.
- Add secondary process support.
- Add handle-based allocation API.
- Fix clang warnings; misc cleanup.
Mattias Rönnblom (3):
doc: add fastmem programming guide
lib: add fastmem library
app/test: add fastmem test suite
app/test/meson.build | 3 +
app/test/test_fastmem.c | 1801 +++++++++++++++++++++++++
app/test/test_fastmem_perf.c | 1040 ++++++++++++++
app/test/test_fastmem_profile.c | 157 +++
doc/api/doxy-api-index.md | 1 +
doc/api/doxy-api.conf.in | 1 +
doc/guides/prog_guide/fastmem_lib.rst | 328 +++++
doc/guides/prog_guide/index.rst | 1 +
lib/fastmem/meson.build | 6 +
lib/fastmem/rte_fastmem.c | 1748 ++++++++++++++++++++++++
lib/fastmem/rte_fastmem.h | 815 +++++++++++
lib/meson.build | 1 +
12 files changed, 5902 insertions(+)
create mode 100644 app/test/test_fastmem.c
create mode 100644 app/test/test_fastmem_perf.c
create mode 100644 app/test/test_fastmem_profile.c
create mode 100644 doc/guides/prog_guide/fastmem_lib.rst
create mode 100644 lib/fastmem/meson.build
create mode 100644 lib/fastmem/rte_fastmem.c
create mode 100644 lib/fastmem/rte_fastmem.h
--
2.43.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox