<div dir="ltr"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 3, 2025 at 2:04 PM Andrew Bailey <<a href="mailto:abailey@iol.unh.edu" target="_blank">abailey@iol.unh.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Currently, there is support for tracking the Rx offload capabilities of<br>
a NIC, but not for Tx offload capabilities. This is an issue if a test<br>
suite is written requiring one of these capabilities, since there is no<br>
way currently to verify that the NIC in use meets the requirements. Add<br>
Tx capabilities to the NIC capabilities at beginning of dts so<br>
requirements can be verified.<br>
<br>
Signed-off-by: Andrew Bailey <<a href="mailto:abailey@iol.unh.edu" target="_blank">abailey@iol.unh.edu</a>><br>
---<br>
dts/framework/remote_session/testpmd_shell.py | 203 ++++++++++++++++++<br>
1 file changed, 203 insertions(+)<br>
<br>
diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py<br>
index 4d9caceb37..dfd83ebdb3 100644<br>
--- a/dts/framework/remote_session/testpmd_shell.py<br>
+++ b/dts/framework/remote_session/testpmd_shell.py<br>
@@ -1285,6 +1285,99 @@ class TestPmdVerbosePacket(TextParser):<br>
)<br>
<br>
<br>
+class TxOffloadCapability(Flag):<br>
+ """TX offload capabilities of a device.<br>
+<br>
+ The flags are taken from ``lib/ethdev/rte_ethdev.h``.<br>
+ They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in ``lib/ethdev/rte_ethdev.h``<br>
+ instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix to.<br>
+ The values are not contiguous, so the correspondence is preserved<br>
+ by specifying concrete values interspersed between auto() values.<br></blockquote><div><br></div><div>afaik only rx_offloads specify concrete values. It looks like these flags are all auto().</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ The ``TX_OFFLOAD`` prefix has been preserved so that the same flag names can be used<br>
+ in :class:`NicCapability`. The prefix is needed in :class:`NicCapability` since there's<br>
+ no other qualifier which would sufficiently distinguish it from other capabilities.<br>
+<br>
+ References:<br>
+ DPDK lib: ``lib/ethdev/rte_ethdev.h``<br>
+ testpmd display function: ``app/test-pmd/cmdline.c:print_rx_offloads()``<br>
+ """<br>
+<br>
+ TX_OFFLOAD_VLAN_INSERT = auto()<br>
+ TX_OFFLOAD_IPV4_CKSUM = auto()<br>
+ TX_OFFLOAD_UDP_CKSUM = auto()<br>
+ TX_OFFLOAD_TCP_CKSUM = auto()<br>
+ TX_OFFLOAD_SCTP_CKSUM = auto()<br>
+ TX_OFFLOAD_TCP_TSO = auto()<br>
+ TX_OFFLOAD_UDP_TSO = auto()<br>
+ TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()<br>
+ TX_OFFLOAD_QINQ_INSERT = auto()<br>
+ TX_OFFLOAD_VXLAN_TNL_TSO = auto()<br>
+ TX_OFFLOAD_GRE_TNL_TSO = auto()<br>
+ TX_OFFLOAD_IPIP_TNL_TSO = auto()<br>
+ TX_OFFLOAD_GENEVE_TNL_TSO = auto()<br>
+ TX_OFFLOAD_MACSEC_INSERT = auto()<br>
+ TX_OFFLOAD_MT_LOCKFREE = auto()<br>
+ TX_OFFLOAD_MULTI_SEGS = auto()<br>
+ TX_OFFLOAD_MBUF_FAST_FREE = auto()<br>
+ TX_OFFLOAD_SECURITY = auto()<br>
+ TX_OFFLOAD_UDP_TNL_TSO = auto()<br>
+ TX_OFFLOAD_IP_TNL_TSO = auto()<br>
+ TX_OFFLOAD_OUTER_UDP_CKSUM = auto()<br>
+ TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()<br>
+<br>
+ @classmethod<br>
+ def from_string(cls, line: str) -> Self:<br>
+ """Make an instance from a string containing the flag names separated with a space.<br>
+<br>
+ Args:<br>
+ line: The line to parse.<br>
+<br>
+ Returns:<br>
+ A new instance containing all found flags.<br>
+ """<br>
+ flag = cls(0)<br>
+ for flag_name in line.split():<br>
+ flag |= cls[f"TX_OFFLOAD_{flag_name}"]<br>
+ return flag<br>
+<br>
+ @classmethod<br>
+ def make_parser(cls, per_port: bool) -> ParserFn:<br>
+ """Make a parser function.<br>
+<br>
+ Args:<br>
+ per_port: If :data:`True`, will return capabilities per port. If :data:`False`,<br>
+ will return capabilities per queue.<br>
+<br>
+ Returns:<br>
+ ParserFn: A dictionary for the `dataclasses.field` metadata argument containing a<br>
+ parser function that makes an instance of this flag from text.<br>
+ """<br>
+ granularity = "Port" if per_port else "Queue"<br>
+ return TextParser.wrap(<br>
+ TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),<br>
+ cls.from_string,<br>
+ )<br>
+<br>
+<br>
+@dataclass<br>
+class TxOffloadCapabilities(TextParser):<br>
+ """The result of testpmd's ``show port <port_id> tx_offload capabilities`` command.<br>
+<br>
+ References:<br>
+ testpmd command function: ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa()``<br>
+ testpmd display function: ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa_parsed()``<br>
+ """<br>
+<br>
+ port_id: int = field(<br>
+ metadata=TextParser.find_int(r"Tx Offloading Capabilities of port (\d+) :")<br>
+ )<br>
+ #: Per-queue Tx offload capabilities.<br>
+ per_queue: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(False))<br>
+ #: Capabilities other than per-queue Tx offload capabilities.<br>
+ per_port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True))<br>
+<br>
+<br>
class RxOffloadCapability(Flag):<br>
"""Rx offload capabilities of a device.<br>
<br>
@@ -2397,6 +2490,28 @@ def close(self) -> None:<br>
====== Capability retrieval methods ======<br>
"""<br>
<br>
+ def get_capabilities_tx_offload(<br>
+ self,<br>
+ supported_capabilities: MutableSet["NicCapability"],<br>
+ unsupported_capabilities: MutableSet["NicCapability"],<br>
+ ) -> None:<br>
+ """Get all TX offload capabilities and divide them into supported and unsupported.<br>
+<br>
+ Args:<br>
+ supported_capabilities: Supported capabilities will be added to this set.<br>
+ unsupported_capabilities: Unsupported capabilities will be added to this set.<br>
+ """<br>
+ self._logger.debug("Getting TX offload capabilities.")<br>
+ command = f"show port {self.ports[0].id} tx_offload capabilities"<br>
+ tx_offload_capabilities_out = self.send_command(command)<br>
+ tx_offload_capabilities = TxOffloadCapabilities.parse(tx_offload_capabilities_out)<br>
+ self._update_capabilities_from_flag(<br>
+ supported_capabilities,<br>
+ unsupported_capabilities,<br>
+ TxOffloadCapability,<br>
+ tx_offload_capabilities.per_port | tx_offload_capabilities.per_queue,<br>
+ )<br>
+<br>
def get_capabilities_rx_offload(<br>
self,<br>
supported_capabilities: MutableSet["NicCapability"],<br>
@@ -2824,6 +2939,94 @@ class NicCapability(NoAliasEnum):<br>
we don't go looking for it again if a different test case also needs it.<br>
"""<br>
<br>
+ TX_OFFLOAD_VLAN_INSERT: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_IPV4_CKSUM: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_UDP_CKSUM: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_TCP_CKSUM: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_SCTP_CKSUM: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_TCP_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_UDP_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_QINQ_INSERT: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_MACSEC_INSERT: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_MT_LOCKFREE: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_MULTI_SEGS: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_SECURITY: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_IP_TNL_TSO: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
+ TX_OFFLOAD_SEND_ON_TIMESTAMP: TestPmdShellNicCapability = (<br>
+ TestPmdShell.get_capabilities_tx_offload,<br>
+ None,<br>
+ )<br>
#: Scattered packets Rx enabled<br>
SCATTERED_RX_ENABLED: TestPmdShellNicCapability = (<br>
TestPmdShell.get_capabilities_rxq_info,<br>
-- <br>
2.50.1<br>
<br></blockquote><div><br></div><div>Looks good. Have you verified the docs will build from this patch? If you haven't done this yet it's</div><div><br></div><div>meson setup my_build</div><div>ninja -C my_build doc</div><div><br></div><div>Reviewed-by: Patrick Robb <<a href="mailto:probb@iol.unh.edu" target="_blank">probb@iol.unh.edu</a>> </div></div></div>
</div>