From: Jeremy Spewock <jspew...@iol.unh.edu> The ability to query RX offloading capabilities of a device already exist, but there are situations in other test suites where skipping a test case/suite based on if a TX capability is missing is also desirable. This patch expands the RX offloading capabilities class to also allow for collecting TX offloading capabilities by creating a common parent class with parsing utility that is generalized to both.
Signed-off-by: Jeremy Spewock <jspew...@iol.unh.edu> --- dts/framework/remote_session/testpmd_shell.py | 395 +++++++++++++----- 1 file changed, 297 insertions(+), 98 deletions(-) diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py index 99f327a91b..13001d6666 100644 --- a/dts/framework/remote_session/testpmd_shell.py +++ b/dts/framework/remote_session/testpmd_shell.py @@ -21,7 +21,7 @@ from enum import Flag, auto from functools import partial from pathlib import PurePath -from typing import TYPE_CHECKING, Any, ClassVar, TypeAlias +from typing import TYPE_CHECKING, Any, ClassVar, TypeAlias, cast if TYPE_CHECKING: from enum import Enum as NoAliasEnum @@ -661,55 +661,8 @@ class TestPmdPortStats(TextParser): tx_bps: int = field(metadata=TextParser.find_int(r"Tx-bps:\s+(\d+)")) - -class RxOffloadCapability(Flag): - """Rx offload capabilities of a device.""" - - #: - RX_OFFLOAD_VLAN_STRIP = auto() - #: Device supports L3 checksum offload. - RX_OFFLOAD_IPV4_CKSUM = auto() - #: Device supports L4 checksum offload. - RX_OFFLOAD_UDP_CKSUM = auto() - #: Device supports L4 checksum offload. - RX_OFFLOAD_TCP_CKSUM = auto() - #: Device supports Large Receive Offload. - RX_OFFLOAD_TCP_LRO = auto() - #: Device supports QinQ (queue in queue) offload. - RX_OFFLOAD_QINQ_STRIP = auto() - #: Device supports inner packet L3 checksum. - RX_OFFLOAD_OUTER_IPV4_CKSUM = auto() - #: Device supports MACsec. - RX_OFFLOAD_MACSEC_STRIP = auto() - #: Device supports filtering of a VLAN Tag identifier. - RX_OFFLOAD_VLAN_FILTER = 1 << 9 - #: Device supports VLAN offload. - RX_OFFLOAD_VLAN_EXTEND = auto() - #: Device supports receiving segmented mbufs. - RX_OFFLOAD_SCATTER = 1 << 13 - #: Device supports Timestamp. - RX_OFFLOAD_TIMESTAMP = auto() - #: Device supports crypto processing while packet is received in NIC. - RX_OFFLOAD_SECURITY = auto() - #: Device supports CRC stripping. - RX_OFFLOAD_KEEP_CRC = auto() - #: Device supports L4 checksum offload. - RX_OFFLOAD_SCTP_CKSUM = auto() - #: Device supports inner packet L4 checksum. - RX_OFFLOAD_OUTER_UDP_CKSUM = auto() - #: Device supports RSS hashing. - RX_OFFLOAD_RSS_HASH = auto() - #: Device supports - RX_OFFLOAD_BUFFER_SPLIT = auto() - #: Device supports all checksum capabilities. - RX_OFFLOAD_CHECKSUM = RX_OFFLOAD_IPV4_CKSUM | RX_OFFLOAD_UDP_CKSUM | RX_OFFLOAD_TCP_CKSUM - #: Device supports all VLAN capabilities. - RX_OFFLOAD_VLAN = ( - RX_OFFLOAD_VLAN_STRIP - | RX_OFFLOAD_VLAN_FILTER - | RX_OFFLOAD_VLAN_EXTEND - | RX_OFFLOAD_QINQ_STRIP - ) +class OffloadCapability(Flag): + """Offload capabilities of a device.""" @classmethod def from_string(cls, line: str) -> Self: @@ -723,7 +676,7 @@ def from_string(cls, line: str) -> Self: """ flag = cls(0) for flag_name in line.split(): - flag |= cls[f"RX_OFFLOAD_{flag_name}"] + flag |= cls[flag_name] return flag @classmethod @@ -745,20 +698,130 @@ def make_parser(cls, per_port: bool) -> ParserFn: ) +class RxOffloadCapability(OffloadCapability): + """Rx offload capabilities of a device.""" + + #: Device supports L3 checksum offload. + IPV4_CKSUM = auto() + #: Device supports L4 checksum offload. + UDP_CKSUM = auto() + #: Device supports L4 checksum offload. + TCP_CKSUM = auto() + #: Device supports inner packet L3 checksum. + OUTER_IPV4_CKSUM = auto() + #: Device supports crypto processing while packet is received in NIC. + SECURITY = auto() + #: + VLAN_STRIP = auto() + #: Device supports Large Receive Offload. + TCP_LRO = auto() + #: Device supports QinQ (queue in queue) offload. + QINQ_STRIP = auto() + #: Device supports MACsec. + MACSEC_STRIP = auto() + #: Device supports filtering of a VLAN Tag identifier. + VLAN_FILTER = 1 << 9 + #: Device supports VLAN offload. + VLAN_EXTEND = auto() + #: Device supports receiving segmented mbufs. + SCATTER = 1 << 13 + #: Device supports Timestamp. + TIMESTAMP = auto() + #: Device supports CRC stripping. + KEEP_CRC = auto() + #: Device supports L4 checksum offload. + SCTP_CKSUM = auto() + #: Device supports inner packet L4 checksum. + OUTER_UDP_CKSUM = auto() + #: Device supports RSS hashing. + RSS_HASH = auto() + #: Device supports + BUFFER_SPLIT = auto() + #: Device supports all checksum capabilities. + CHECKSUM = IPV4_CKSUM | UDP_CKSUM | TCP_CKSUM + #: Device supports all VLAN capabilities. + VLAN = VLAN_STRIP | VLAN_FILTER | VLAN_EXTEND | QINQ_STRIP + + +class TxOffloadCapability(OffloadCapability): + """Tx offload capabilities of a device.""" + + #: Device supports L3 checksum offload. + IPV4_CKSUM = auto() + #: Device supports L4 checksum offload. + UDP_CKSUM = auto() + #: Device supports L4 checksum offload. + TCP_CKSUM = auto() + #: Device supports inner packet L3 checksum. + OUTER_IPV4_CKSUM = auto() + #: Device supports crypto processing while packet is received in NIC. + SECURITY = auto() + #: + VLAN_INSERT = auto() + #: + QINQ_INSERT = auto() + #: + SCTP_CKSUM = auto() + #: Device supports QinQ (queue in queue) stripping offload. + QINQ_STRIP = auto() + #: Device supports TCP Segmentation Offload. + TCP_TSO = auto() + #: Device supports TCP Segmentation Offload with UDP. + UDP_TSO = auto() + #: Device supports TCP Segmentation Offload with VXLAN tunnels. + VXLAN_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with GRE tunnels. + GRE_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with IPIP tunnels. + IPIP_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with IP tunnels. + IP_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with GENEVE tunnels. + GENEVE_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with UDP tunnels. + UDP_TNL_TSO = auto() + #: + MACSEC_INSERT = auto() + #: + MT_LOCKFREE = auto() + #: + MULTI_SEGS = auto() + #: + MBUF_FAST_FREE = auto() + + @dataclass -class RxOffloadCapabilities(TextParser): - """The result of testpmd's ``show port <port_id> rx_offload capabilities`` command.""" +class OffloadCapabilities(TextParser): + """The result of testpmd's ``show port <port_id> rx/tx_offload capabilities`` command.""" + + #: + port_id: int = field(metadata=TextParser.find_int(r"Offloading Capabilities of port (\d+) :")) + #: Per-queue offload capabilities. + per_queue: RxOffloadCapability | TxOffloadCapability + #: Capabilities other than per-queue offload capabilities. + per_port: RxOffloadCapability | TxOffloadCapability + + +@dataclass +class RxOffloadCapabilities(OffloadCapabilities): + """Extends :class:`OffloadCapabilities` with Rx specific functionality.""" #: - port_id: int = field( - metadata=TextParser.find_int(r"Rx Offloading Capabilities of port (\d+) :") - ) - #: Per-queue Rx offload capabilities. per_queue: RxOffloadCapability = field(metadata=RxOffloadCapability.make_parser(False)) - #: Capabilities other than per-queue Rx offload capabilities. + #: per_port: RxOffloadCapability = field(metadata=RxOffloadCapability.make_parser(True)) +@dataclass +class TxOffloadCapabilities(OffloadCapabilities): + """Extends :class:`OffloadCapabilities` with Tx specific functionality.""" + + #: + per_queue: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(False)) + #: + per_port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True)) + + T = TypeVarTuple("T") # type: ignore[misc] @@ -1501,6 +1564,32 @@ def show_port_stats(self, port_id: int) -> TestPmdPortStats: return TestPmdPortStats.parse(output) + def show_port_rx_offload_capabilities(self, port_id: int) -> RxOffloadCapabilities: + """Query the offloading capabilities of a given Rx port. + + Args: + port_id: The ID of the port to query. + + Returns: + Offloading capabilities of the port whose ID matches `port_id`. + """ + command = f"show port {port_id} rx_offload capabilities" + offload_capabilities_out = self.send_command(command) + return RxOffloadCapabilities.parse(offload_capabilities_out) + + def show_port_tx_offload_capabilities(self, port_id: int) -> TxOffloadCapabilities: + """Query the offloading capabilities of a given Tx port. + + Args: + port_id: The ID of the port to query. + + Returns: + Offloading capabilities of the port whose ID matches `port_id`. + """ + command = f"show port {port_id} tx_offload capabilities" + offload_capabilities_out = self.send_command(command) + return TxOffloadCapabilities.parse(offload_capabilities_out) + def _stop_port(self, port_id: int, verify: bool = True) -> None: """Stop port with `port_id` in testpmd. @@ -1856,27 +1945,52 @@ def _close(self) -> None: ====== Capability retrieval methods ====== """ - def get_capabilities_rx_offload( - self, - supported_capabilities: MutableSet["NicCapability"], - unsupported_capabilities: MutableSet["NicCapability"], - ) -> None: - """Get all rx offload capabilities and divide them into supported and unsupported. + @staticmethod + def get_offload_capabilities_func( + is_rx: bool, + ) -> Callable[["TestPmdShell", MutableSet["NicCapability"], MutableSet["NicCapability"]], None]: + """High-order function that returns a method for gathering Rx/Tx offload capabilities. Args: - supported_capabilities: Supported capabilities will be added to this set. - unsupported_capabilities: Unsupported capabilities will be added to this set. + is_rx: If :data:`True` the method that is returned will gather Rx capabilities. If + :data:`False` the returned method will return Tx capabilities. + + Returns: + A method for gathering Rx/Tx offload capabilities that meets the required structure. """ - self._logger.debug("Getting rx offload capabilities.") - command = f"show port {self.ports[0].id} rx_offload capabilities" - rx_offload_capabilities_out = self.send_command(command) - rx_offload_capabilities = RxOffloadCapabilities.parse(rx_offload_capabilities_out) - self._update_capabilities_from_flag( - supported_capabilities, - unsupported_capabilities, - RxOffloadCapability, - rx_offload_capabilities.per_port | rx_offload_capabilities.per_queue, - ) + + def get_capabilities( + self: "TestPmdShell", + supported_capabilities: MutableSet["NicCapability"], + unsupported_capabilities: MutableSet["NicCapability"], + ) -> None: + """Get all rx/tx offload capabilities and divide them into supported and unsupported. + + Args: + self: The shell to get the capabilities from. + supported_capabilities: Supported capabilities will be added to this set. + unsupported_capabilities: Unsupported capabilities will be added to this set. + """ + capabilities_class = RxOffloadCapability if is_rx else TxOffloadCapability + offload_type = "RX" if is_rx else "TX" + offload_capabilities_func = ( + self.show_port_rx_offload_capabilities + if is_rx + else self.show_port_tx_offload_capabilities + ) + offload_capabilities = offload_capabilities_func(self.ports[0].id) + # Cast to the generic type for mypy + per_port = cast(OffloadCapability, offload_capabilities.per_port) + per_queue = cast(OffloadCapability, offload_capabilities.per_queue) + self._update_capabilities_from_flag( + supported_capabilities, + unsupported_capabilities, + capabilities_class, + per_port | per_queue, + prefix=f"{offload_type}_OFFLOAD_", + ) + + return get_capabilities def _update_capabilities_from_flag( self, @@ -1884,13 +1998,14 @@ def _update_capabilities_from_flag( unsupported_capabilities: MutableSet["NicCapability"], flag_class: type[Flag], supported_flags: Flag, + prefix: str = "", ) -> None: """Divide all flags from `flag_class` into supported and unsupported.""" for flag in flag_class: if flag in supported_flags: - supported_capabilities.add(NicCapability[str(flag.name)]) + supported_capabilities.add(NicCapability[f"{prefix}{flag.name}"]) else: - unsupported_capabilities.add(NicCapability[str(flag.name)]) + unsupported_capabilities.add(NicCapability[f"{prefix}{flag.name}"]) def get_capabilities_rxq_info( self, @@ -1983,83 +2098,167 @@ class NicCapability(NoAliasEnum): ) #: RX_OFFLOAD_VLAN_STRIP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L3 checksum offload. RX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. RX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. RX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports Large Receive Offload. RX_OFFLOAD_TCP_LRO: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports QinQ (queue in queue) offload. RX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports inner packet L3 checksum. RX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports MACsec. RX_OFFLOAD_MACSEC_STRIP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports filtering of a VLAN Tag identifier. RX_OFFLOAD_VLAN_FILTER: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports VLAN offload. RX_OFFLOAD_VLAN_EXTEND: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports receiving segmented mbufs. RX_OFFLOAD_SCATTER: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports Timestamp. RX_OFFLOAD_TIMESTAMP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports crypto processing while packet is received in NIC. RX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports CRC stripping. RX_OFFLOAD_KEEP_CRC: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. RX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports inner packet L4 checksum. RX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports RSS hashing. RX_OFFLOAD_RSS_HASH: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports scatter Rx packets to segmented mbufs. RX_OFFLOAD_BUFFER_SPLIT: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports all checksum capabilities. RX_OFFLOAD_CHECKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports all VLAN capabilities. RX_OFFLOAD_VLAN: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L3 checksum offload. + TX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports L4 checksum offload. + TX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports L4 checksum offload. + TX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports inner packet L3 checksum. + TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports crypto processing while packet is received in NIC. + TX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_VLAN_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_QINQ_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports QinQ (queue in queue) stripping offload. + TX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload. + TX_OFFLOAD_TCP_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with UDP. + TX_OFFLOAD_UDP_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with VXLAN tunnels. + TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with GRE tunnels. + TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with IPIP tunnels. + TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with IP tunnels. + TX_OFFLOAD_IP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with GENEVE tunnels. + TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with UDP tunnels. + TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MACSEC_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MT_LOCKFREE: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MULTI_SEGS: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports Rx queue setup after device started. RUNTIME_RX_QUEUE_SETUP: TestPmdShellCapabilityMethod = partial( -- 2.46.0