Add support for setting Mac address, set flow control,
VF mode in the testpmd shell.

Signed-off-by: Thomas Wilks <thomas.wi...@arm.com>
Reviewed-by: Paul Szczepanek <paul.szczepa...@arm.com>
---
 dts/framework/remote_session/testpmd_shell.py | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/dts/framework/remote_session/testpmd_shell.py 
b/dts/framework/remote_session/testpmd_shell.py
index d187eaea94..14a7fae281 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -1932,6 +1932,78 @@ def set_vlan_filter(self, port: int, enable: bool, 
verify: bool = True) -> None:
                     filter on port {port}"""
                 )
 
+    def set_mac_address(self, port: int, mac_address: str):
+        """Sets Mac Address
+
+        Args:
+            port (int): Port Id
+            mac_address (str): MAC Address to be set
+        """
+        self.send_command(f"mac_addr set {port} {mac_address}")
+
+    def set_flow_control(
+        self,
+        port: int,
+        rx: bool = True,
+        tx: bool = True,
+        high_water: int = 0,
+        low_water: int = 0,
+        pause_time: int = 0,
+        send_xon: bool = False,
+        mac_ctrl_frame_fwd: bool = False,
+        autoneg: bool = False,
+    ):
+        """Set Flow Control.
+
+        Args:
+            rx (bool): Enable Reactive Extensions
+            tx (bool): Enable Transmit
+            high_water (int): High threshold value to trigger XOFF,
+            low_water (int): Low threshold value to trigger XON.
+            pause_time (int): Pause quota in the Pause frame.
+            send_xon (bool): Send XON frame.
+            mac_ctrl_frame_fwd (bool): Enable receiving MAC control frames.
+            autoneg (bool): _description_
+            port (int): Change the auto-negotiation parameter.
+        """
+
+        self.send_command(
+            f"set flow_ctrl rx {'on' if rx else 'off'} tx {'on' if tx else 
'off'} {high_water} {low_water} {pause_time} {1 if send_xon else 0} 
mac_ctrl_frame_fwd {'on' if mac_ctrl_frame_fwd else 'off'} autoneg {'on' if 
autoneg else 'off'} {port}"
+        )
+
+    def show_port_flow_info(self, port: int):
+        """Show port info flow
+
+        Args:
+            port (int): port id
+
+        Returns:
+            str: port flow control config
+        """
+        output = self.send_command(f"show port {port} flow_ctrl")
+        output = TestPmdPortFlowCtrl.parse(output)
+        return output
+
+    def set_port_VF_mode(self, port: int, vf_id: int, rxmode: str, enable: 
bool):
+        """Set VF receive mode of a port
+
+        Args:
+            port (int): Port id
+            vf_id (int): Virtual Function id
+            rxmode (str):  AUPE Accepts untagged VLAN.
+                           ROPE Accepts unicast hash.
+                           BAM Accepts broadcast packets.
+                           MPE Accepts all multicast packets.
+            enable (bool): Enables vf mode
+        """
+        rxmode_valid = ["AUPE", "ROPE", "BAM", "MPE"]
+        if rxmode in rxmode_valid:
+            self.send_command(
+                f"set port {port} vf {vf_id} rxmode {rxmode} {'on' if enable 
else 'off'}"
+            )
+        else:
+            raise InteractiveCommandExecutionError(f"{rxmode} is an invlaid 
rxmode")
+
     def rx_vlan(self, vlan: int, port: int, add: bool, verify: bool = True) -> 
None:
         """Add specified vlan tag to the filter list on a port. Requires vlan 
filter to be on.
 
@@ -2315,6 +2387,50 @@ def get_capabilities_mcast_filtering(
             command = str.replace(command, "add", "remove", 1)
             self.send_command(command)
 
+    def get_capabilities_flow_ctrl(
+        self,
+        supported_capabilities: MutableSet["NicCapability"],
+        unsupported_capabilities: MutableSet["NicCapability"],
+    ) -> None:
+        """Get Flow control capability from `show port <port_id> flow_ctrl` 
and check for a testpmd error code
+
+        Args:
+            supported_capabilities: Supported capabilities will be added to 
this set.
+            unsupported_capabilities: Unsupported capabilities will be added 
to this set.
+        """
+        self._logger.debug("Getting flow ctrl capabilities.")
+        command = f"show port {self.ports[0].id} flow_ctrl"
+        output = self.send_command(command)
+        if "Flow control infos" in output:
+            supported_capabilities.add(NicCapability.FLOW_CTRL)
+        else:
+            unsupported_capabilities.add(NicCapability.FLOW_CTRL)
+
+
+@dataclass
+class TestPmdPortFlowCtrl(TextParser):
+    """Dataclass representation of the common parts of the testpmd `show port 
<port_id> flow_ctrl` command."""
+
+    flow_ctrl_rx: bool = field(metadata=TextParser.find(r"Rx pause: on"))
+    #:
+    flow_ctrl_tx: bool = field(metadata=TextParser.find(r"Tx pause: on"))
+    #:
+    flow_ctrl_high_water: int = field(
+        metadata=TextParser.find_int(r"High waterline: (0x[a-fA-F\d]+)")
+    )
+    #:
+    flow_ctrl_low_water: int = field(
+        metadata=TextParser.find_int(r"Low waterline: (0x[a-fA-F\d]+)")
+    )
+    #:
+    flow_ctrl_pause_time: int = field(metadata=TextParser.find_int(r"Pause 
time: (0x[a-fA-F\d]+)"))
+    #:
+    flow_ctrl_send_xon: bool = field(metadata=TextParser.find(r"Tx pause: on"))
+    #:
+    flow_ctrl_mac_ctrl_frame_fwd: bool = field(metadata=TextParser.find(r"Tx 
pause: on"))
+    #:
+    flow_ctrl_autoneg: bool = field(metadata=TextParser.find(r"Autoneg: on"))
+
 
 class NicCapability(NoAliasEnum):
     """A mapping between capability names and the associated 
:class:`TestPmdShell` methods.
@@ -2450,6 +2566,10 @@ class NicCapability(NoAliasEnum):
     MCAST_FILTERING: TestPmdShellCapabilityMethod = functools.partial(
         TestPmdShell.get_capabilities_mcast_filtering
     )
+    #: Device supports flow ctrl.
+    FLOW_CTRL: TestPmdShellCapabilityMethod = functools.partial(
+        TestPmdShell.get_capabilities_flow_ctrl
+    )
 
     def __call__(
         self,
-- 
2.43.0

Reply via email to