From f05218047efc07893b7636b988ad7dff63e04959 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Fri, 3 Nov 2023 17:59:23 +0100 Subject: [PATCH 01/15] fix(anlt hlfunc): Fix ANLT DO issue when AN=ON LT=OFF ANLT DO doesn't send PP_AUTONEG DISABLE when AN=ON and LT=OFF Reference Issue Numbers: #216 --- xoa_driver/functions/anlt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xoa_driver/functions/anlt.py b/xoa_driver/functions/anlt.py index b6f3a309..b4d62981 100644 --- a/xoa_driver/functions/anlt.py +++ b/xoa_driver/functions/anlt.py @@ -111,9 +111,9 @@ def __builder__(self) -> t.Generator[Token, None, None]: ) # yield self.__pp_autoneg(self.should_do_an and not self.should_do_lt) - if (not self.should_do_an) or self.should_do_lt: - # Disable autoneg - yield self.__pp_autoneg(False) + # if (not self.should_do_an) or self.should_do_lt: + # Disable autoneg + yield self.__pp_autoneg(False) if self.should_do_lt: for serdes_str, algorithm in self.lt_algorithm.items(): From 7b1a5600835dbfbdd6a6c8602e05cc6458925c21 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Fri, 3 Nov 2023 17:59:56 +0100 Subject: [PATCH 02/15] Update version number to 2.2.4 --- xoa_driver/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xoa_driver/__init__.py b/xoa_driver/__init__.py index 7f256c11..3341708e 100644 --- a/xoa_driver/__init__.py +++ b/xoa_driver/__init__.py @@ -1,2 +1,2 @@ -__version__ = "2.2.3" +__version__ = "2.2.4" __short_version__ = "2.0" From e3764777fb0c2f95df10413f0852d039e42e5b1b Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Fri, 3 Nov 2023 20:03:52 +0100 Subject: [PATCH 03/15] Add anlt auto-restart 1. when link down detected 2. when LT failure --- xoa_driver/__init__.py | 2 +- xoa_driver/functions/anlt.py | 24 +++++++++++++----------- xoa_driver/functions/tools.py | 3 ++- xoa_driver/internals/commands/enums.py | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/xoa_driver/__init__.py b/xoa_driver/__init__.py index 3341708e..91db4c00 100644 --- a/xoa_driver/__init__.py +++ b/xoa_driver/__init__.py @@ -1,2 +1,2 @@ -__version__ = "2.2.4" +__version__ = "2.3.0" __short_version__ = "2.0" diff --git a/xoa_driver/functions/anlt.py b/xoa_driver/functions/anlt.py index b4d62981..95781e4d 100644 --- a/xoa_driver/functions/anlt.py +++ b/xoa_driver/functions/anlt.py @@ -460,31 +460,33 @@ async def txtap_set( ) -async def anlt_link_recovery(port: GenericL23Port, enable: bool) -> None: +async def anlt_link_recovery(port: GenericL23Port, restart_link_down: bool, restart_lt_failure: bool) -> None: """ - .. versionadded:: 1.1 - - Should xenaserver automatically do link recovery when detecting down signal. + This command manages the auto-restart features. :param port: the port object :type port: :class:`~xoa_driver.ports.GenericL23Port` - :param enable: should the port automatically do link recovery when link is down. - :type enable: bool + :param restart_link_down: enable AN+LT auto-restart when a link down condition is detected. A "link down" state signifies the loss of a valid input signal, which can occur due to events such as cable unplugging and re-plugging, TX disable, or link flap on the link partner's end. The auto-restart process will continue until the link is re-established. Please note that this setting is only effective when AN and/or LT are enabled. + :type restart_link_down: bool + :param restart_lt_failure: if LT is enabled and experiences a failure on either side, the port will initiate the AN+LT restart process repeatedly until LT succeeds. This functionality is only applicable when LT is enabled. + :type restart_lt_failure: bool :return: :rtype: None """ conn, mid, pid = get_ctx(port) + param = 0 + if restart_link_down == True: + param += 1 + if restart_lt_failure == True: + param += 2 cmd_ = commands.PL1_CFG_TMP( - conn, mid, pid, 0, enums.Layer1ConfigType.ANLT_INTERACTIVE + conn, mid, pid, 0, enums.Layer1ConfigType.AUTO_LINK_RECOVERY ) - param = enums.OnOff.ON if enable else enums.OnOff.OFF await cmd_.set(values=[param]) async def anlt_status(port: GenericL23Port) -> dict[str, t.Any]: """ - .. versionadded:: 1.1 - Get the overview of ANLT status :param port: the port object @@ -498,7 +500,7 @@ async def anlt_status(port: GenericL23Port) -> dict[str, t.Any]: conn, mid, pid = get_ctx(port) r = await apply( commands.PL1_CFG_TMP( - conn, mid, pid, 0, enums.Layer1ConfigType.ANLT_INTERACTIVE + conn, mid, pid, 0, enums.Layer1ConfigType.AUTO_LINK_RECOVERY ).get(), commands.PP_AUTONEGSTATUS(conn, mid, pid).get(), commands.PP_LINKTRAIN(conn, mid, pid).get(), diff --git a/xoa_driver/functions/tools.py b/xoa_driver/functions/tools.py index 6139ca03..7340fc4c 100644 --- a/xoa_driver/functions/tools.py +++ b/xoa_driver/functions/tools.py @@ -139,7 +139,8 @@ def dictionize_anlt_status( "autoneg_enabled": enums.AutoNegMode(autoneg.mode).name.lower().lstrip("aneg_"), "link_training_mode": enums.LinkTrainingMode(linktrain.mode).name.lower(), "link_training_timeout": enums.TimeoutMode(linktrain.timeout_mode).name.lower(), - "link_recovery": "on" if link_recovery.values[0] == 1 else "off", + "restart_link_down": "on" if link_recovery.values[0] == 1 or link_recovery.values[0] == 3 else "off", + "restart_lt_fail": "on" if link_recovery.values[0] == 2 or link_recovery.values[0] == 3 else "off", "serdes_count": capabilities.serdes_count, "autoneg_allow_loopback": allow_loopback.values, "link_training_preset0": enums.NRZPreset(linktrain.nrz_preset).name.lower(), diff --git a/xoa_driver/internals/commands/enums.py b/xoa_driver/internals/commands/enums.py index 869e62f5..24d79c22 100644 --- a/xoa_driver/internals/commands/enums.py +++ b/xoa_driver/internals/commands/enums.py @@ -2186,8 +2186,8 @@ class Layer1ConfigType(IntEnum): Enums for PL1_CFG_TMP's type. """ - ANLT_INTERACTIVE = 0 - """ANLT Interactive mode config""" + AUTO_LINK_RECOVERY = 0 + """ANLT Auto Link Recovery""" AN_LOOPBACK = 1 """Auto-negotiation loopback config""" From 9fc2c8506c9bc98a74b52f5e6c644512cc117216 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sun, 5 Nov 2023 17:06:05 +0100 Subject: [PATCH 04/15] Remove versionadded --- docs/source/api_ref/hlapiv1/index.rst | 2 -- docs/source/getting_started/quick_start.rst | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/source/api_ref/hlapiv1/index.rst b/docs/source/api_ref/hlapiv1/index.rst index e10a3325..aa0a7daa 100644 --- a/docs/source/api_ref/hlapiv1/index.rst +++ b/docs/source/api_ref/hlapiv1/index.rst @@ -1,8 +1,6 @@ 🚀 High-Level API ======================== -.. versionadded:: 1.1 - HL-API uses the classes defined in LL-API and lets you quickly develop scripts or program in an **object-oriented** fashion with explicit definition of commands of different *tester*, *module*, *port* types. In addition, the HL-API layer provides functionalities such as: * :ref:`Auto connection keep-alive ` diff --git a/docs/source/getting_started/quick_start.rst b/docs/source/getting_started/quick_start.rst index dc68db6f..88da92f8 100644 --- a/docs/source/getting_started/quick_start.rst +++ b/docs/source/getting_started/quick_start.rst @@ -96,8 +96,6 @@ At last, release the ports (It is absolutely OK if you don't release them.) Integrate with CLI and ValkyrieManager -------------------------------------- -.. versionadded:: 2.1.1 - The simple code example demonstrates how to use XOA Python API : * Establish connection to a Valkyrie tester. From ea4ed91b08abe58804d9cfe01cd4ea8703f419ab Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Mon, 6 Nov 2023 23:35:28 +0100 Subject: [PATCH 05/15] Add more PRBS polynomials to PRBSPattern --- xoa_driver/internals/commands/enums.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/xoa_driver/internals/commands/enums.py b/xoa_driver/internals/commands/enums.py index 24d79c22..e30cfdcc 100644 --- a/xoa_driver/internals/commands/enums.py +++ b/xoa_driver/internals/commands/enums.py @@ -1248,6 +1248,16 @@ class PRBSPattern(IntEnum): """PRBS-23""" PRBS31 = 5 """PRBS-31""" + PRBS58 = 6 + """PRBS-58""" + PRBS49 = 7 + """PRBS-49""" + PRBS10 = 8 + """PRBS-10""" + PRBS20 = 9 + """PRBS-20""" + PRBS13 = 10 + """PRBS-13""" class PHYSignalStatus(IntEnum): From e9a91ee5f06b888d1ab8637aaeda96f626933c4e Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Mon, 6 Nov 2023 23:36:18 +0100 Subject: [PATCH 06/15] Fix HL-API ref errors --- .../api_ref/hlapiv1/module/identification.rst | 2 +- docs/source/api_ref/hlapiv1/module/tls.rst | 4 ++ .../api_ref/hlapiv1/port/identification.rst | 39 +------------------ .../source/api_ref/hlapiv1/port/multicast.rst | 4 +- .../hlapiv1/port/pcs_pma/rx_status.rst | 2 +- .../source/api_ref/hlapiv1/stream/content.rst | 1 - .../hlapiv1/stream/modifier/modifier.rst | 8 ++-- .../hlapiv1/stream/modifier/modifier_ext.rst | 8 ++-- 8 files changed, 17 insertions(+), 51 deletions(-) diff --git a/docs/source/api_ref/hlapiv1/module/identification.rst b/docs/source/api_ref/hlapiv1/module/identification.rst index 9f65dbe0..6f00f788 100644 --- a/docs/source/api_ref/hlapiv1/module/identification.rst +++ b/docs/source/api_ref/hlapiv1/module/identification.rst @@ -22,7 +22,7 @@ Legacy Model .. code-block:: python - await module.mode.get() + await module.model.get() Model ------------- diff --git a/docs/source/api_ref/hlapiv1/module/tls.rst b/docs/source/api_ref/hlapiv1/module/tls.rst index 22487d6b..0816f342 100644 --- a/docs/source/api_ref/hlapiv1/module/tls.rst +++ b/docs/source/api_ref/hlapiv1/module/tls.rst @@ -1,6 +1,10 @@ TLS Cipher ========================= +.. note:: + + For Vulcan module only. + .. code-block:: python await module.tls_cipher.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/identification.rst b/docs/source/api_ref/hlapiv1/port/identification.rst index eef5b7b6..73098420 100644 --- a/docs/source/api_ref/hlapiv1/port/identification.rst +++ b/docs/source/api_ref/hlapiv1/port/identification.rst @@ -19,47 +19,10 @@ Description await port.comment.set(comment="description") await port.comment.get() -Legacy Model ------------- - -.. code-block:: python - - await module.mode.get() - -Model -------------- - -.. code-block:: python - - await module.revision.get() - - -Serial Number ------------------ - -.. code-block:: python - - await module.serial_number.get() - - -Firmware Version ------------------ - -.. code-block:: python - - await module.version_number.get() - - -Port Count ------------- - -.. code-block:: python - - await module.port_count.get() Status ------ .. code-block:: python - await module.status.get() \ No newline at end of file + await port.status.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/multicast.rst b/docs/source/api_ref/hlapiv1/port/multicast.rst index 1b7286d7..98fa8450 100644 --- a/docs/source/api_ref/hlapiv1/port/multicast.rst +++ b/docs/source/api_ref/hlapiv1/port/multicast.rst @@ -27,8 +27,8 @@ Source List .. code-block:: python - await port.multicast.source_list..set() - await port.multicast.source_list..get() + await port.multicast.source_list.set() + await port.multicast.source_list.get() Header diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst index 91e6a054..37ac8af4 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst @@ -33,7 +33,7 @@ Clear Counters await port.pcs_pma.rx.clear.set() -RX FEX Stats +RX FEC Stats --------------- .. code-block:: python diff --git a/docs/source/api_ref/hlapiv1/stream/content.rst b/docs/source/api_ref/hlapiv1/stream/content.rst index 6a57a8b1..27004aef 100644 --- a/docs/source/api_ref/hlapiv1/stream/content.rst +++ b/docs/source/api_ref/hlapiv1/stream/content.rst @@ -20,7 +20,6 @@ Packet Auto Size .. code-block:: python await stream.packet.auto_adjust.set() - await stream.packet.auto_adjust.get() Payload Type diff --git a/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst b/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst index 1a7958a7..d6abeb37 100644 --- a/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst +++ b/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst @@ -37,8 +37,8 @@ Range .. code-block:: python - modifier.range.set() - modifier.range.get() + await modifier.range.set() + await modifier.range.get() Position, Action, Mask @@ -46,5 +46,5 @@ Position, Action, Mask .. code-block:: python - modifier.specification.set() - modifier.specification.get() \ No newline at end of file + await modifier.specification.set() + await modifier.specification.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst b/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst index fa264982..61024f3e 100644 --- a/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst +++ b/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst @@ -37,8 +37,8 @@ Range .. code-block:: python - modifier_ext.range.set() - modifier_ext.range.get() + await modifier_ext.range.set() + await modifier_ext.range.get() Position, Action, Mask @@ -46,5 +46,5 @@ Position, Action, Mask .. code-block:: python - modifier_ext.specification.set() - modifier_ext.specification.get() \ No newline at end of file + await modifier_ext.specification.set() + await modifier_ext.specification.get() \ No newline at end of file From 14552c5d3158816f24578aa90138b36ca17c06d4 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Mon, 6 Nov 2023 23:36:37 +0100 Subject: [PATCH 07/15] Add HL-API summary --- docs/source/api_ref/hlapiv1/index.rst | 1 + docs/source/api_ref/hlapiv1/summary.py | 2924 +++++++++++++++++ docs/source/api_ref/hlapiv1/summary.rst | 14 + .../understand_xoa_python/hlapi_guide.rst | 2 + 4 files changed, 2941 insertions(+) create mode 100644 docs/source/api_ref/hlapiv1/summary.py create mode 100644 docs/source/api_ref/hlapiv1/summary.rst diff --git a/docs/source/api_ref/hlapiv1/index.rst b/docs/source/api_ref/hlapiv1/index.rst index aa0a7daa..6e71a781 100644 --- a/docs/source/api_ref/hlapiv1/index.rst +++ b/docs/source/api_ref/hlapiv1/index.rst @@ -21,6 +21,7 @@ The HL-API (V1) are categorized into: .. toctree:: + summary tester/index module/index port/index diff --git a/docs/source/api_ref/hlapiv1/summary.py b/docs/source/api_ref/hlapiv1/summary.py new file mode 100644 index 00000000..e545525a --- /dev/null +++ b/docs/source/api_ref/hlapiv1/summary.py @@ -0,0 +1,2924 @@ +import asyncio + +from xoa_driver import testers +from xoa_driver import modules +from xoa_driver import ports +from xoa_driver import enums +from xoa_driver import utils +from xoa_driver import misc +from xoa_driver.hlfuncs import mgmt +from xoa_driver.misc import Hex +from xoa_driver.lli import commands +import ipaddress + + +async def my_awesome_func(stop_event: asyncio.Event): + +# region Tester + ################################################# + # Tester # + ################################################# + tester = await testers.L23Tester( + host="10.10.10.10", + username="my_name", + password="xena", + enable_logging=False) + + # Shutdown/Restart + await tester.down.set(operation=enums.ChassisShutdownAction.POWER_OFF) + await tester.down.set_poweroff() + await tester.down.set(operation=enums.ChassisShutdownAction.RESTART) + await tester.down.set_restart() + + # Flash + await tester.flash.set(on_off=enums.OnOff.OFF) + await tester.flash.set_off() + await tester.flash.set(on_off=enums.OnOff.ON) + await tester.flash.set_on() + + resp = await tester.flash.get() + resp.on_off + + # Debug Log + resp = await tester.debug_log.get() + resp.data + resp.message_length + + # IP Address + await tester.management_interface.ip_address.set( + ipv4_address=ipaddress.IPv4Address("10.10.10.10"), + subnet_mask=ipaddress.IPv4Address("255.255.255.0"), + gateway=ipaddress.IPv4Address("10.10.10.1")) + + resp = await tester.management_interface.ip_address.get() + resp.ipv4_address + resp.subnet_mask + resp.gateway + + # MAC Address + resp = await tester.management_interface.macaddress.get() + resp.mac_address + + # Hostname + await tester.management_interface.hostname.set(hostname="name") + + resp = await tester.management_interface.hostname.get() + resp.hostname + + # DHCP + await tester.management_interface.dhcp.set(on_off=enums.OnOff.ON) + await tester.management_interface.dhcp.set_on() + await tester.management_interface.dhcp.set(on_off=enums.OnOff.OFF) + await tester.management_interface.dhcp.set_off() + + resp = await tester.management_interface.dhcp.get() + resp.on_off + + # Capabilities + resp = await tester.capabilities.get() + resp.version + resp.max_name_len + resp.max_comment_len + resp.max_password_len + resp.max_ext_rate + resp.max_session_count + resp.max_chain_depth + resp.max_module_count + resp.max_protocol_count + resp.can_stream_based_arp + resp.can_sync_traffic_start + resp.can_read_log_files + resp.can_par_module_upgrade + resp.can_upgrade_timekeeper + resp.can_custom_defaults + resp.max_owner_name_length + resp.can_read_temperatures + resp.can_latency_f2f + + # Name + await tester.name.set(chassis_name="name") + + resp = await tester.name.get() + resp.chassis_name + + # Password + await tester.password.set(password="xena") + + resp = await tester.password.get() + resp.password + + # Description + await tester.comment.set(comment="description") + + resp = await tester.comment.get() + resp.comment + + # Model + resp = await tester.model.get() + resp.model + + # Serial Number + resp = await tester.serial_no.get() + resp.serial_number + + # Firmware Version + resp = await tester.version_no.get() + resp.chassis_major_version + resp.pci_driver_version + + resp = await tester.version_no_minor.get() + resp.chassis_minor_version + resp.reserved_1 + resp.reserved_2 + + # Build String + resp = await tester.build_string.get() + resp.build_string + + # Reservation + await tester.reservation.set(operation=enums.ReservedAction.RELEASE) + await tester.reservation.set_release() + await tester.reservation.set(operation=enums.ReservedAction.RELINQUISH) + await tester.reservation.set_relinquish() + await tester.reservation.set(operation=enums.ReservedAction.RESERVE) + await tester.reservation.set_reserve() + + resp = await tester.reservation.get() + resp.operation + + # Reserved By + resp = await tester.reserved_by.get() + resp.username + + # Information + # The following are pre-fetched in cache when connection is established, thus no need to use await + + tester.session.owner_name + tester.session.keepalive + tester.session.pwd + tester.session.is_online + tester.session.sessions_info + tester.session.timeout + tester.is_released() + tester.is_reserved_by_me() + + # Logoff + await tester.session.logoff() + + # Time + resp = await tester.time.get() + resp.local_time + + # TimeKeeper Configuration + await tester.time_keeper.config_file.set(config_file="filename") + + resp = await tester.time_keeper.config_file.get() + resp.config_file + + # TimeKeeper GPS State + resp = await tester.time_keeper.gps_state.get() + resp.status + + # TimeKeeper License File + await tester.time_keeper.license_file.set(license_content="") + + resp = await tester.time_keeper.license_file.get() + resp.license_content + + # TimeKeeper License State + resp = await tester.time_keeper.license_state.get() + resp.license_errors + resp.license_file_state + resp.license_type + + # TimeKeeper Status + resp = await tester.time_keeper.status.get() + resp.status_string + + resp = await tester.time_keeper.status_extended.get() + resp.status_string + + # Chassis Traffic + await tester.traffic.set(on_off=enums.OnOff.ON, module_ports=[0,0,0,1]) + await tester.traffic.set(on_off=enums.OnOff.OFF, module_ports=[0,0,0,1]) + await tester.traffic.set_on(module_ports=[0,0,0,1]) + await tester.traffic.set_off(module_ports=[0,0,0,1]) + + # Synchronized Chassis Traffic + await tester.traffic_sync.set(on_off=enums.OnOff.ON, timestamp=1234567, module_ports=[0,0,0,1]) + await tester.traffic_sync.set(on_off=enums.OnOff.OFF, timestamp=1234567, module_ports=[0,0,0,1]) + await tester.traffic_sync.set_on(timestamp=1234567, module_ports=[0,0,0,1]) + await tester.traffic_sync.set_off(timestamp=1234567, module_ports=[0,0,0,1]) + +# endregion + +# region Module + ################################################# + # Module # + ################################################# + + # Access module index 0 on the tester + module = tester.modules.obtain(0) + + # Capabilities + resp = await module.capabilities.get() + resp.can_advanced_timing + resp.can_local_time_adjust + resp.can_media_config + resp.can_ppm_sweep + resp.can_tsn + resp.is_chimera + resp.max_clock_ppm + + # Name + resp = await module.name.get() + resp.name + + # Description + await module.comment.set(comment="description") + + resp = await module.comment.get() + resp.comment + + # Legacy Model + resp = await module.model.get() + resp.model + + # Model + resp = await module.revision.get() + resp.revision + + # Serial Number + resp = await module.serial_number.get() + resp.serial_number + + # Firmware Version + resp = await module.version_number.get() + resp.version + + # Port Count + resp = await module.port_count.get() + resp.port_count + + # Status + resp = await module.status.get() + resp.temperature + + # Media Configuration + await module.media.set(media_config=enums.MediaConfigurationType.BASE_T1) + await module.media.set(media_config=enums.MediaConfigurationType.BASE_T1S) + await module.media.set(media_config=enums.MediaConfigurationType.CFP) + await module.media.set(media_config=enums.MediaConfigurationType.CFP4) + await module.media.set(media_config=enums.MediaConfigurationType.CXP) + await module.media.set(media_config=enums.MediaConfigurationType.OSFP800) + await module.media.set(media_config=enums.MediaConfigurationType.OSFP800_ANLT) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP112) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP112_ANLT) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP28_NRZ) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP28_PAM4) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP56_PAM4) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD_NRZ) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD_PAM4) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD800) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD800_ANLT) + await module.media.set(media_config=enums.MediaConfigurationType.SFP112) + await module.media.set(media_config=enums.MediaConfigurationType.SFP28) + await module.media.set(media_config=enums.MediaConfigurationType.SFP56) + await module.media.set(media_config=enums.MediaConfigurationType.SFPDD) + + resp = await module.media.get() + resp.media_config + + # Supported Media + resp = await module.available_speeds.get() + resp.media_info_list + + # Port Configuration + await module.cfp.config.set(portspeed_list=[1, 800000]) + await module.cfp.config.set(portspeed_list=[2, 400000, 400000]) + await module.cfp.config.set(portspeed_list=[4, 200000, 200000, 200000, 200000]) + await module.cfp.config.set(portspeed_list=[8, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000]) + + resp = await module.cfp.config.get() + resp.portspeed_list + + # Reservation + await module.reservation.set(operation=enums.ReservedAction.RELEASE) + await module.reservation.set_release() + await module.reservation.set(operation=enums.ReservedAction.RELINQUISH) + await module.reservation.set_relinquish() + await module.reservation.set(operation=enums.ReservedAction.RESERVE) + await module.reservation.set_reserve() + + resp = await module.reservation.get() + resp.operation + + # Reserved By + resp = await module.reserved_by.get() + resp.username + + # TX Clock Filter Loop Bandwidth + if not isinstance(module, modules.ModuleChimera): + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW103HZ) + await module.advanced_timing.clock_tx.filter.set_bw103hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW1683HZ) + await module.advanced_timing.clock_tx.filter.set_bw1683hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW207HZ) + await module.advanced_timing.clock_tx.filter.set_bw207hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW416HZ) + await module.advanced_timing.clock_tx.filter.set_bw416hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW7019HZ) + await module.advanced_timing.clock_tx.filter.set_bw7019hz() + + resp = await module.advanced_timing.clock_tx.filter.get() + resp.filter_bandwidth + + # TX Clock Source + if not isinstance(module, modules.ModuleChimera): + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.MODULELOCALCLOCK) + await module.advanced_timing.clock_tx.source.set_modulelocalclock() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P0RXCLK) + await module.advanced_timing.clock_tx.source.set_p0rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P1RXCLK) + await module.advanced_timing.clock_tx.source.set_p1rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P2RXCLK) + await module.advanced_timing.clock_tx.source.set_p2rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P3RXCLK) + await module.advanced_timing.clock_tx.source.set_p3rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P4RXCLK) + await module.advanced_timing.clock_tx.source.set_p4rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P5RXCLK) + await module.advanced_timing.clock_tx.source.set_p5rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P6RXCLK) + await module.advanced_timing.clock_tx.source.set_p6rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P7RXCLK) + await module.advanced_timing.clock_tx.source.set_p7rxclk() + + resp = await module.advanced_timing.clock_tx.source.get() + resp.tx_clock + + # TX Clock Status + if not isinstance(module, modules.ModuleChimera): + resp = await module.advanced_timing.clock_tx.status.get() + resp.status + + # SMA Status + if not isinstance(module, modules.ModuleChimera): + resp = await module.advanced_timing.sma.status.get() + resp.status + + # SMA Input + if not isinstance(module, modules.ModuleChimera): + await module.advanced_timing.sma.input.set(sma_in=enums.SMAInputFunction.NOT_USED) + await module.advanced_timing.sma.input.set_notused() + await module.advanced_timing.sma.input.set(sma_in=enums.SMAInputFunction.TX10MHZ) + await module.advanced_timing.sma.input.set_tx10mhz() + await module.advanced_timing.sma.input.set(sma_in=enums.SMAInputFunction.TX2MHZ) + await module.advanced_timing.sma.input.set_tx2mhz() + + resp = await module.advanced_timing.sma.input.get() + resp.sma_in + + # SMA Output + if not isinstance(module, modules.ModuleChimera): + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.DISABLED) + await module.advanced_timing.sma.output.set_disabled() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P0RXCLK) + await module.advanced_timing.sma.output.set_p0rxclk() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P0RXCLK2MHZ) + await module.advanced_timing.sma.output.set_p0rxclk2mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P0SOF) + await module.advanced_timing.sma.output.set_p0sof() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P1RXCLK) + await module.advanced_timing.sma.output.set_p1rxclk() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P1RXCLK2MHZ) + await module.advanced_timing.sma.output.set_p1rxclk2mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P1SOF) + await module.advanced_timing.sma.output.set_p1sof() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.PASSTHROUGH) + await module.advanced_timing.sma.output.set_passthrough() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF10MHZ) + await module.advanced_timing.sma.output.set_ref10mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF125MHZ) + await module.advanced_timing.sma.output.set_ref125mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF156MHZ) + await module.advanced_timing.sma.output.set_ref156mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF2MHZ) + await module.advanced_timing.sma.output.set_ref2mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.TS_PPS) + await module.advanced_timing.sma.output.set_ts_pps() + + resp = await module.advanced_timing.sma.output.get() + resp.sma_out + + # Local Clock Adjust + await module.timing.clock_local_adjust.set(ppb=10) + + resp = await module.timing.clock_local_adjust.get() + resp.ppb + + # Clock Sync Status + resp = await module.timing.clock_sync_status.get() + resp.m_clock_diff + resp.m_correction + resp.m_is_steady_state + resp.m_tune_is_increase + resp.m_tune_value + + # Clock Source + await module.timing.source.set(source=enums.TimingSource.CHASSIS) + await module.timing.source.set_chassis() + await module.timing.source.set(source=enums.TimingSource.EXTERNAL) + await module.timing.source.set_external() + await module.timing.source.set(source=enums.TimingSource.MODULE) + await module.timing.source.set_module() + + resp = await module.timing.source.get() + resp.source + + # Clock PPM Sweep Configuration + FREYA_MODULES = (modules.MFreya800G4S1P_a, modules.MFreya800G4S1P_b, modules.MFreya800G4S1POSFP_a, modules.MFreya800G4S1POSFP_b) + if isinstance(module, FREYA_MODULES): + await module.clock_sweep.config.set(mode=enums.PPMSweepMode.OFF, ppb_step=10, step_delay=10, max_ppb=10, loops=1) + await module.clock_sweep.config.set(mode=enums.PPMSweepMode.TRIANGLE, ppb_step=10, step_delay=10, max_ppb=10, loops=1) + + resp = await module.clock_sweep.config.get() + resp.mode + resp.ppb_step + resp.step_delay + resp.max_ppb + resp.loops + + # Clock PPM Sweep Status + if isinstance(module, FREYA_MODULES): + resp = await module.clock_sweep.status.get() + resp.curr_step + resp.curr_sweep + resp.max_steps + + + # Chimera - Bypass Mode + if isinstance(module, modules.ModuleChimera): + await module.emulator_bypass_mode.set(on_off=enums.OnOff.ON) + await module.emulator_bypass_mode.set_on() + await module.emulator_bypass_mode.set(on_off=enums.OnOff.OFF) + await module.emulator_bypass_mode.set_off() + + resp = await module.emulator_bypass_mode.get() + resp.on_off + + # Chimera - Latency Mode + if isinstance(module, modules.ModuleChimera): + await module.latency_mode.set(mode=enums.ImpairmentLatencyMode.NORMAL) + await module.latency_mode.set_normal() + await module.latency_mode.set(mode=enums.ImpairmentLatencyMode.EXTENDED) + await module.latency_mode.set_extended() + + resp = await module.latency_mode.get() + resp.mode + + # Chimera - TX Clock Source + if isinstance(module, modules.ModuleChimera): + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.MODULELOCALCLOCK) + await module.tx_clock.source.set_modulelocalclock() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P0RXCLK) + await module.tx_clock.source.set_p0rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P1RXCLK) + await module.tx_clock.source.set_p1rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P2RXCLK) + await module.tx_clock.source.set_p2rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P3RXCLK) + await module.tx_clock.source.set_p3rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P4RXCLK) + await module.tx_clock.source.set_p4rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P5RXCLK) + await module.tx_clock.source.set_p5rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P6RXCLK) + await module.tx_clock.source.set_p6rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P7RXCLK) + await module.tx_clock.source.set_p7rxclk() + + resp = await module.tx_clock.source.get() + resp.tx_clock + + # Chimera - TX Clock Status + if isinstance(module, modules.ModuleChimera): + resp = await module.tx_clock.status.get() + resp.status +# endregion + +# region Port + ################################################# + # Port # + ################################################# + + port = module.ports.obtain(0) + + # Reset + await port.reset.set() + + if isinstance(port, ports.PortChimera): + return + + # Flash + await port.flash.set(on_off=enums.OnOff.ON) + await port.flash.set_on() + await port.flash.set(on_off=enums.OnOff.OFF) + await port.flash.set_off() + + resp = await port.flash.get() + resp.on_off + + + # MAC Address + await port.net_config.mac_address.set(mac_address=Hex("000000000000")) + + resp = await port.net_config.mac_address.get() + resp.mac_address + + # IPv4 Address + await port.net_config.ipv4.address.set( + ipv4_address=ipaddress.IPv4Address("10.10.10.10"), + subnet_mask=ipaddress.IPv4Address("255.255.255.0"), + gateway=ipaddress.IPv4Address("10.10.1.1"), + wild=ipaddress.IPv4Address("0.0.0.0")) + + resp = await port.net_config.ipv4.address.get() + resp.ipv4_address + resp.gateway + resp.subnet_mask + resp.wild + + # ARP Reply + await port.net_config.ipv4.arp_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv4.arp_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv4.arp_reply.get() + resp.on_off + + # Ping Reply + await port.net_config.ipv4.ping_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv4.ping_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv4.ping_reply.get() + resp.on_off + + # IPv6 Address + await port.net_config.ipv6.address.set( + ipv6_address=ipaddress.IPv6Address("fc00::0002"), + gateway=ipaddress.IPv6Address("fc00::0001"), + subnet_prefix=7, + wildcard_prefix=0 + ) + + resp = await port.net_config.ipv6.address.get() + resp.ipv6_address + resp.gateway + resp.subnet_prefix + resp.wildcard_prefix + + # NDP Reply + await port.net_config.ipv6.arp_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv6.arp_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv6.arp_reply.get() + resp.on_off + + # IPv6 Ping Reply + await port.net_config.ipv6.ping_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv6.ping_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv6.ping_reply.get() + resp.on_off + + # ARP Table, https://github.com/xenanetworks/open-automation-script-library/tree/main/ip_streams_arp_table + await port.arp_rx_table.set(chunks=[]) + + resp = await port.arp_rx_table.get() + resp.chunks + + # NDP Table, https://github.com/xenanetworks/open-automation-script-library/tree/main/ip_streams_arp_table + await port.ndp_rx_table.set(chunks=[]) + + resp = await port.ndp_rx_table.get() + resp.chunks + + # Capture Trigger Criteria, https://github.com/xenanetworks/open-automation-script-library/blob/main/packet_capture/packet_capture.py + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.ON, start_criteria_filter=0, stop_criteria=enums.StopTrigger.FULL, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.ON, start_criteria_filter=0, stop_criteria=enums.StopTrigger.USERSTOP, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.FCSERR, start_criteria_filter=0, stop_criteria=enums.StopTrigger.FCSERR, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.PLDERR, start_criteria_filter=0, stop_criteria=enums.StopTrigger.PLDERR, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.FILTER, start_criteria_filter=0, stop_criteria=enums.StopTrigger.FILTER, stop_criteria_filter=0) + + resp = await port.capturer.trigger.get() + resp.start_criteria + resp.start_criteria_filter + resp.stop_criteria + resp.stop_criteria_filter + + # Capture - Frame to Keep, https://github.com/xenanetworks/open-automation-script-library/blob/main/packet_capture/packet_capture.py + await port.capturer.keep.set(kind=enums.PacketType.ALL, index=0, byte_count=0) + await port.capturer.keep.set_all() + await port.capturer.keep.set(kind=enums.PacketType.FCSERR, index=0, byte_count=0) + await port.capturer.keep.set_fcserr() + await port.capturer.keep.set(kind=enums.PacketType.FILTER, index=0, byte_count=0) + await port.capturer.keep.set_filter() + await port.capturer.keep.set(kind=enums.PacketType.NOTPLD, index=0, byte_count=0) + await port.capturer.keep.set_notpld() + await port.capturer.keep.set(kind=enums.PacketType.PLDERR, index=0, byte_count=0) + await port.capturer.keep.set_plderr() + await port.capturer.keep.set(kind=enums.PacketType.TPLD, index=0, byte_count=0) + await port.capturer.keep.set_tpld() + + resp = await port.capturer.keep.get() + resp.kind + resp.index + resp.byte_count + + # Capture - State + await port.capturer.state.set(on_off=enums.StartOrStop.START) + await port.capturer.state.set_start() + await port.capturer.state.set(on_off=enums.StartOrStop.STOP) + await port.capturer.state.set_stop() + + resp = await port.capturer.state.get() + resp.on_off + + # Capture - Statistics + resp = await port.capturer.stats.get() + resp.start_time + resp.status + + # Read Captured Packets + pkts = await port.capturer.obtain_captured() + for i in range(len(pkts)): + resp = await pkts[i].packet.get() + print(f"Packet content # {i}: {resp.hex_data}") + + # Inter-frame Gap + await port.interframe_gap.set(min_byte_count=20) + + resp = await port.interframe_gap.get() + resp.min_byte_count + + # PAUSE Frames + await port.pause.set(on_off=enums.OnOff.ON) + await port.pause.set_on() + await port.pause.set(on_off=enums.OnOff.OFF) + await port.pause.set_off() + + resp = await port.pause.get() + resp.on_off + + # Auto-Train + await port.autotrain.set(interval=1) + + resp = await port.autotrain.get() + resp.interval + + # Gap Monitor + await port.gap_monitor.set(start=100, stop=10) + + resp = await port.gap_monitor.get() + resp.start + resp.stop + + # Priority Flow Control + await port.pfc_enable.set( + cos_0=enums.OnOff.ON, + cos_1=enums.OnOff.OFF, + cos_2=enums.OnOff.ON, + cos_3=enums.OnOff.OFF, + cos_4=enums.OnOff.ON, + cos_5=enums.OnOff.OFF, + cos_6=enums.OnOff.ON, + cos_7=enums.OnOff.OFF, + ) + + resp = await port.pfc_enable.get() + resp.cos_0 + resp.cos_1 + resp.cos_2 + resp.cos_3 + resp.cos_4 + resp.cos_5 + resp.cos_6 + resp.cos_7 + + # Loopback + await port.loop_back.set(mode=enums.LoopbackMode.L1RX2TX) + await port.loop_back.set_l1rx2tx() + await port.loop_back.set(mode=enums.LoopbackMode.L2RX2TX) + await port.loop_back.set_l2rx2tx() + await port.loop_back.set(mode=enums.LoopbackMode.L3RX2TX) + await port.loop_back.set_l3rx2tx() + await port.loop_back.set(mode=enums.LoopbackMode.NONE) + await port.loop_back.set_none() + await port.loop_back.set(mode=enums.LoopbackMode.PORT2PORT) + await port.loop_back.set_port2port() + await port.loop_back.set(mode=enums.LoopbackMode.TXOFF2RX) + await port.loop_back.set_txoff2rx() + await port.loop_back.set(mode=enums.LoopbackMode.TXON2RX) + await port.loop_back.set_txon2rx() + + resp = await port.loop_back.get() + resp.mode + + # BRR Mode + await port.brr_mode.set(mode=enums.BRRMode.MASTER) + await port.brr_mode.set_master() + await port.brr_mode.set(mode=enums.BRRMode.SLAVE) + await port.brr_mode.set_slave() + + resp = await port.brr_mode.get() + resp.mode + + # MDI/MDIX Mode + await port.mdix_mode.set(mode=enums.MDIXMode.AUTO) + await port.mdix_mode.set_auto() + await port.mdix_mode.set(mode=enums.MDIXMode.MDI) + await port.mdix_mode.set_mdi() + await port.mdix_mode.set(mode=enums.MDIXMode.MDIX) + await port.mdix_mode.set_mdix() + + resp = await port.mdix_mode.get() + resp.mode + + # EEE- Capabilities + resp = await port.eee.capabilities.get() + resp.eee_capabilities + + # EEE - Partner Capabilities + resp = await port.eee.partner_capabilities.get() + resp.cap_1000base_t + resp.cap_100base_kx + resp.cap_10gbase_kr + resp.cap_10gbase_kx4 + resp.cap_10gbase_t + + # EEE - Control + await port.eee.enable.set(on_off=enums.OnOff.OFF) + await port.eee.enable.set_off() + await port.eee.enable.set(on_off=enums.OnOff.ON) + await port.eee.enable.set_on() + + resp = await port.eee.enable.get() + resp.on_off + + # EEE - Low Power TX Mode + await port.eee.mode.set(on_off=enums.OnOff.ON) + await port.eee.mode.set_off() + await port.eee.mode.set(on_off=enums.OnOff.OFF) + await port.eee.mode.set_on() + + resp = await port.eee.mode.get() + resp.on_off + + # EEE - RX Power + resp = await port.eee.rx_power.get() + resp.channel_a + resp.channel_b + resp.channel_c + resp.channel_d + + # EEE - SNR Margin + resp = await port.eee.snr_margin.get() + resp.channel_a + resp.channel_b + resp.channel_c + resp.channel_d + + # EEE - Status + resp = await port.eee.status.get() + resp.link_up + resp.rxc + resp.rxh + resp.txc + resp.txh + + # Fault - Signaling + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.DISABLED) + await port.fault.signaling.set_disabled() + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.FORCE_LOCAL) + await port.fault.signaling.set_force_local() + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.FORCE_REMOTE) + await port.fault.signaling.set_force_remote() + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.NORMAL) + await port.fault.signaling.set_normal() + + resp = await port.fault.signaling.get() + resp.fault_signaling + + # Fault - Status + resp = await port.fault.status.get() + resp.local_fault_status + resp.remote_fault_status + + # Interface + resp = await port.interface.get() + resp.interface + + # Description + await port.comment.set(comment="description") + + resp = await port.comment.get() + resp.comment + + # Status + resp = await port.status.get() + resp.optical_power + + # Latency Mode + if not isinstance(port, ports.PortChimera): + await port.latency_config.mode.set(mode=enums.LatencyMode.FIRST2FIRST) + await port.latency_config.mode.set_first2first() + await port.latency_config.mode.set(mode=enums.LatencyMode.FIRST2LAST) + await port.latency_config.mode.set_first2last() + await port.latency_config.mode.set(mode=enums.LatencyMode.LAST2FIRST) + await port.latency_config.mode.set_last2first() + await port.latency_config.mode.set(mode=enums.LatencyMode.LAST2LAST) + await port.latency_config.mode.set_last2last() + + resp = await port.latency_config.mode.get() + resp.mode + + # Latency Offset + if not isinstance(port, ports.PortChimera): + await port.latency_config.offset.set(offset=5) + + resp = await port.latency_config.offset.get() + resp.offset + + # Link Flap - Control + await port.pcs_pma.link_flap.enable.set(on_off=enums.OnOff.ON) + await port.pcs_pma.link_flap.enable.set_on() + await port.pcs_pma.link_flap.enable.set(on_off=enums.OnOff.OFF) + await port.pcs_pma.link_flap.enable.set_off() + + resp = await port.pcs_pma.link_flap.enable.get() + resp.on_off + + # Link Flap - Configuration + await port.pcs_pma.link_flap.params.set(duration=10, period=20, repetition=0) + + resp = await port.pcs_pma.link_flap.params.get() + resp.duration + resp.period + resp.repetition + + # Multicast Mode + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.JOIN, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.JOIN, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.LEAVE, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.OFF, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.ON, + second_count=10) + + resp = await port.multicast.mode.get() + resp.ipv4_multicast_addresses + resp.operation + resp.second_count + + # Multicast Extended Mode + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.EXCLUDE, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV3 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.INCLUDE, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV3 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.JOIN, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.LEAVE, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.LEAVE_TO_ALL, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.GENERAL_QUERY, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.GROUP_QUERY, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.ON, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.OFF, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + + resp = await port.multicast.mode_extended.get() + resp.ipv4_multicast_addresses + resp.operation + resp.second_count + resp.igmp_version + + # Multicast Source List + await port.multicast.source_list.set(ipv4_addresses=[]) + + resp = await port.multicast.source_list.get() + resp.ipv4_addresses + + + # Multicast Header + await port.multicast.header.set(header_count=1, header_format=enums.MulticastHeaderFormat.VLAN, tag=10, pcp=0, dei=0) + await port.multicast.header.set(header_count=0, header_format=enums.MulticastHeaderFormat.NOHDR, tag=10, pcp=0, dei=0) + + resp = await port.multicast.header.get() + resp.header_count + resp.header_format + resp.tag + resp.pcp + resp.dei + + # Random Seed + await port.random_seed.set(seed=1) + + resp = await port.random_seed.get() + resp.seed + + # Checksum Offset + await port.checksum.set(offset=14) + + resp = await port.checksum.get() + resp.offset + + # Maximum Header Length + await port.max_header_length.set(max_header_length=56) + + resp = await port.max_header_length.get() + resp.max_header_length + + # MIX Weights + await port.mix.weights.set( + weight_56_bytes:=0, + weight_60_bytes:=0, + weight_64_bytes:=70, + weight_70_bytes:=15, + weight_78_bytes:=15, + weight_92_bytes:=0, + weight_256_bytes:=0, + weight_496_bytes:=0, + weight_512_bytes:=0, + weight_570_bytes:=0, + weight_576_bytes:=0, + weight_594_bytes:=0, + weight_1438_bytes:=0, + weight_1518_bytes:=0, + weight_9216_bytes:=0, + weight_16360_bytes:=0) + + resp = await port.mix.weights.get() + resp.weight_56_bytes + resp.weight_60_bytes + resp.weight_64_bytes + resp.weight_70_bytes + resp.weight_78_bytes + resp.weight_92_bytes + resp.weight_256_bytes + resp.weight_496_bytes + resp.weight_512_bytes + resp.weight_570_bytes + resp.weight_576_bytes + resp.weight_594_bytes + resp.weight_1438_bytes + resp.weight_1518_bytes + resp.weight_9216_bytes + resp.weight_16360_bytes + + # MIX Lengths + await port.mix.lengths[0].set(frame_size=56) + await port.mix.lengths[1].set(frame_size=60) + await port.mix.lengths[14].set(frame_size=9216) + await port.mix.lengths[15].set(frame_size=16360) + + resp = await port.mix.lengths[0].get() + resp.frame_size + resp = await port.mix.lengths[1].get() + resp.frame_size + resp = await port.mix.lengths[14].get() + resp.frame_size + resp = await port.mix.lengths[15].get() + resp.frame_size + + # Payload Mode + await port.payload_mode.set(mode=enums.PayloadMode.NORMAL) + await port.payload_mode.set_normal() + await port.payload_mode.set(mode=enums.PayloadMode.EXTPL) + await port.payload_mode.set_extpl() + await port.payload_mode.set(mode=enums.PayloadMode.CDF) + await port.payload_mode.set_cdf() + + resp = await port.payload_mode.get() + resp.mode + + # RX Preamble Insert + await port.preamble.rx_insert.set(on_off=enums.OnOff.ON) + await port.preamble.rx_insert.set(on_off=enums.OnOff.OFF) + + resp = await port.preamble.rx_insert.get() + resp.on_off + + # TX Preamble Removal + await port.preamble.tx_remove.set(on_off=enums.OnOff.ON) + await port.preamble.tx_remove.set(on_off=enums.OnOff.OFF) + + resp = await port.preamble.tx_remove.get() + resp.on_off + + # Reservation + await port.reservation.set(operation=enums.ReservedAction.RELEASE) + await port.reservation.set_release() + await port.reservation.set(operation=enums.ReservedAction.RELINQUISH) + await port.reservation.set_relinquish() + await port.reservation.set(operation=enums.ReservedAction.RESERVE) + await port.reservation.set_reserve() + + resp = await port.reservation.get() + resp.status + + # Reserved By + resp = await port.reserved_by.get() + resp.username + + # Runt - RX Length + await port.runt.rx_length.set(runt_length=40) + + resp = await port.runt.rx_length.get() + resp.runt_length + + # Runt - TX Length + await port.runt.tx_length.set(runt_length=40) + + resp = await port.runt.tx_length.get() + resp.runt_length + + # Runt - Length Error + resp = await port.runt.has_length_errors.get() + resp.status + + # Speed Mode Selection + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.AUTO) + await port.speed.mode.selection.set_auto() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10M) + await port.speed.mode.selection.set_f10m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10M100M) + await port.speed.mode.selection.set_f10m100m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10MHDX) + await port.speed.mode.selection.set_f10mhdx() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M) + await port.speed.mode.selection.set_f100m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M1G) + await port.speed.mode.selection.set_f100m1g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M1G10G) + await port.speed.mode.selection.set_f100m1g10g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M1G2500M) + await port.speed.mode.selection.set_f100m1g2500m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100MHDX) + await port.speed.mode.selection.set_f100mhdx() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F1G) + await port.speed.mode.selection.set_f1g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F2500M) + await port.speed.mode.selection.set_f2500m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F5G) + await port.speed.mode.selection.set_f5g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10G) + await port.speed.mode.selection.set_f10g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F40G) + await port.speed.mode.selection.set_f40g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100G) + await port.speed.mode.selection.set_f100g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.UNKNOWN) + await port.speed.mode.selection.set_unknown() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F200G) + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F400G) + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F800G) + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F1600G) + + resp = await port.speed.mode.selection.get() + resp.mode + + # Supported Speed Modes + resp = await port.speed.mode.supported.get() + resp.auto + resp.f10M + resp.f100M + resp.f1G + resp.f10G + resp.f40G + resp.f100G + resp.f10MHDX + resp.f100MHDX + resp.f10M100M + resp.f100M1G + resp.f100M1G10G + resp.f2500M + resp.f5G + resp.f100M1G2500M + resp.f25G + resp.f50G + resp.f200G + resp.f400G + resp.f800G + resp.f1600G + + # Current Speed + resp = await port.speed.current.get() + resp.port_speed + + # Speed Reduction + await port.speed.reduction.set(ppm=100) + + resp = await port.speed.reduction.get() + resp.ppm + + # Sync Status + resp = await port.sync_status.get() + resp.sync_status == enums.SyncStatus.IN_SYNC + resp.sync_status == enums.SyncStatus.NO_SYNC + + # Transceiver Status + resp = await port.tcvr_status.get() + resp.rx_loss_lane_0 + resp.rx_loss_lane_1 + resp.rx_loss_lane_2 + resp.rx_loss_lane_3 + + # Transceiver Read & Write + await port.transceiver.access_rw(page_address=0, register_address=0).set(value=Hex("00")) + + resp = await port.transceiver.access_rw(page_address=0, register_address=0).get() + resp.value + + # Transceiver Sequential Read & Write + await port.transceiver.access_rw_seq(page_address=0, register_address=0, byte_count=4).set(value=Hex("00FF00FF")) + + resp = await port.transceiver.access_rw_seq(page_address=0, register_address=0, byte_count=4).get() + resp.value + + # Transceiver MII + await port.transceiver.access_mii(register_address=0).set(value=Hex("00")) + + resp = await port.transceiver.access_mii(register_address=0).get() + resp.value + + # Transceiver Temperature + resp = await port.transceiver.access_temperature().get() + resp.integral_part + resp.fractional_part + + # Transceiver RX Laser Power + resp = await port.pcs_pma.transceiver.rx_laser_power.get() + resp.nanowatts + + # Transceiver TX Laser Power + resp = await port.pcs_pma.transceiver.tx_laser_power.get() + resp.nanowatts + + # Traffic Control - Rate Percent + await port.rate.fraction.set(port_rate_ppm=1_000_000) + + resp = await port.rate.fraction.get() + resp.port_rate_ppm + + # Traffic Control - Rate L2 Bits Per Second + await port.rate.l2_bps.set(port_rate_bps=1_000_000) + + resp = await port.rate.l2_bps.get() + resp.port_rate_bps + + # Traffic Control - Rate Frames Per Second + await port.rate.pps.set(port_rate_pps=10_000) + + resp = await port.rate.pps.get() + resp.port_rate_pps + + # Traffic Control - Start and Stop + await port.traffic.state.set(on_off=enums.StartOrStop.START) + await port.traffic.state.set_start() + await port.traffic.state.set(on_off=enums.StartOrStop.STOP) + await port.traffic.state.set_stop() + + resp = await port.traffic.state.get() + resp.on_off + + # Traffic Control - Traffic Error + resp = await port.traffic.error.get() + resp.error + + # Traffic Control - Single Frame TX + await port.tx_single_pkt.send.set(hex_data=Hex("00000000000102030405060800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + + # Traffic Control - Single Frame Time + resp = await port.tx_single_pkt.time.get() + resp.nanoseconds + + # TPLD Mode + await port.tpld_mode.set(mode=enums.TPLDMode.NORMAL) + await port.tpld_mode.set_normal() + await port.tpld_mode.set(mode=enums.TPLDMode.MICRO) + await port.tpld_mode.set_micro() + + resp = await port.tpld_mode.get() + resp.mode + + # TX Mode + await port.tx_config.mode.set(mode=enums.TXMode.NORMAL) + await port.tx_config.mode.set_normal() + await port.tx_config.mode.set(mode=enums.TXMode.BURST) + await port.tx_config.mode.set_burst() + await port.tx_config.mode.set(mode=enums.TXMode.SEQUENTIAL) + await port.tx_config.mode.set_sequential() + await port.tx_config.mode.set(mode=enums.TXMode.STRICTUNIFORM) + await port.tx_config.mode.set_strictuniform() + + resp = await port.tx_config.mode.get() + resp.mode + + # Burst Period + await port.tx_config.burst_period.set(burst_period=100) + + resp = await port.tx_config.burst_period.get() + resp.burst_period + + # TX Delay + await port.tx_config.delay.set(delay_val=100) + + resp = await port.tx_config.delay.get() + resp.delay_val + + # TX Enable + await port.tx_config.enable.set(on_off=enums.OnOff.ON) + await port.tx_config.enable.set(on_off=enums.OnOff.OFF) + + resp = await port.tx_config.enable.get() + resp.on_off + + # Packet Limit + await port.tx_config.packet_limit.set(packet_count_limit=1_000_000) + + resp = await port.tx_config.packet_limit.get() + resp.packet_count_limit + + # Time Limit + await port.tx_config.time_limit.set(microseconds=1_000_000) + + resp = await port.tx_config.time_limit.get() + resp.microseconds + + # TX Time Elapsed + resp = await port.tx_config.time.get() + resp.microseconds + + # Prepare TX + await port.tx_config.prepare.set() + + # Dynamic Traffic Rate + await port.dynamic.set(on_off=enums.OnOff.OFF) + await port.dynamic.set_off() + await port.dynamic.set(on_off=enums.OnOff.ON) + await port.dynamic.set_on() + + resp = await port.dynamic.get() + resp.on_off + + ################################################# + # Port Filter # + ################################################# + + # Create and Obtain + # Create a filter on the port, and obtain the filter object. The filter index is automatically assigned by the port. + filter = await port.filters.create() + + # Obtain One or Multiple + filter = port.filters.obtain(position_idx=0) + filter_list = port.filters.obtain_multiple(*[0,1,2]) + + # Remove + # Remove a filter on the port with an explicit filter index by the index manager of the port. + await port.filters.remove(position_idx=0) + + # Filter - Enable + await filter.enable.set(on_off=enums.OnOff.ON) + await filter.enable.set_on() + await filter.enable.set(on_off=enums.OnOff.OFF) + await filter.enable.set_off() + + resp = await filter.enable.get() + resp.on_off + + # Filter - Description + await filter.comment.set(comment="this is a comment") + + resp = await filter.comment.get() + resp.comment + + # Filter - Condition + await filter.condition.set(and_expression_0=0, and_not_expression_0=0, and_expression_1=1, and_not_expression_1=0, and_expression_2=0, and_expression_3=0) + + resp = await filter.condition.get() + resp.and_expression_0 + resp.and_not_expression_0 + resp.and_expression_1 + resp.and_not_expression_1 + resp.and_expression_2 + resp.and_expression_3 + + # Filter - String Representation + await filter.string.set(string_name="this is name") + + resp = await filter.string.get() + resp.string_name + + ################################################# + # Port Length Term # + ################################################# + + # Create and Obtain + # Create a length term on the port, and obtain the length term object. The length term index is automatically assigned by the port. + length_term = await port.length_terms.create() + + # Obtain One or Multiple + length_term = port.length_terms.obtain(key=0) + length_term_list = port.length_terms.obtain_multiple(*[0,1,2]) + + # Remove + # Remove a length term on the port with an explicit length term index by the index manager of the port. + await port.length_terms.remove(position_idx=0) + + ################################################# + # Port Match Term # + ################################################# + + # Create and Obtain + # Create a match term on the port, and obtain the match term object. The match term index is automatically assigned by the port. + match_term = await port.match_terms.create() + + # Obtain One or Multiple + length_term = port.match_terms.obtain(key=0) + length_term_list = port.match_terms.obtain_multiple(*[0,1,2]) + + # Remove + # Remove a match term on the port with an explicit match term index by the index manager of the port. + await port.match_terms.remove(position_idx=0) + + ################################################# + # Port Histogram # + ################################################# + + # Create and Obtain + # Create a histogram on the port, and obtain the histogram object. The histogram index is automatically assigned by the port. + dataset = await port.datasets.create() + + # Obtain One or Multiple + length_term = port.datasets.obtain(key=0) + length_term_list = port.datasets.obtain_multiple(*[0,1,2]) + + # Remove + # Remove a histogram on the port with an explicit histogram index by the index manager of the port. + await port.datasets.remove(position_idx=0) + + ################################################# + # Port PCS/PMA # + ################################################# + + # Auto-Negotiation Settings + resp = await port.pcs_pma.auto_neg.settings.get() + resp.tec_ability + resp.fec_capable + resp.fec_requested + resp.pause_mode + + # Auto-Negotiation Status + resp = await port.pcs_pma.auto_neg.status.get() + resp.mode + resp.auto_state + resp.tec_ability + resp.fec_capable + resp.fec_requested + resp.fec + resp.pause_mode + + # Auto-Negotiation Selection + # Only applicable to RJ45 ports + await port.autoneg_selection.set(on_off=enums.OnOff.ON) + await port.autoneg_selection.set_on() + await port.autoneg_selection.set(on_off=enums.OnOff.OFF) + await port.autoneg_selection.set_off() + + resp = await port.autoneg_selection.get() + resp.on_off + + # FEC Mode + await port.pcs_pma.phy.auto_neg.set(fec_mode=enums.OnOff.ON,reserved_1=0, reserved_2=0, reserved_3=0, reserved_4=0) + + await port.fec_mode.set(mode=enums.FECMode.RS_FEC) + await port.fec_mode.set(mode=enums.FECMode.RS_FEC_KP) + await port.fec_mode.set(mode=enums.FECMode.RS_FEC_KR) + await port.fec_mode.set(mode=enums.FECMode.FC_FEC) + await port.fec_mode.set(mode=enums.FECMode.OFF) + await port.fec_mode.set(mode=enums.FECMode.ON) + + resp = await port.fec_mode.get() + resp.mode + + # Link Training Settings + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.DISABLED, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DEFAULT) + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.STANDALONE, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DEFAULT) + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.INTERACTIVE, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DISABLED) + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.START_AFTER_AUTONEG, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DEFAULT) + + resp = await port.pcs_pma.link_training.settings.get() + resp.mode + resp.pam4_frame_size + resp.nrz_pam4_init_cond + resp.nrz_preset + resp.timeout_mode + + # Link Training Serdes Status + resp = await port.pcs_pma.link_training.per_lane_status[0].get() + resp.mode + resp.failure + resp.status + + # PMA Pulse Error Inject Control + await port.pcs_pma.pma_pulse_err_inj.enable.set(on_off=enums.OnOff.ON) + await port.pcs_pma.pma_pulse_err_inj.enable.set_on() + await port.pcs_pma.pma_pulse_err_inj.enable.set(on_off=enums.OnOff.OFF) + await port.pcs_pma.pma_pulse_err_inj.enable.set_off() + + resp = await port.pcs_pma.pma_pulse_err_inj.enable.get() + resp.on_off + + # PMA Pulse Error Inject Configuration + await port.pcs_pma.pma_pulse_err_inj.params.set(duration=1000, period=1000, repetition=10, coeff=5, exp=-5) + + resp = await port.pcs_pma.pma_pulse_err_inj.params.get() + resp.duration + resp.period + resp.coeff + resp.exp + + # RX Status - Lane Error Counters + resp = await port.pcs_pma.lanes[0].rx_status.errors.get() + resp.alignment_error_count + resp.corrected_fec_error_count + resp.header_error_count + + # RX Status - Lock Status + resp = await port.pcs_pma.lanes[0].rx_status.lock.get() + resp.align_lock + resp.header_lock + + # RX Status - Lane Status + resp = await port.pcs_pma.lanes[0].rx_status.status.get() + resp.skew + resp.virtual_lane + + # RX Status - Clear Counters + await port.pcs_pma.rx.clear.set() + + # RX Status - RX FEC Stats + resp = await port.pcs_pma.rx.fec_status.get() + resp.stats_type + resp.value_count + resp.correction_stats + resp.rx_uncorrectable_code_word_count + + # RX Status - RX Total Stats + resp = await port.pcs_pma.rx.total_status.get() + resp.total_corrected_codeword_count + resp.total_corrected_symbol_count + resp.total_post_fec_ber + resp.total_pre_fec_ber + resp.total_rx_bit_count + resp.total_rx_codeword_count + resp.total_uncorrectable_codeword_count + + # TX Configuration - Error Counters + resp = await port.pcs_pma.alarms.errors.get() + resp.total_alarms + resp.los_error_count + resp.total_align_error_count + resp.total_bip_error_count + resp.total_fec_error_count + resp.total_header_error_count + resp.total_higher_error_count + resp.total_pcs_error_count + resp.valid_mask + + # TX Configuration - Error Generation Rate + resp = await port.pcs_pma.error_gen.error_rate.get() + resp.rate + + # TX Configuration - Error Generation Inject + await port.pcs_pma.error_gen.inject_one.set() + + # TX Configuration - Error Injection + await port.pcs_pma.lanes[0].tx_error_inject.set_alignerror() + await port.pcs_pma.lanes[0].tx_error_inject.set_bip8error() + await port.pcs_pma.lanes[0].tx_error_inject.set_headererror() + + # TX Configuration - Lane Configuration + await port.pcs_pma.lanes[0].tx_config.set(virt_lane_index=1, skew=10) + + resp = await port.pcs_pma.lanes[0].tx_config.get() + resp.virt_lane_index + resp.skew + + ################################################# + # Port Medium # + ################################################# + + # Eye Diagram Information + resp = await port.serdes[0].eye_diagram.info.get() + resp.width_mui + resp.height_mv + resp.h_slope_left + resp.h_slope_right + resp.y_intercept_left + resp.y_intercept_right + resp.r_squared_fit_left + resp.r_squared_fit_right + resp.est_rj_rms_left + resp.est_rj_rms_right + resp.est_dj_pp + resp.v_slope_bottom + resp.v_slope_top + resp.x_intercept_bottom + resp.x_intercept_top + resp.r_squared_fit_bottom + resp.r_squared_fit_top + resp.est_rj_rms_bottom + resp.est_rj_rms_top + + # Eye Diagram Bit Error Rate + resp = await port.serdes[0].eye_diagram.ber.get() + resp.eye_ber_estimation + + # Eye Diagram Dwell Bits + resp = await port.serdes[0].eye_diagram.dwell_bits.get() + resp.max_dwell_bit_count + resp.min_dwell_bit_count + + # Eye Diagram Measure + resp = await port.serdes[0].eye_diagram.measure.get() + resp.status + + # Eye Diagram Resolution + resp = await port.serdes[0].eye_diagram.resolution.get() + resp.x_resolution + resp.y_resolution + + # Eye Diagram Data Columns + resp = await port.serdes[0].eye_diagram.read_column[0].get() + resp.valid_column_count + resp.values + resp.x_resolution + resp.y_resolution + + # PHY - Signal Status + resp = await port.pcs_pma.phy.signal_status.get() + resp.phy_signal_status + + # PHY - Settings + await port.pcs_pma.phy.settings.set( + link_training_on_off=enums.OnOff.ON, + precode_on_off=enums.OnOffDefault.DEFAULT, + graycode_on_off=enums.OnOff.OFF, pam4_msb_lsb_swap=enums.OnOff.OFF) + + resp = await port.pcs_pma.phy.settings.get() + resp.link_training_on_off + resp.precode_on_off + resp.graycode_on_off + resp.pam4_msb_lsb_swap + + # TX Tap Autotune + await port.serdes[0].phy.autotune.set(on_off=enums.OnOff.ON) + await port.serdes[0].phy.autotune.set_on() + await port.serdes[0].phy.autotune.set(on_off=enums.OnOff.OFF) + await port.serdes[0].phy.autotune.set_off() + + resp = await port.serdes[0].phy.autotune.get() + resp.on_off + + # TX Tap Retune + await port.serdes[0].phy.retune.set(dummy=1) + + # TX Tap Configuration + await port.serdes[0].phy.tx_equalizer.set(pre2=0, pre1=0, main=86, post1=0, post2=0, post3=0) + resp = await port.serdes[0].phy.tx_equalizer.get() + resp.pre2 + resp.pre1 + resp.main + resp.post1 + resp.post2 + resp.post3 + + # RX Tap Configuration + await port.serdes[0].phy.rx_equalizer.set(auto=0, ctle=0, reserved=0) + + resp = await port.serdes[0].phy.rx_equalizer.get() + resp.auto + resp.ctle + + ################################################# + # Port PRBS # + ################################################# + + # PRBS Configuration + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS7, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.CAUI_VIRTUAL, + polynomial=enums.PRBSPolynomial.PRBS9, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.PERSECOND) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS10, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS11, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS13, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS15, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS20, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS23, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS31, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS49, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS58, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + + resp = await port.serdes[0].prbs.config.type.get() + resp.prbs_inserted_type + resp.polynomial + resp.invert + resp.statistics_mode + + # PRBS Statistics + resp = await port.serdes[0].prbs.status.get() + resp.byte_count + resp.error_count + resp.lock +# endregion + +# region Statistics + ################################################# + # Statistics # + ################################################# + + # Error Counter + resp = await port.errors_count.get() + resp.error_count + + # RX Statistics - Clear Counter + await port.statistics.rx.clear.set() + + # RX Statistics - Calibrate + await port.statistics.rx.calibrate.set() + + # RX Statistics - Total Counter + resp = await port.statistics.rx.total.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + + # RX Statistics - Non-TPLD Counter + resp = await port.statistics.rx.no_tpld.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + + # RX Statistics - PFC Counter + resp = await port.statistics.rx.pfc_stats.get() + resp.packet_count + resp.quanta_pri_0 + resp.quanta_pri_1 + resp.quanta_pri_2 + resp.quanta_pri_3 + resp.quanta_pri_4 + resp.quanta_pri_5 + resp.quanta_pri_6 + resp.quanta_pri_7 + + # RX Statistics - Extra Counter + resp = await port.statistics.rx.extra.get() + resp.fcs_error_count + resp.pause_frame_count + resp.gap_count + resp.gap_duration + resp.pause_frame_count + resp.rx_arp_reply_count + resp.rx_arp_request_count + resp.rx_ping_reply_count + resp.rx_ping_request_count + + # RX Statistics - Received TPLDs + await port.statistics.rx.obtain_available_tplds() + + # RX Statistics - TPLD - Error Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).errors.get() + resp.non_incre_payload_packet_count + resp.non_incre_seq_event_count + resp.swapped_seq_misorder_event_count + + # RX Statistics - TPLD - Latency Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).latency.get() + resp.avg_last_sec + resp.max_last_sec + resp.min_last_sec + resp.avg_val + resp.max_val + resp.min_val + + # RX Statistics - TPLD - Jitter Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).jitter.get() + resp.avg_last_sec + resp.max_last_sec + resp.min_last_sec + resp.avg_val + resp.max_val + resp.min_val + + # RX Statistics - TPLD - Traffic Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).traffic.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + + # RX Statistics - Filter Statistics + resp = await port.statistics.rx.obtain_filter_statistics(filter=0).get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + + # TX Statistics - Clear Counter + await port.statistics.tx.clear.set() + + # TX Statistics - Total Counter + resp = await port.statistics.tx.total.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + + # TX Statistics - Non-TPLD Counter + resp = await port.statistics.tx.no_tpld.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + + # TX Statistics - Extra Counter + resp = await port.statistics.tx.extra.get() + resp.tx_arp_req_count + + # TX Statistics - Stream Counter + resp = await port.statistics.tx.obtain_from_stream(stream=0).get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec +# endregion + +# region Stream + ################################################# + # Stream # + ################################################# + + # Create and Obtain + # Create a stream on the port, and obtain the stream object. The stream index is automatically assigned by the port. + stream = await port.streams.create() + + # Obtain One or Multiple + stream = port.streams.obtain(0) + stream_list = port.streams.obtain_multiple(*[0,1,2]) + + # Remove + # Remove a stream on the port with an explicit stream index. + await port.streams.remove(position_idx=0) + + # Description + await stream.comment.set(comment="description") + + resp = await stream.comment.get() + resp.comment + + # Test Payload ID + await stream.tpld_id.set(test_payload_identifier=0) + + resp = await stream.tpld_id.get() + resp.test_payload_identifier + + # State + await stream.enable.set(state=enums.OnOffWithSuppress.OFF) + await stream.enable.set_off() + await stream.enable.set(state=enums.OnOffWithSuppress.ON) + await stream.enable.set_on() + await stream.enable.set(state=enums.OnOffWithSuppress.SUPPRESS) + await stream.enable.set_suppress() + + resp = await stream.enable.get() + resp.state + + # Header Protocol Segment + await stream.packet.header.protocol.set(segments=[ + enums.ProtocolOption.ETHERNET, + enums.ProtocolOption.VLAN, + enums.ProtocolOption.IP, + enums.ProtocolOption.UDP, + ]) + + # ETHERNET = 1 + # """Ethernet II""" + # VLAN = 2 + # """VLAN""" + # ARP = 3 + # """Address Resolution Protocol""" + # IP = 4 + # """IPv4""" + # IPV6 = 5 + # """IPv6""" + # UDP = 6 + # """User Datagram Protocol (w/o checksum)""" + # TCP = 7 + # """Transmission Control Protocol (w/o checksum)""" + # LLC = 8 + # """Logic Link Control""" + # SNAP = 9 + # """Subnetwork Access Protocol""" + # GTP = 10 + # """GPRS Tunnelling Protocol""" + # ICMP = 11 + # """Internet Control Message Protocol""" + # RTP = 12 + # """Real-time Transport Protocol""" + # RTCP = 13 + # """RTP Control Protocol""" + # STP = 14 + # """Spanning Tree Protocol""" + # SCTP = 15 + # """Stream Control Transmission Protocol""" + # MACCTRL = 16 + # """MAC Control""" + # MPLS = 17 + # """Multiprotocol Label Switching""" + # PBBTAG = 18 + # """Provider Backbone Bridge tag""" + # FCOE = 19 + # """Fibre Channel over Ethernet""" + # FC = 20 + # """Fibre Channel""" + # FCOETAIL = 21 + # """Fibre Channel over Ethernet (tail)""" + # IGMPV3L0 = 22 + # """IGMPv3 Membership Query L=0""" + # IGMPV3L1 = 23 + # """IGMPv3 Membership Query L=1""" + # UDPCHECK = 24 + # """User Datagram Protocol (w/ checksum)""" + # IGMPV2 = 25 + # """Internet Group Management Protocol v2""" + # MPLS_TP_OAM = 26 + # """MPLS-TP, OAM Header""" + # GRE_NOCHECK = 27 + # """Generic Routing Encapsulation (w/o checksum)""" + # GRE_CHECK = 28 + # """Generic Routing Encapsulation (w/ checksum)""" + # TCPCHECK = 29 + # """Transmission Control Protocol (w/ checksum)""" + # GTPV1L0 = 30 + # """GTPv1 (no options), GPRS Tunneling Protocol v1""" + # GTPV1L1 = 31 + # """GTPv1 (w/ options), GPRS Tunneling Protocol v1""" + # GTPV2L0 = 32 + # """GTPv2 (no options), GPRS Tunneling Protocol v2""" + # GTPV2L1 = 33 + # """GTPv2 (w/ options), GPRS Tunneling Protocol v2""" + # IGMPV1 = 34 + # """Internet Group Management Protocol v1""" + # PWETHCTRL = 35 + # """PW Ethernet Control Word""" + # VXLAN = 36 + # """Virtual eXtensible LAN""" + # ETHERNET_8023 = 37 + # """Ethernet 802.3""" + # NVGRE = 38 + # """Generic Routing Encapsulation (Network Virtualization)""" + # DHCPV4 = 39 + # """Dynamic Host Configuration Protocol (IPv4)""" + # GENEVE = 40 + # """Generic Network Virtualization Encapsulation""" + + resp = await stream.packet.header.protocol.get() + resp.segments + + # Header Value + await stream.packet.header.data.set( + hex_data=Hex("00000000000004F4BC7FFE908100000008004500002A000000007F113BC400000000000000000000000000160000")) + + resp = await stream.packet.header.data.get() + resp.hex_data + + # Packet Size + await stream.packet.length.set(length_type=enums.LengthType.FIXED, min_val=64, max_val=64) + await stream.packet.length.set(length_type=enums.LengthType.INCREMENTING, min_val=64, max_val=1500) + await stream.packet.length.set(length_type=enums.LengthType.BUTTERFLY, min_val=64, max_val=1500) + await stream.packet.length.set(length_type=enums.LengthType.RANDOM, min_val=64, max_val=1500) + await stream.packet.length.set(length_type=enums.LengthType.MIX, min_val=64, max_val=64) + + resp = await stream.packet.length.get() + resp.length_type + resp.min_val + resp.max_val + + # Packet Auto Size + await stream.packet.auto_adjust.set() + + # Payload Type + # Pattern string in hex, min = 1 byte, max = 18 bytes + await stream.payload.content.set(payload_type=enums.PayloadType.PATTERN, hex_data=Hex("000102030405060708090A0B0C0D0E0FDEAD")) + await stream.payload.content.set(payload_type=enums.PayloadType.PATTERN, hex_data=Hex("F5")) + + # Patter string ignored for non-pattern types + await stream.payload.content.set(payload_type=enums.PayloadType.INC16, hex_data=Hex("F5")) + await stream.payload.content.set_inc_word("00") + await stream.payload.content.set(payload_type=enums.PayloadType.INC8, hex_data=Hex("F5")) + await stream.payload.content.set_inc_byte("00") + await stream.payload.content.set(payload_type=enums.PayloadType.DEC8, hex_data=Hex("F5")) + await stream.payload.content.set_dec_byte("00") + await stream.payload.content.set(payload_type=enums.PayloadType.DEC16, hex_data=Hex("F5")) + await stream.payload.content.set_dec_word("00") + await stream.payload.content.set(payload_type=enums.PayloadType.PRBS, hex_data=Hex("F5")) + await stream.payload.content.set_prbs("00") + await stream.payload.content.set(payload_type=enums.PayloadType.RANDOM, hex_data=Hex("F5")) + await stream.payload.content.set_random("00") + + resp = await stream.payload.content.get() + resp.hex_data + resp.payload_type + + # Extended Payload + # Use await port.payload_mode.set_extpl() to set the port's payload mode to Extended Payload. + await stream.payload.extended.set(hex_data=Hex("00110022FF")) + + resp = await stream.payload.extended.get() + resp.hex_data + + # Rate Fraction + await stream.rate.fraction.set(stream_rate_ppm=1_000_000) + + resp = await stream.rate.fraction.get() + resp.stream_rate_ppm + + # Packet Rate + await stream.rate.pps.set(stream_rate_pps=1_000) + + resp = await stream.rate.pps.get() + resp.stream_rate_pps + + # Bit Rate L2 + await stream.rate.l2bps.set(l2_bps=1_000_000) + + resp = await stream.rate.l2bps.get() + resp.l2_bps + + # Packet Limit + await stream.packet.limit.set(packet_count=1_000) + + resp = await stream.packet.limit.get() + resp.packet_count + + # Burst Size and Density + await stream.burst.burstiness.set(size=20, density=80) + + resp = await stream.burst.burstiness.get() + resp.size + resp.density + + # Inter Burst/Packet Gap + await stream.burst.gap.set(inter_packet_gap=30, inter_burst_gap=30) + + resp = await stream.burst.gap.get() + resp.inter_packet_gap + resp.inter_burst_gap + + # Priority Flow + await stream.priority_flow.set(cos=enums.PFCMode.ZERO) + await stream.priority_flow.set(cos=enums.PFCMode.ONE) + await stream.priority_flow.set(cos=enums.PFCMode.TWO) + await stream.priority_flow.set(cos=enums.PFCMode.THREE) + await stream.priority_flow.set(cos=enums.PFCMode.FOUR) + await stream.priority_flow.set(cos=enums.PFCMode.FIVE) + await stream.priority_flow.set(cos=enums.PFCMode.SIX) + await stream.priority_flow.set(cos=enums.PFCMode.SEVEN) + await stream.priority_flow.set(cos=enums.PFCMode.VLAN_PCP) + + resp = await stream.priority_flow.get() + resp.cos + + # IPv4 Gateway Address + await stream.gateway.ipv4.set(gateway=ipaddress.IPv4Address("10.10.10.1")) + + resp = await stream.gateway.ipv4.get() + resp.gateway + + # IPv6 Gateway Address + await stream.gateway.ipv6.set(gateway=ipaddress.IPv6Address("::0001")) + + resp = await stream.gateway.ipv6.get() + resp.gateway + + # ARP Resolve Peer Address + # You need to make sure either the port has a correct gateway or the stream has a correct destination IP address to ARP resolve the MAC address. + resp = await stream.request.arp.get() + resp.mac_address + + # PING Check IP Peer + # You need to make sure either the port has a correct gateway or the stream has a correct destination IP address to ping. + resp = await stream.request.ping.get() + resp.delay + resp.time_to_live + + # Custom Data Field + # Use await port.payload_mode.set_cdf() to set the port's payload mode to Custom Data Field. + + # Field Offset + await stream.cdf.offset.set(offset=1) + + resp = await stream.cdf.offset.get() + resp.offset + + # Byte Count + await stream.cdf.count.set(cdf_count=1) + + resp = await stream.cdf.count.get() + resp.cdf_count + + ################################################ + # Stream Modifier # + ################################################ + + # Create + await stream.packet.header.modifiers.configure(number=1) + + # Clear + await stream.packet.header.modifiers.clear() + + # Obtain + # Must create modifiers before obtain. + modifier = stream.packet.header.modifiers.obtain(idx=0) + + # Range + await modifier.range.set(min_val=0, step=10, max_val=9) + + resp = await modifier.range.get() + resp.min_val + resp.max_val + resp.step + + # Position, Action, Mask + await modifier.specification.set(position=0, mask=Hex("FFFF0000"), action=enums.ModifierAction.INC, repetition=1) + await modifier.specification.set(position=0, mask=Hex("FFFF0000"), action=enums.ModifierAction.DEC, repetition=1) + await modifier.specification.set(position=0, mask=Hex("FFFF0000"), action=enums.ModifierAction.RANDOM, repetition=1) + + resp = await modifier.specification.get() + resp.action + resp.mask + resp.position + resp.repetition + + # ################################################# + # # Stream 32-bit Modifier # + # ################################################# + + # Create + await stream.packet.header.modifiers_extended.configure(number=1) + + # Clear + await stream.packet.header.modifiers_extended.clear() + + # Obtain + # Must create modifiers before obtain. + modifier_ext = stream.packet.header.modifiers_extended.obtain(idx=0) + + # Range + await modifier_ext.range.set(min_val=0, step=1, max_val=100) + + resp = await modifier_ext.range.get() + resp.max_val + resp.min_val + resp.step + + # Position, Action, Mask + await modifier_ext.specification.set(position=0, mask=Hex("FFFFFFFF"), action=enums.ModifierAction.INC, repetition=1) + await modifier_ext.specification.set(position=0, mask=Hex("FFFFFFFF"), action=enums.ModifierAction.DEC, repetition=1) + await modifier_ext.specification.set(position=0, mask=Hex("FFFFFFFF"), action=enums.ModifierAction.RANDOM, repetition=1) + + resp = await modifier_ext.specification.get() + resp.action + resp.mask + resp.position + resp.repetition + + # ################################################# + # # Stream Error Control # + # ################################################# + + # Misorder Error Injection + await stream.inject_err.misorder.set() + + # Payload Integrity Error Injection + await stream.inject_err.payload_integrity.set() + + # Sequence Error Injection + await stream.inject_err.sequence.set() + + # Test Payload Error Injection + await stream.inject_err.test_payload.set() + + # Checksum Error Injection + await stream.inject_err.frame_checksum.set() + + # Insert Frame Checksum + await stream.insert_packets_checksum.set(on_off=enums.OnOff.ON) + await stream.insert_packets_checksum.set_on() + await stream.insert_packets_checksum.set(on_off=enums.OnOff.OFF) + await stream.insert_packets_checksum.set_off() + + resp = await stream.insert_packets_checksum.get() + resp.on_off +# endregion + +# region Network Emulation + ################################################# + # Network Emulation # + ################################################# + + # Configure Chimera port + if isinstance(module, modules.ModuleChimera): + port = module.ports.obtain(0) + + await port.pcs_pma.link_flap.params.set(duration=100, period=1000, repetition=0) + await port.pcs_pma.link_flap.enable.set_on() + await port.pcs_pma.link_flap.enable.set_off() + + await port.pcs_pma.pma_pulse_err_inj.params.set(duration=100, period=1000, repetition=0, coeff=100, exp=-4) + await port.pcs_pma.pma_pulse_err_inj.enable.set_on() + await port.pcs_pma.pma_pulse_err_inj.enable.set_off() + + # Enable impairment on the port. + await port.emulate.set_off() + await port.emulate.set_on() + + resp = await port.emulate.get() + resp.action + + # Set TPLD mode + await port.emulation.tpld_mode.set(mode=enums.TPLDMode.NORMAL) + await port.emulation.tpld_mode.set(mode=enums.TPLDMode.MICRO) + + resp = await port.emulation.tpld_mode.get() + resp.mode + + # Configure flow's basic filter on a port + # Configure flow properties + flow = port.emulation.flows[1] + + await flow.comment.set(comment="Flow description") + + resp = await flow.comment.get() + resp.comment + + # Initializing the shadow copy of the filter. + await flow.shadow_filter.initiating.set() + + # Configure shadow filter to BASIC mode + await flow.shadow_filter.use_basic_mode() + + # Query the mode of the filter (either basic or extended) + filter = await flow.shadow_filter.get_mode() + + if isinstance(filter, misc.BasicImpairmentFlowFilter): + #------------------ + # Ethernet subfilter + #------------------ + # Use and configure basic-mode shadow filter's Ethernet subfilter + await utils.apply( + filter.ethernet.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.ethernet.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.ethernet.src_address.set(use=enums.OnOff.ON, value=Hex("AAAAAAAAAAAA"), mask=Hex("FFFFFFFFFFFF")), + filter.ethernet.dest_address.set(use=enums.OnOff.ON, value=Hex("BBBBBBBBBBBB"), mask=Hex("FFFFFFFFFFFF")) + ) + + #------------------ + # Layer 2+ subfilter + #------------------ + # Not use basic-mode shadow filter's Layer 2+ subfilter + await filter.l2plus_use.set(use=enums.L2PlusPresent.NA) + + # Use and configure basic-mode shadow filter's Layer2+ subfilter (One VLAN tag) + await utils.apply( + filter.l2plus_use.set(use=enums.L2PlusPresent.VLAN1), + filter.vlan.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.vlan.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.vlan.inner.tag.set(use=enums.OnOff.ON, value=1234, mask=Hex("0FFF")), + filter.vlan.inner.pcp.set(use=enums.OnOff.OFF, value=3, mask=Hex("07")), + ) + # Use and configure basic-mode shadow filter's Layer2+ subfilter (Two VLAN tag) + await utils.apply( + filter.l2plus_use.set(use=enums.L2PlusPresent.VLAN2), + filter.vlan.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.vlan.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.vlan.inner.tag.set(use=enums.OnOff.ON, value=1234, mask=Hex("0FFF")), + filter.vlan.inner.pcp.set(use=enums.OnOff.OFF, value=3, mask=Hex("07")), + filter.vlan.outer.tag.set(use=enums.OnOff.ON, value=2345, mask=Hex("0FFF")), + filter.vlan.outer.pcp.set(use=enums.OnOff.OFF, value=0, mask=Hex("07")), + ) + # Use and configure basic-mode shadow filter's Layer2+ subfilter (MPLS) + await utils.apply( + filter.l2plus_use.set(use=enums.L2PlusPresent.MPLS), + filter.mpls.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.mpls.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.mpls.label.set(use=enums.OnOff.ON, value=1000, mask=Hex("FFFFF")), + filter.mpls.toc.set(use=enums.OnOff.ON, value=0, mask=Hex("07")), + ) + + #------------------ + # Layer 3 subfilter + #------------------ + # Not use basic-mode shadow filter's Layer 3 subfilter + await filter.l3_use.set(use=enums.L3Present.NA) + # Use and configure basic-mode shadow filter's Layer 3 subfilter (IPv4) + await utils.apply( + filter.l3_use.set(use=enums.L3Present.IP4), + filter.ip.v4.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.ip.v4.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.ip.v4.src_address.set(use=enums.OnOff.ON, value=ipaddress.IPv4Address("10.0.0.2"), mask=Hex("FFFFFFFF")), + filter.ip.v4.dest_address.set(use=enums.OnOff.ON, value=ipaddress.IPv4Address("10.0.0.2"), mask=Hex("FFFFFFFF")), + filter.ip.v4.dscp.set(use=enums.OnOff.ON, value=0, mask=Hex("FC")), + ) + # Use and configure basic-mode shadow filter's Layer 3 subfilter (IPv6) + await utils.apply( + filter.l3_use.set(use=enums.L3Present.IP6), + filter.ip.v6.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.ip.v6.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.ip.v6.src_address.set(use=enums.OnOff.ON, value=ipaddress.IPv6Address("2001::2"), mask=Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + filter.ip.v6.dest_address.set(use=enums.OnOff.ON, value=ipaddress.IPv6Address("2002::2"), mask=Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + filter.ip.v6.traffic_class.set(use=enums.OnOff.ON, value=0, mask=Hex("FC")), + ) + + #------------------ + # Layer 4 subfilter + #------------------ + # Use and configure basic-mode shadow filter's Layer 4 subfilter (TCP) + await utils.apply( + filter.tcp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.tcp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.tcp.src_port.set(use=enums.OnOff.ON, value=1234, mask=Hex("FFFF")), + filter.tcp.dest_port.set(use=enums.OnOff.ON, value=80, mask=Hex("FFFF")), + ) + # Use and configure basic-mode shadow filter's Layer 4 subfilter (UDP) + await utils.apply( + filter.udp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.udp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.udp.src_port.set(use=enums.OnOff.ON, value=1234, mask=Hex("FFFF")), + filter.udp.dest_port.set(use=enums.OnOff.ON, value=80, mask=Hex("FFFF")), + ) + + #------------------ + # Layer Xena subfilter + #------------------ + await utils.apply( + filter.tpld.settings.set(action=enums.InfoAction.EXCLUDE), + filter.tpld.settings.set(action=enums.InfoAction.INCLUDE), + filter.tpld.test_payload_filters_config[0].set(use=enums.OnOff.ON, id = 2), + filter.tpld.test_payload_filters_config[0].set(use=enums.OnOff.OFF, id = 2), + filter.tpld.test_payload_filters_config[1].set(use=enums.OnOff.ON, id = 4), + filter.tpld.test_payload_filters_config[1].set(use=enums.OnOff.OFF, id = 4), + filter.tpld.test_payload_filters_config[2].set(use=enums.OnOff.ON, id = 6), + filter.tpld.test_payload_filters_config[2].set(use=enums.OnOff.OFF, id = 6), + filter.tpld.test_payload_filters_config[3].set(use=enums.OnOff.ON, id = 8), + filter.tpld.test_payload_filters_config[3].set(use=enums.OnOff.OFF, id = 8), + filter.tpld.test_payload_filters_config[4].set(use=enums.OnOff.ON, id = 10), + filter.tpld.test_payload_filters_config[4].set(use=enums.OnOff.OFF, id = 10), + filter.tpld.test_payload_filters_config[5].set(use=enums.OnOff.ON, id = 20), + filter.tpld.test_payload_filters_config[5].set(use=enums.OnOff.OFF, id = 20), + filter.tpld.test_payload_filters_config[6].set(use=enums.OnOff.ON, id = 40), + filter.tpld.test_payload_filters_config[6].set(use=enums.OnOff.OFF, id = 40), + filter.tpld.test_payload_filters_config[7].set(use=enums.OnOff.ON, id = 60), + filter.tpld.test_payload_filters_config[7].set(use=enums.OnOff.OFF, id = 60), + filter.tpld.test_payload_filters_config[8].set(use=enums.OnOff.ON, id = 80), + filter.tpld.test_payload_filters_config[8].set(use=enums.OnOff.OFF, id = 80), + filter.tpld.test_payload_filters_config[9].set(use=enums.OnOff.ON, id = 100), + filter.tpld.test_payload_filters_config[9].set(use=enums.OnOff.OFF, id = 100), + filter.tpld.test_payload_filters_config[10].set(use=enums.OnOff.ON, id = 102), + filter.tpld.test_payload_filters_config[10].set(use=enums.OnOff.OFF, id = 102), + filter.tpld.test_payload_filters_config[11].set(use=enums.OnOff.ON, id = 104), + filter.tpld.test_payload_filters_config[11].set(use=enums.OnOff.OFF, id = 104), + filter.tpld.test_payload_filters_config[12].set(use=enums.OnOff.ON, id = 106), + filter.tpld.test_payload_filters_config[12].set(use=enums.OnOff.OFF, id = 106), + filter.tpld.test_payload_filters_config[13].set(use=enums.OnOff.ON, id = 108), + filter.tpld.test_payload_filters_config[13].set(use=enums.OnOff.OFF, id = 108), + filter.tpld.test_payload_filters_config[14].set(use=enums.OnOff.ON, id = 110), + filter.tpld.test_payload_filters_config[14].set(use=enums.OnOff.OFF, id = 110), + filter.tpld.test_payload_filters_config[15].set(use=enums.OnOff.ON, id = 200), + filter.tpld.test_payload_filters_config[15].set(use=enums.OnOff.OFF, id = 200), + ) + + #------------------ + # Layer Any subfilter + #------------------ + await utils.apply( + filter.any.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE), + filter.any.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE), + filter.any.config.set(position=0, value=Hex("112233445566"), mask=Hex("112233445566")) + ) + + # Apply the filter so the configuration data in the shadow copy is committed to the working copy automatically. + await flow.shadow_filter.enable.set_off() + await flow.shadow_filter.enable.set_on() + await flow.shadow_filter.apply.set() + + # Configure flow's extended filter on a port + # Configure flow properties + flow = port.emulation.flows[1] + await flow.comment.set("Flow description") + + # Initializing the shadow copy of the filter. + await flow.shadow_filter.initiating.set() + + # Configure shadow filter to EXTENDED mode + await flow.shadow_filter.use_extended_mode() + + # Query the mode of the filter (either basic or extended) + filter = await flow.shadow_filter.get_mode() + + if isinstance(filter, misc.ExtendedImpairmentFlowFilter): + + await filter.use_segments( + enums.ProtocolOption.VLAN) + protocol_segments = await filter.get_protocol_segments() + await protocol_segments[0].value.set(value=Hex("AAAAAAAAAAAABBBBBBBBBBBB8100")) + await protocol_segments[0].mask.set(masks=Hex("0000000000000000000000000000")) + await protocol_segments[1].value.set(value=Hex("0064FFFF")) + await protocol_segments[1].mask.set(masks=Hex("00000000")) + + # Configure impairment - Drop + # Fixed Burst distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.fixed_burst.set(burst_size=5), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=5), #repeat (duration = 1, period = x) + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=0), #one shot + ) + + # Random Burst distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.random_burst.set(minimum=1, maximum=10, probability=10_000), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Fixed Rate distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.fixed_rate.set(probability=10_000), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Bit Error Rate distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.bit_error_rate.set(coef=1, exp=1), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Random Rate distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.random_rate.set(probability=10_000), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gilbert Elliot distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.ge.set(good_state_prob=0, good_state_trans_prob=0, bad_state_prob=0, bad_state_trans_prob=0), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Uniform distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.uniform.set(minimum=1, maximum=1), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gaussian distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.gaussian.set(mean=1, std_deviation=1), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Poisson distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.poison.set(mean=9), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gamma distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.drop_type_config.gamma.set(shape=1, scale=1), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Custom distribution for impairment Drop + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await utils.apply( + flow.impairment_distribution.drop_type_config.custom.set(cust_id=0), + flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1), + flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Set distribution and start impairment Drop + await flow.impairment_distribution.drop_type_config.enable.set_on() + await flow.impairment_distribution.drop_type_config.enable.set_off() + + # Configure impairment - Misordering + + # Fixed Burst distribution for impairment Misordering + # dist = distributions.misordering.FixedBurst(burst_size=1) + # dist.repeat(period=5) + # dist.one_shot() + + # Fixed Burst distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.misorder_type_config.fixed_burst.set(burst_size=5), + flow.impairment_distribution.misorder_type_config.schedule.set(duration=1, period=5), #repeat + flow.impairment_distribution.misorder_type_config.schedule.set(duration=1, period=0), #one shot + ) + + # Fixed Rate distribution for impairment Drop + await utils.apply( + flow.impairment_distribution.misorder_type_config.fixed_rate.set(probability=10_000), + flow.impairment_distribution.misorder_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.misorder_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Set distribution and start impairment Misordering + await flow.misordering.set(depth=1) + await flow.impairment_distribution.misorder_type_config.enable.set_on() + await flow.impairment_distribution.misorder_type_config.enable.set_off() + + # Configure impairment - Latency & Jitter + # Fixed Burst distribution for impairment Latency & Jitter + await flow.impairment_distribution.latency_jitter_type_config.constant_delay.set(delay=100) + + # Random Burst distribution for impairment Latency & Jitter + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.accumulate_and_burst.set(delay=1300), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=1, period=1), #repeat (duration = 1, period = x) + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=1, period=0), #one shot + ) + + # Step distribution for impairment Latency & Jitter + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.step.set(low=1300, high=77000), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Uniform distribution for impairment Latency & Jitter + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.uniform.set(minimum=1, maximum=1), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gaussian distribution for impairment Latency & Jitter + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.gaussian.set(mean=1, std_deviation=1), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Poisson distribution for impairment Latency & Jitter + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.poison.set(mean=1), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gamma distribution for impairment Latency & Jitter + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.gamma.set(shape=1, scale=1), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Custom distribution for impairment Latency & Jitter + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await utils.apply( + flow.impairment_distribution.latency_jitter_type_config.custom.set(cust_id=0), + flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Set distribution and start impairment Latency & Jitter + await flow.impairment_distribution.latency_jitter_type_config.enable.set_on() + await flow.impairment_distribution.latency_jitter_type_config.enable.set_off() + + # Configure impairment - Duplication + + # Fixed Burst distribution for impairment Duplication + # dist.one_shot() + await utils.apply( + flow.impairment_distribution.duplication_type_config.fixed_burst.set(burst_size=1300), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1), #repeat (duration = 1, period = x) + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=0), #one shot + ) + + # Random Burst distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.random_burst.set(minimum=1, maximum=1, probability=10_0000), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Fixed Rate distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.fixed_rate.set(probability=10_000), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Bit Error Rate distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.bit_error_rate.set(coef=1, exp=1), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Random Rate distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.random_rate.set(probability=10_000), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gilbert Elliot distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.ge.set(good_state_prob=0, good_state_trans_prob=0, bad_state_prob=0, bad_state_trans_prob=0), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Uniform distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.uniform.set(minimum=1, maximum=1), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gaussian distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.gaussian.set(mean=1, std_deviation=1), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Poisson distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.poison.set(mean=9), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gamma distribution for impairment Duplication + await utils.apply( + flow.impairment_distribution.duplication_type_config.gamma.set(shape=1, scale=1), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Custom distribution for impairment Duplication + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await utils.apply( + flow.impairment_distribution.duplication_type_config.custom.set(cust_id=0), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1), + flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Set distribution and start impairment Duplication + await flow.impairment_distribution.duplication_type_config.enable.set_on() + await flow.impairment_distribution.duplication_type_config.enable.set_off() + + # Configure impairment - Corruption + + # Fixed Burst distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.fixed_burst.set(burst_size=1300), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), #repeat (duration = 1, period = x) + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=0), #one shot + ) + + # Random Burst distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.random_burst.set(minimum=1, maximum=1, probability=10_0000), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Fixed Rate distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.fixed_rate.set(probability=10_000), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Bit Error Rate distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.bit_error_rate.set(coef=1, exp=1), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Random Rate distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.random_rate.set(probability=10_000), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gilbert Elliot distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.ge.set(good_state_prob=0, good_state_trans_prob=0, bad_state_prob=0, bad_state_trans_prob=0), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Uniform distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.uniform.set(minimum=1, maximum=1), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gaussian distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.gaussian.set(mean=1, std_deviation=1), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1),# repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Poisson distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.poison.set(mean=9), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Gamma distribution for impairment Corruption + await utils.apply( + flow.impairment_distribution.corruption_type_config.gamma.set(shape=1, scale=1), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), # repeat pattern + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + + # Custom distribution for impairment Corruption + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await utils.apply( + flow.impairment_distribution.corruption_type_config.custom.set(cust_id=0), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), + flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous + ) + + # Set distribution and start impairment Corruption + await flow.corruption.set(corruption_type=enums.CorruptionType.ETH) + await flow.corruption.set(corruption_type=enums.CorruptionType.IP) + await flow.corruption.set(corruption_type=enums.CorruptionType.TCP) + await flow.corruption.set(corruption_type=enums.CorruptionType.UDP) + await flow.corruption.set(corruption_type=enums.CorruptionType.BER) + await flow.impairment_distribution.corruption_type_config.enable.set_on() + await flow.impairment_distribution.corruption_type_config.enable.set_off() + + + # Configure bandwidth control - Policer + + await flow.bandwidth_control.policer.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L1, cir=10_000, cbs=1_000) + await flow.bandwidth_control.policer.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L2, cir=10_000, cbs=1_000) + + + # Configure bandwidth control - Shaper + + # Set and start bandwidth control Shaper + await flow.bandwidth_control.shaper.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L1, cir=10_000, cbs=1_000, buffer_size=1_000) + await flow.bandwidth_control.shaper.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L2, cir=10_000, cbs=1_000, buffer_size=1_000) + + # Flow statistics + + rx_total = await flow.statistics.rx.total.get() + rx_total.byte_count + rx_total.packet_count + rx_total.l2_bps + rx_total.pps + + tx_total = await flow.statistics.tx.total.get() + tx_total.byte_count + tx_total.packet_count + tx_total.l2_bps + tx_total.pps + + flow_drop_total = await flow.statistics.total.drop_packets.get() + flow_drop_total.pkt_drop_count_total + flow_drop_total.pkt_drop_count_programmed + flow_drop_total.pkt_drop_count_bandwidth + flow_drop_total.pkt_drop_count_other + flow_drop_total.pkt_drop_ratio_total + flow_drop_total.pkt_drop_ratio_programmed + flow_drop_total.pkt_drop_ratio_bandwidth + flow_drop_total.pkt_drop_ratio_other + + flow_corrupted_total = await flow.statistics.total.corrupted_packets.get() + flow_corrupted_total.fcs_corrupted_pkt_count + flow_corrupted_total.fcs_corrupted_pkt_ratio + flow_corrupted_total.ip_corrupted_pkt_count + flow_corrupted_total.ip_corrupted_pkt_ratio + flow_corrupted_total.tcp_corrupted_pkt_count + flow_corrupted_total.tcp_corrupted_pkt_ratio + flow_corrupted_total.total_corrupted_pkt_count + flow_corrupted_total.total_corrupted_pkt_ratio + flow_corrupted_total.udp_corrupted_pkt_count + flow_corrupted_total.udp_corrupted_pkt_ratio + + flow_delayed_total = await flow.statistics.total.latency_packets.get() + flow_delayed_total.pkt_count + flow_delayed_total.ratio + + flow_jittered_total = await flow.statistics.total.jittered_packets.get() + flow_jittered_total.pkt_count + flow_jittered_total.ratio + + flow_duplicated_total = await flow.statistics.total.duplicated_packets.get() + flow_duplicated_total.pkt_count + flow_duplicated_total.ratio + + flow_misordered_total = await flow.statistics.total.mis_ordered_packets.get() + flow_misordered_total.pkt_count + flow_misordered_total.ratio + + await flow.statistics.tx.clear.set() + await flow.statistics.rx.clear.set() + await flow.statistics.clear.set() + + # Port statistics + port_drop = await port.emulation.statistics.drop.get() + port_drop.pkt_drop_count_total + port_drop.pkt_drop_count_programmed + port_drop.pkt_drop_count_bandwidth + port_drop.pkt_drop_count_other + port_drop.pkt_drop_ratio_total + port_drop.pkt_drop_ratio_programmed + port_drop.pkt_drop_ratio_bandwidth + port_drop.pkt_drop_ratio_other + + port_corrupted = await port.emulation.statistics.corrupted.get() + port_corrupted.fcs_corrupted_pkt_count + port_corrupted.fcs_corrupted_pkt_ratio + port_corrupted.ip_corrupted_pkt_count + port_corrupted.ip_corrupted_pkt_ratio + port_corrupted.tcp_corrupted_pkt_count + port_corrupted.tcp_corrupted_pkt_ratio + port_corrupted.total_corrupted_pkt_count + port_corrupted.total_corrupted_pkt_ratio + port_corrupted.udp_corrupted_pkt_count + port_corrupted.udp_corrupted_pkt_ratio + + port_delayed = await port.emulation.statistics.latency.get() + port_delayed.pkt_count + port_delayed.ratio + + port_jittered = await port.emulation.statistics.jittered.get() + port_jittered.pkt_count + port_jittered.ratio + + port_duplicated = await port.emulation.statistics.duplicated.get() + port_duplicated.pkt_count + port_duplicated.ratio + + port_misordered = await port.emulation.statistics.mis_ordered.get() + port_misordered.pkt_count + port_misordered.ratio + + await port.emulation.clear.set() +# endregion diff --git a/docs/source/api_ref/hlapiv1/summary.rst b/docs/source/api_ref/hlapiv1/summary.rst new file mode 100644 index 00000000..b6ffe00e --- /dev/null +++ b/docs/source/api_ref/hlapiv1/summary.rst @@ -0,0 +1,14 @@ +Summary +================================= + +The summary of XOA HL-API (object-oriented) is provided in the attached file. + +You can find ``set`` and ``get`` method of APIs of ``tester``, ``module``, ``port``, ``stream``, and ``impairment flow``. + +.. seealso:: + + Read more about :ref:`Get and Set Method ` + +.. literalinclude:: summary.py + :language: python + :linenos: \ No newline at end of file diff --git a/docs/source/understand_xoa_python/hlapi_guide.rst b/docs/source/understand_xoa_python/hlapi_guide.rst index 88140341..75eac1b6 100644 --- a/docs/source/understand_xoa_python/hlapi_guide.rst +++ b/docs/source/understand_xoa_python/hlapi_guide.rst @@ -50,6 +50,8 @@ are represented as If there is a method returning both a single value and multiple values, it is considered a bug. +.. _get_set_methods: + Get and Set Methods -------------------------------- From 2f72a149ed442678f1e642b90707011e909c9b06 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Fri, 10 Nov 2023 20:52:01 +0700 Subject: [PATCH 08/15] Fix HLIv1 name for Poisson distribution --- .../internals/hli_v1/ports/port_l23/chimera/pe_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_distribution.py b/xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_distribution.py index 89da851b..751f3053 100644 --- a/xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_distribution.py +++ b/xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_distribution.py @@ -92,7 +92,7 @@ def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int, flow_i :type: PED_GAUSS """ - self.poison = PED_POISSON(conn, module_id, port_id, flow_index, impairment_type_index) + self.poisson = PED_POISSON(conn, module_id, port_id, flow_index, impairment_type_index) """Poisson distribution configuration. :type: PED_POISSON From 9bba7a76bbe13d3360676ac95c2314a8928daff1 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 00:28:45 +0700 Subject: [PATCH 09/15] Fix PP_RXFECSTATS last param --- xoa_driver/internals/commands/pp_commands.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/xoa_driver/internals/commands/pp_commands.py b/xoa_driver/internals/commands/pp_commands.py index bc064308..5ad8ab4c 100644 --- a/xoa_driver/internals/commands/pp_commands.py +++ b/xoa_driver/internals/commands/pp_commands.py @@ -421,12 +421,12 @@ class PP_RXFECSTATS: class GetDataAttr(ResponseBodyStruct): stats_type: int = field(XmpLong()) """long integer, currently always 0.""" - value_count: int = field(XmpLong()) + data_count: int = field(XmpLong()) """long integer, number of values.""" correction_stats: typing.List[int] = field(XmpSequence(types_chunk=[XmpLong()], length=8)) """list of long integers, array of length value_count-1. The correction_stats array shows how many FEC blocks have been seen with [0, 1, 2, 3....15, >15] symbol errors.""" - rx_uncorrectable_code_word_count: int = field(XmpLong()) - """long integer, the number of received uncorrectable code words.""" + sum_of_zero_and_correctable_fec_block: int = field(XmpLong()) + """long integer, the sum of FEC blocks with <=n symbol errors.""" def get(self) -> Token[GetDataAttr]: """Get statistics on how many FEC blocks have been seen with a given number of symbol errors. @@ -813,9 +813,7 @@ def get(self) -> Token[GetDataAttr]: class PP_TXLASERPOWER: """ Reading of the optical power level of the transmission signal. There is one - value for each laser/wavelength, and the number of these depends on the kind of - CFP transceiver used. The list is empty if the CFP transceiver does not support - optical power read-out. + value for each laser/wavelength, and the number of these depends on the kind of CFP transceiver used. The list is empty if the CFP transceiver does not support optical power read-out. """ code: typing.ClassVar[int] = 296 From 37d48e69e389ea73e6359fc415ab9404fa6e78db Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 00:29:23 +0700 Subject: [PATCH 10/15] Update command descriptions --- xoa_driver/internals/commands/m_commands.py | 8 +- xoa_driver/internals/commands/p_commands.py | 132 ++++-------------- xoa_driver/internals/commands/pc_commands.py | 3 +- xoa_driver/internals/commands/pe_commands.py | 6 +- xoa_driver/internals/commands/ped_commands.py | 4 +- xoa_driver/internals/commands/px_commands.py | 7 +- 6 files changed, 36 insertions(+), 124 deletions(-) diff --git a/xoa_driver/internals/commands/m_commands.py b/xoa_driver/internals/commands/m_commands.py index 6c2f5b69..611b3cca 100644 --- a/xoa_driver/internals/commands/m_commands.py +++ b/xoa_driver/internals/commands/m_commands.py @@ -1054,8 +1054,7 @@ def get(self) -> Token[GetDataAttr]: @dataclass class M_MEDIA: """ - For the test modules that support media configuration (check M_CAPABILITIES), this command sets the desired media - type (front port). + For the test modules that support media configuration (check M_CAPABILITIES), this command sets the desired media type (front port). """ code: typing.ClassVar[int] = 342 @@ -1657,12 +1656,11 @@ def get(self) -> Token[GetDataAttr]: @dataclass class M_LATENCYMODE: """ - Configures the latency mode for Chimera module. In extended latency mode, the FPGA allows all latency parameters to be 10 times higher, - at the cost of reduced latency precision. + Configures the latency mode for Chimera module. In extended latency mode, the FPGA allows all latency parameters to be 10 times higher, at the cost of reduced latency precision. .. note:: - - When change the latency mode, all latency configurations are reset on all ports in chimera module. + When change the latency mode, all latency configurations are reset on all ports in chimera module. """ diff --git a/xoa_driver/internals/commands/p_commands.py b/xoa_driver/internals/commands/p_commands.py index 4173777c..164210d3 100644 --- a/xoa_driver/internals/commands/p_commands.py +++ b/xoa_driver/internals/commands/p_commands.py @@ -69,11 +69,7 @@ @dataclass class P_RESERVATION: """ - You set this command to reserve, release, or relinquish a port. The port must - be reserved before any of its configuration can be changed, including streams, - filters, capture, and datasets.The owner of the session must already have been - specified. Reservation will fail if the chassis or module is reserved to other - users. + You set this command to reserve, release, or relinquish a port. The port must be reserved before any of its configuration can be changed, including streams, filters, capture, and datasets.The owner of the session must already have been specified. Reservation will fail if the chassis or module is reserved to other users. """ code: typing.ClassVar[int] = 102 @@ -133,12 +129,7 @@ def set(self, operation: ReservedAction) -> Token[None]: @dataclass class P_RESERVEDBY: """ - Identify the user who has a port reserved. The empty string if the port is not - currently reserved. Note that multiple connections can specify the same name - with C_OWNER, but a resource can only be reserved to one connection. Therefore - you cannot count on having the port just because it is reserved in your name. - The port is reserved to this connection only if P_RESERVATION returns - RESERVED_BY_YOU. + Identify the user who has a port reserved. The empty string if the port is not currently reserved. Note that multiple connections can specify the same name with C_OWNER, but a resource can only be reserved to one connection. Therefore you cannot count on having the port just because it is reserved in your name. The port is reserved to this connection only if P_RESERVATION returns RESERVED_BY_YOU. """ code: typing.ClassVar[int] = 103 @@ -809,11 +800,7 @@ def set(self, comment: str) -> Token[None]: @dataclass class P_SPEEDREDUCTION: """ - A speed reduction applied to the transmitting side of a port, resulting in an - effective traffic rate that is slightly lower than the rate of the physical - interface. Speed reduction is effectuated by inserting short idle periods in the - generated traffic pattern to consume part of the port's physical bandwidth. The - port's clock speed is not altered. + A speed reduction applied to the transmitting side of a port, resulting in an effective traffic rate that is slightly lower than the rate of the physical interface. Speed reduction is effectuated by inserting short idle periods in the generated traffic pattern to consume part of the port's physical bandwidth. The port's clock speed is not altered. """ code: typing.ClassVar[int] = 113 @@ -854,8 +841,7 @@ def set(self, ppm: int) -> Token[None]: @dataclass class P_INTERFRAMEGAP: """ - The minimum gap between packets in the traffic generated for a port. The gap - includes the Ethernet preamble. + The minimum gap between packets in the traffic generated for a port. The gap includes the Ethernet preamble. """ code: typing.ClassVar[int] = 114 @@ -1156,13 +1142,7 @@ def set(self, on_off: OnOff) -> Token[None]: @dataclass class P_RANDOMSEED: """ - A fixed seed value specified for a port. This value is used for a pseudo-random - number generator used when generating traffic that requires random variation in - packet length, payload, or modified fields. As long as no part of the port - configuration is changed, the generated traffic patterns are reproducible when - restarting traffic for the port. A specified seed value of -1 instead creates - variation by using a new time-based seed value each time traffic generation is - restarted. + A fixed seed value specified for a port. This value is used for a pseudo-random number generator used when generating traffic that requires random variation in packet length, payload, or modified fields. As long as no part of the port configuration is changed, the generated traffic patterns are reproducible when restarting traffic for the port. A specified seed value of -1 instead creates variation by using a new time-based seed value each time traffic generation is restarted. """ code: typing.ClassVar[int] = 121 @@ -1203,12 +1183,7 @@ def set(self, seed: int) -> Token[None]: @dataclass class P_LOOPBACK: """ - The loopback mode for a port. Ports can be configured to perform two different - kinds of loopback: 1) External RX-to-TX loopback, where the received packets - are re-transmitted immediately. The packets are still processed by the receive - logic, and can be captured and analyzed. 2) Internal TX-to-RX loopback, where - the transmitted packets are received directly by the port itself. This is mainly - useful for testing the generated traffic patterns before actual use. + The loopback mode for a port. Ports can be configured to perform two different kinds of loopback: 1) External RX-to-TX loopback, where the received packets are re-transmitted immediately. The packets are still processed by the receive logic, and can be captured and analyzed. 2) Internal TX-to-RX loopback, where the transmitted packets are received directly by the port itself. This is mainly useful for testing the generated traffic patterns before actual use. """ @@ -1330,12 +1305,11 @@ def set(self, on_off: OnOff) -> Token[None]: class P_TRAFFIC: """ Whether a port is transmitting packets. When on, the port generates a sequence - of packets with contributions from each stream that is enabled. The streams are - configured using the PS_xxx parameters. + of packets with contributions from each stream that is enabled. The streams are configured using the PS_xxx parameters. .. note:: - From Release 57.1, if any of the specified packet sizes cannot fit into the packet generator, this command will return FAILED and not start the traffic. + If any of the specified packet sizes cannot fit into the packet generator, this command will return FAILED and not start the traffic. While traffic is on the streams for this port cannot be enabled or disabled, and the configuration of those streams that are enabled cannot be changed. """ @@ -1737,16 +1711,7 @@ def set(self, frame_loss_ratio: int) -> Token[None]: class P_MIXWEIGHTS: """ Allow changing the distribution of the MIX packet length by specifying the - percentage of each of the 16 possible frame sizes used in the MIX. The sum of - the percentage values specified must be 100. The command will affect the mix- - distribution for all streams on the port. The possible 16 frame sizes are: 56 - (not valid for 40G/100G), 60, 64, 70, 78, 92, 256, 496, 512, 570, 576, 594, - 1438, 1518, 9216, and 16360. - - .. note:: - - This command requires Xena server version 375 or higher. - + percentage of each of the 16 possible frame sizes used in the MIX. The sum of the percentage values specified must be 100. The command will affect the mix-distribution for all streams on the port. The possible 16 frame sizes are: 56 (not valid for 40G/100G), 60, 64, 70, 78, 92, 256, 496, 512, 570, 576, 594, 1438, 1518, 9216, and 16360. """ code: typing.ClassVar[int] = 192 @@ -2060,8 +2025,7 @@ class P_CHECKSUM: """ Controls an extra payload integrity checksum, which also covers the header protocols following the Ethernet header. It will therefore catch any - modifications to the protocol fields (which should therefore not have modifiers - on them). + modifications to the protocol fields (which should therefore not have modifiers on them). """ code: typing.ClassVar[int] = 302 @@ -2198,18 +2162,7 @@ def set(self, on_off: OnOff) -> Token[None]: @dataclass class P_MIXLENGTH: """ - Allows inspecting the frame sizes defined for each position of the P_MIXWEIGHTS - command. By default, the 16 frame sizes are: 56 (not valid for 40G/100G), 60, - 64, 70, 78, 92, 256, 496, 512, 570, 576, 594, 1438, 1518, 9216, and 16360. In - addition to inspecting these sizes one by one, it also allows changing frame - size for positions 0, 1, 14 and 15 (default values 56, 60, 9216 and 16360). - Supported by the following modules: Thor-400G-7S-1P, Thor-100G-5S-4P and - Loki-100G-5S-2P. - - .. note:: - - This command requires release 84 or higher. - + Allows inspecting the frame sizes defined for each position of the P_MIXWEIGHTS command. By default, the 16 frame sizes are: 56 (not valid for 40G/100G), 60, 64, 70, 78, 92, 256, 496, 512, 570, 576, 594, 1438, 1518, 9216, and 16360. In addition to inspecting these sizes one by one, it also allows changing frame size for positions 0, 1, 14 and 15 (default values 56, 60, 9216 and 16360). """ code: typing.ClassVar[int] = 305 @@ -2347,8 +2300,7 @@ def set(self, chunks: typing.List[NdpChunk]) -> Token[None]: @dataclass class P_MULTICAST: """ - A multicast mode for a port. Ports can use the IGMPv2 protocol to join or leave - multicast groups, either on an on-off basis or repeatedly. + A multicast mode for a port. Ports can use the IGMPv2 protocol to join or leave multicast groups, either on an on-off basis or repeatedly. """ code: typing.ClassVar[int] = 311 @@ -2427,9 +2379,7 @@ def set(self, ipv4_multicast_addresses: typing.List[ipaddress.IPv4Address], oper @dataclass class P_MULTICASTEXT: """ - A multicast mode for a port. Ports can use the IGMPv2/IGMPv3 protocol to join or - leave multicast groups, either on an on-off basis or repeatedly. ** Requires - software release 83.2 or higher + A multicast mode for a port. Ports can use the IGMPv2/IGMPv3 protocol to join or leave multicast groups, either on an on-off basis or repeatedly. """ code: typing.ClassVar[int] = 312 @@ -2499,8 +2449,7 @@ def set(self, ipv4_multicast_addresses: typing.List[ipaddress.IPv4Address], oper @dataclass class P_MCSRCLIST: """ - Multicast source list of the port. Only valid if the IGMP protocol version is - IGMPv3 set by P_MULTICASTEXT. + Multicast source list of the port. Only valid if the IGMP protocol version is IGMPv3 set by P_MULTICASTEXT. """ code: typing.ClassVar[int] = 313 @@ -2635,8 +2584,7 @@ def set(self, mode: TXMode) -> Token[None]: @dataclass class P_MULTICASTHDR: """ - Allows addition of a VLAN tag to IGMPv2 and IGPMv3 packets. This command - requires software release 83.2 or higher. + Allows addition of a VLAN tag to IGMPv2 and IGPMv3 packets. """ code: typing.ClassVar[int] = 314 @@ -2713,10 +2661,7 @@ def set(self, header_count: int, header_format: MulticastHeaderFormat, tag: int, @dataclass class P_RATEFRACTION: """ - The port-level rate of the traffic transmitted for a port in sequential tx mode, - expressed in millionths of the effective rate for the port. The bandwidth - consumption includes the inter-frame gaps, and does not depend on the length of - the packets for the streams. + The port-level rate of the traffic transmitted for a port in sequential tx mode, expressed in millionths of the effective rate for the port. The bandwidth consumption includes the inter-frame gaps, and does not depend on the length of the packets for the streams. """ code: typing.ClassVar[int] = 321 @@ -2757,10 +2702,7 @@ def set(self, port_rate_ppm: int) -> Token[None]: @dataclass class P_RATEPPS: """ - The port-level rate of the traffic transmitted for a port in sequential tx mode, - expressed in packets per second. The bandwidth consumption is heavily dependent - on the length of the packets generated for the streams, and also on the inter- - frame gap for the port. + The port-level rate of the traffic transmitted for a port in sequential tx mode, expressed in packets per second. The bandwidth consumption is heavily dependent on the length of the packets generated for the streams, and also on the inter-frame gap for the port. """ code: typing.ClassVar[int] = 322 @@ -2801,11 +2743,7 @@ def set(self, port_rate_pps: int) -> Token[None]: @dataclass class P_RATEL2BPS: """ - The port-level rate of the traffic transmitted for a port in sequential tx mode, - expressed in units of bits per-second at layer-2, thus including the Ethernet - header but excluding the inter-frame gap. The bandwidth consumption is somewhat - dependent on the length of the packets generated for the stream, and also on the - inter-frame gap for the port. + The port-level rate of the traffic transmitted for a port in sequential tx mode, expressed in units of bits per-second at layer-2, thus including the Ethernet header but excluding the inter-frame gap. The bandwidth consumption is somewhat dependent on the length of the packets generated for the stream, and also on the inter-frame gap for the port. """ code: typing.ClassVar[int] = 323 @@ -2850,13 +2788,7 @@ def set(self, port_rate_bps: int) -> Token[None]: @dataclass class P_PAYLOADMODE: """ - Set this command to configure the port to use different payload modes, i.e. - normal, extend payload, and custom payload field, for ALL streams on this port. - The extended payload feature allows the definition of a much larger (up to MTU) - payload buffer for each stream. The custom payload field feature allows you to - define a sequence of custom data fields for each stream. The data fields will - then be used in a round robin fashion when packets are sent based on the stream - definition. + Set this command to configure the port to use different payload modes, i.e. normal, extend payload, and custom payload field, for ALL streams on this port. The extended payload feature allows the definition of a much larger (up to MTU) payload buffer for each stream. The custom payload field feature allows you to define a sequence of custom data fields for each stream. The data fields will then be used in a round robin fashion when packets are sent based on the stream definition. """ code: typing.ClassVar[int] = 324 @@ -2910,8 +2842,7 @@ def set(self, mode: PayloadMode) -> Token[None]: class P_BRRMODE: """ Selects the Master/Slave setting of - 100 Mbit/s (requires Valkyrie release 76.1 or higher), - 1000 Mbit/s (requires Valkyrie release 76.2 or higher) BroadR-Reach copper interfaces. + 100 Mbit/s, 1000 Mbit/s BroadR-Reach copper interfaces. """ code: typing.ClassVar[int] = 326 @@ -3009,12 +2940,7 @@ def set(self, on_off: OnOff) -> Token[None]: @dataclass class P_MAXHEADERLENGTH: """ - The maximum number of header content bytes that can be freely specified for each - generated stream. The remaining payload bytes of the packet are auto- - generated.The default is 128 bytes. When a larger number is select there is a - corresponding proportional reduction in the number of stream definitions that - are available for the port. Possible values: 128 (default), 256, 512, 1024, - 2048. + The maximum number of header content bytes that can be freely specified for each generated stream. The remaining payload bytes of the packet are auto-generated.The default is 128 bytes. When a larger number is select there is a corresponding proportional reduction in the number of stream definitions that are available for the port. Possible values: 128 (default), 256, 512, 1024, 2048. """ code: typing.ClassVar[int] = 328 @@ -3127,8 +3053,7 @@ def get(self) -> Token[GetDataAttr]: @dataclass class P_XMITONETIME: """ - The time at which the latest packet was transmitted using the P_XMITONE command. - The time reference is the same used by the time stamps of captured packets. + The time at which the latest packet was transmitted using the P_XMITONE command. The time reference is the same used by the time stamps of captured packets. """ code: typing.ClassVar[int] = 331 @@ -3767,10 +3692,6 @@ class P_FAULTSTATUS: Shows if a local or remote fault is currently being detected by the Reconciliation Sub-layer of the port. - .. note:: - - Currently only available on M1CFP100, M2CFP40, M2QSFP+ and M1CFP4QSFP28CXP. - """ code: typing.ClassVar[int] = 349 @@ -3938,8 +3859,7 @@ def set(self, packet_count_limit: int) -> Token[None]: @dataclass class P_TCVRSTATUS: """ - Get various tcvr status information. RX loss status of the individual RX optical - lanes (only 4 lanes are supported currently). + Get various tcvr status information. RX loss status of the individual RX optical lanes (only 4 lanes are supported currently). """ code: typing.ClassVar[int] = 357 @@ -4023,8 +3943,7 @@ def set(self, on_off: OnOff) -> Token[None]: @dataclass class P_PFCENABLE: """ - This setting control whether a port responds to incoming Ethernet Priority Flow - Control (PFC) frames, by holding back outgoing traffic for that priority. + This setting control whether a port responds to incoming Ethernet Priority Flow Control (PFC) frames, by holding back outgoing traffic for that priority. """ code: typing.ClassVar[int] = 373 @@ -4207,8 +4126,7 @@ def set(self, runt_length: int) -> Token[None]: @dataclass class P_RXRUNTLENGTH: """ - Enable RX runt length detection to flag if packets are seen with length not - being I bytes. + Enable RX runt length detection to flag if packets are seen with length not being I bytes. """ code: typing.ClassVar[int] = 391 diff --git a/xoa_driver/internals/commands/pc_commands.py b/xoa_driver/internals/commands/pc_commands.py index 35ae2092..fb523ef1 100644 --- a/xoa_driver/internals/commands/pc_commands.py +++ b/xoa_driver/internals/commands/pc_commands.py @@ -307,8 +307,7 @@ def get(self) -> Token[GetDataAttr]: class PC_PACKET: """ Obtains the raw bytes of a captured packet for a port. The packet data may be - truncated if the :class:`PC_KEEP` command specified a limit on the number of bytes - kept. + truncated if the :class:`PC_KEEP` command specified a limit on the number of bytes kept. """ code: typing.ClassVar[int] = 226 diff --git a/xoa_driver/internals/commands/pe_commands.py b/xoa_driver/internals/commands/pe_commands.py index a9efa0c4..03a28ec4 100644 --- a/xoa_driver/internals/commands/pe_commands.py +++ b/xoa_driver/internals/commands/pe_commands.py @@ -319,7 +319,7 @@ class PE_MISORDER: .. note:: - probability [see PED_FIXED] * (depth + 1) should be less than 1,000,000. + probability * (depth + 1) should be less than 1,000,000. (see PED_FIXED) """ @@ -333,11 +333,11 @@ class PE_MISORDER: class GetDataAttr(ResponseBodyStruct): depth: int = field(XmpInt()) - """integer, specifies the misordering depth (Range 1 - 32). Default value. Note: probability [see PED_FIXED] * (depth + 1) should be less than 1,000,000.""" + """integer, specifies the misordering depth (Range 1 - 32). Default value. probability * (depth + 1) should be less than 1,000,000. (see PED_FIXED)""" class SetDataAttr(RequestBodyStruct): depth: int = field(XmpInt()) - """integer, specifies the misordering depth (Range 1 - 32). Default value. Note: probability [see PED_FIXED] * (depth + 1) should be less than 1,000,000.""" + """integer, specifies the misordering depth (Range 1 - 32). Default value. probability * (depth + 1) should be less than 1,000,000. (see PED_FIXED)""" def get(self) -> Token[GetDataAttr]: """Get the misordering depth in number of packets of a flow. diff --git a/xoa_driver/internals/commands/ped_commands.py b/xoa_driver/internals/commands/ped_commands.py index a39762e8..70418397 100644 --- a/xoa_driver/internals/commands/ped_commands.py +++ b/xoa_driver/internals/commands/ped_commands.py @@ -97,7 +97,7 @@ class PED_ONESHOTSTATUS: .. note:: The return value is only valid, if the configured distribution is either accumulate & burst (DELAY) or fixed burst (non-DELAY). - + """ code: typing.ClassVar[int] = 1612 @@ -510,7 +510,7 @@ class PED_UNI: .. note:: - If minimum is less than minimum latency, value is set to minimum latency. If minimum is greater than maximum latency, value is set to maximum latency. + If minimum is less than minimum , value is set to minimum. If minimum is greater than maximum, value is set to maximum. """ diff --git a/xoa_driver/internals/commands/px_commands.py b/xoa_driver/internals/commands/px_commands.py index 06bdbdad..75faab64 100644 --- a/xoa_driver/internals/commands/px_commands.py +++ b/xoa_driver/internals/commands/px_commands.py @@ -24,8 +24,7 @@ @dataclass class PX_RW: """ - Provides read and write access to the register interface supported by the port transceiver. It - is possible to both read and write register values. + Provides read and write access to the register interface supported by the port transceiver. It is possible to both read and write register values. """ code: typing.ClassVar[int] = 501 @@ -68,8 +67,6 @@ def set(self, value: Hex) -> Token[None]: @dataclass class PX_RW_SEQ: """ - .. versionadded: v1.1 - :term:`I2C` sequential access to a transceiver's register. When invoked, the ```` number of bytes will be read or written in one I2C transaction, in which the ```` is read or written with only a single register address setup. @@ -127,7 +124,7 @@ def set(self, value: Hex) -> Token[None]: @register_command @dataclass class PX_MII: - """Provides access to the register interface supported by the media-independent interface (MII) transceiver. It + """Provides access to the register interface supported by the media-independent interface (MII) transceiver. It is possible to both read and write register values.""" code: typing.ClassVar[int] = 537 From c810309dd5f19c4f32ec4fd81e1bc6b24001b64e Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 01:14:01 +0700 Subject: [PATCH 11/15] Fix PP_RXFECSTATS --- xoa_driver/internals/commands/pp_commands.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/xoa_driver/internals/commands/pp_commands.py b/xoa_driver/internals/commands/pp_commands.py index 5ad8ab4c..38568e82 100644 --- a/xoa_driver/internals/commands/pp_commands.py +++ b/xoa_driver/internals/commands/pp_commands.py @@ -423,16 +423,15 @@ class GetDataAttr(ResponseBodyStruct): """long integer, currently always 0.""" data_count: int = field(XmpLong()) """long integer, number of values.""" - correction_stats: typing.List[int] = field(XmpSequence(types_chunk=[XmpLong()], length=8)) - """list of long integers, array of length value_count-1. The correction_stats array shows how many FEC blocks have been seen with [0, 1, 2, 3....15, >15] symbol errors.""" - sum_of_zero_and_correctable_fec_block: int = field(XmpLong()) - """long integer, the sum of FEC blocks with <=n symbol errors.""" + stats: typing.List[int] = field(XmpSequence(types_chunk=[XmpLong()])) + """list of long integers, array of length value_count. The stats array shows how many FEC blocks have been seen with [0, 1, 2, 3....15, >15] symbol errors and the last one is the sum of FEC blocks with <=n symbol errors""" + # sum_of_zero_and_correctable_fec_block: int = field(XmpLong()) + # """long integer, the sum of FEC blocks with <=n symbol errors.""" def get(self) -> Token[GetDataAttr]: """Get statistics on how many FEC blocks have been seen with a given number of symbol errors. :return: stats type (currently always 0), number of values, correction stats array, and the number of received uncorrectable code words. - The correction stats array shows how many FEC blocks have been seen with [0, 1, 2, 3....15, >15] symbol errors, length = value_count-1. :rtype: PP_RXFECSTATS.GetDataAttr """ From 7fb6515a6e6a45f3a2bb4b89c2ebb41a3dd337a7 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 02:10:25 +0700 Subject: [PATCH 12/15] PP_RXTOTALSTATS code changed to 270 --- xoa_driver/internals/commands/pp_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xoa_driver/internals/commands/pp_commands.py b/xoa_driver/internals/commands/pp_commands.py index 38568e82..72e50f27 100644 --- a/xoa_driver/internals/commands/pp_commands.py +++ b/xoa_driver/internals/commands/pp_commands.py @@ -341,7 +341,7 @@ class PP_RXTOTALSTATS: Provides FEC Total counters. """ - code: typing.ClassVar[int] = 285 + code: typing.ClassVar[int] = 270 pushed: typing.ClassVar[bool] = False _connection: 'interfaces.IConnection' From ccf83e5ccdbfd36df5b5157055ff4e237e0ef65d Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 17:56:00 +0700 Subject: [PATCH 13/15] Update PP_PHYTXEQ --- xoa_driver/functions/anlt.py | 6 ++-- xoa_driver/functions/tools.py | 6 ++-- xoa_driver/internals/commands/pp_commands.py | 36 ++++++++++++++------ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/xoa_driver/functions/anlt.py b/xoa_driver/functions/anlt.py index 95781e4d..e670e518 100644 --- a/xoa_driver/functions/anlt.py +++ b/xoa_driver/functions/anlt.py @@ -451,11 +451,11 @@ async def txtap_set( conn, mid, pid = get_ctx(port) cmd_ = commands.PP_PHYTXEQ(conn, mid, pid, serdes) await cmd_.set( - pre1=pre, + pre=pre, main=main, - post1=post1, + post=post1, pre2=pre2, - post2=pre3, + pre3_post2=pre3, post3=0, ) diff --git a/xoa_driver/functions/tools.py b/xoa_driver/functions/tools.py index 7340fc4c..2459d58b 100644 --- a/xoa_driver/functions/tools.py +++ b/xoa_driver/functions/tools.py @@ -120,11 +120,11 @@ def dictionize_lt_status( def dictionize_txtap_get(r: commands.PP_PHYTXEQ.GetDataAttr) -> dict[str, int]: return { - "c(-3)": r.post2, + "c(-3)": r.pre3_post2, "c(-2)": r.pre2, - "c(-1)": r.pre1, + "c(-1)": r.pre, "c(0)": r.main, - "c(1)": r.post1, + "c(1)": r.post, } diff --git a/xoa_driver/internals/commands/pp_commands.py b/xoa_driver/internals/commands/pp_commands.py index 72e50f27..ae10531c 100644 --- a/xoa_driver/internals/commands/pp_commands.py +++ b/xoa_driver/internals/commands/pp_commands.py @@ -1132,15 +1132,15 @@ class PP_PHYTXEQ: _serdes_xindex: int class GetDataAttr(ResponseBodyStruct): - pre1: int = field(XmpInt()) + pre: int = field(XmpInt()) """integer, preemphasis, (range: Module dependent), default = 0 (neutral).""" main: int = field(XmpInt()) """integer, amplification, (range: Module dependent), default = 0 (neutral).""" - post1: int = field(XmpInt()) + post: int = field(XmpInt()) """integer, postemphasis, (range: Module dependent), default = 0 (neutral).""" pre2: int = field(XmpInt()) """integer, preemphasis, (range: Module dependent), default = 0 (neutral).""" - post2: int = field(XmpInt()) + pre3_post2: int = field(XmpInt()) """integer, postemphasis, (range: Module dependent), default = 0 (neutral).""" post3: int = field(XmpInt()) """integer, postemphasis, (range: Module dependent), default = 0 (neutral).""" @@ -1148,15 +1148,15 @@ class GetDataAttr(ResponseBodyStruct): """integer, value must be 4""" class SetDataAttr(RequestBodyStruct): - pre1: int = field(XmpInt()) + pre: int = field(XmpInt()) """integer, preemphasis, (range: Module dependent), default = 0 (neutral).""" main: int = field(XmpInt()) """integer, amplification, (range: Module dependent), default = 0 (neutral).""" - post1: int = field(XmpInt()) + post: int = field(XmpInt()) """integer, postemphasis, (range: Module dependent), default = 0 (neutral).""" pre2: int = field(XmpInt()) """integer, preemphasis, (range: Module dependent), default = 0 (neutral).""" - post2: int = field(XmpInt()) + pre3_post2: int = field(XmpInt()) """integer, postemphasis, (range: Module dependent), default = 0 (neutral).""" post3: int = field(XmpInt()) """integer, postemphasis, (range: Module dependent), default = 0 (neutral).""" @@ -1173,12 +1173,22 @@ def get(self) -> Token[GetDataAttr]: return Token(self._connection, build_get_request(self, module=self._module, port=self._port, indices=[self._serdes_xindex])) - def set(self, pre2: int, pre1: int, main: int, post1: int, post2: int, post3: int) -> Token[None]: + def set(self, pre2: int, pre: int, main: int, post: int, pre3_post2: int, post3: int) -> Token[None]: """Set the equalizer settings of the on-board PHY in the transmission direction (towards the transceiver cage) on Thor and Loki modules. - :param pre1: preemphasis, (range: Module dependent), default = 0 (neutral) - :type pre1: typing.List[int] + :param pre2: pre2 emphasis + :type pre2: int + :param pre: pre emphasis + :type pre: int + :param main: main emphasis + :type main: int + :param post: post emphasis + :type post: int + :param pre3_post2: post2 or pre3 emphasis + :type pre3_post2: int + :param post3: post3 emphasis + :type post3: int """ return Token( @@ -1189,8 +1199,12 @@ def set(self, pre2: int, pre1: int, main: int, post1: int, post2: int, post3: in port=self._port, indices=[self._serdes_xindex], pre2=pre2, - pre1=pre1, - main=main, post1=post1, post2=post2, post3=post3, mode=4)) + pre=pre, + main=main, + post=post, + pre3_post2=pre3_post2, + post3=post3, + mode=4)) @register_command From d4ff9e63d7a37e38553ab03b8d5e1858cae3467e Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 17:56:19 +0700 Subject: [PATCH 14/15] Add description and examples to ref --- .../api_ref/hlapiv1/module/capabilities.rst | 13 +- .../api_ref/hlapiv1/module/identification.rst | 67 ++++- .../api_ref/hlapiv1/module/impairment.rst | 79 ++++-- docs/source/api_ref/hlapiv1/module/index.rst | 3 +- docs/source/api_ref/hlapiv1/module/media.rst | 62 ++++- .../api_ref/hlapiv1/module/reservation.rst | 34 ++- docs/source/api_ref/hlapiv1/module/time.rst | 72 +++++- .../api_ref/hlapiv1/module/time_adv.rst | 78 +++++- .../hlapiv1/module/{ => vulcan}/capture.rst | 8 + .../api_ref/hlapiv1/module/vulcan/index.rst | 11 + .../hlapiv1/module/{ => vulcan}/license.rst | 7 + .../hlapiv1/module/{ => vulcan}/pe.rst | 7 + .../hlapiv1/module/{ => vulcan}/replay.rst | 3 + .../hlapiv1/module/{ => vulcan}/system.rst | 5 + .../hlapiv1/module/{ => vulcan}/tls.rst | 1 + docs/source/api_ref/hlapiv1/port/action.rst | 17 +- docs/source/api_ref/hlapiv1/port/address.rst | 134 ++++++++-- .../api_ref/hlapiv1/port/capabilities.rst | 3 + docs/source/api_ref/hlapiv1/port/capture.rst | 78 +++++- .../api_ref/hlapiv1/port/chimera/config.rst | 35 ++- .../port/chimera/corruption/configuration.rst | 22 +- .../port/chimera/corruption/distribution.rst | 232 +++++++++++++++--- .../port/chimera/corruption/scheduling.rst | 37 +++ .../port/chimera/drop/distribution.rst | 223 ++++++++++++++--- .../hlapiv1/port/chimera/drop/scheduling.rst | 37 +++ .../port/chimera/duplication/distribution.rst | 221 ++++++++++++++--- .../port/chimera/duplication/scheduling.rst | 37 +++ .../hlapiv1/port/chimera/filter/basic/any.rst | 42 +++- .../port/chimera/filter/basic/index.rst | 9 - .../hlapiv1/port/chimera/filter/basic/l2.rst | 50 +++- .../port/chimera/filter/basic/l2plus.rst | 156 ++++++++++-- .../hlapiv1/port/chimera/filter/basic/l3.rst | 149 +++++++++-- .../hlapiv1/port/chimera/filter/basic/l4.rst | 101 ++++++-- .../port/chimera/filter/basic/tpld.rst | 63 ++++- .../hlapiv1/port/chimera/filter/extended.rst | 139 +++++++++-- .../port/chimera/filter/properties.rst | 80 +++++- .../chimera/latencyjitter/configuration.rst | 16 +- .../chimera/latencyjitter/distribution.rst | 193 ++++++++++++--- .../port/chimera/latencyjitter/scheduling.rst | 37 +++ .../port/chimera/misorder/configuration.rst | 19 +- .../port/chimera/misorder/distribution.rst | 70 ++++-- .../port/chimera/misorder/scheduling.rst | 37 +++ .../hlapiv1/port/chimera/policer/index.rst | 17 +- .../hlapiv1/port/chimera/shaper/index.rst | 18 +- .../hlapiv1/port/chimera/statistics/index.rst | 63 ++++- docs/source/api_ref/hlapiv1/port/control.rst | 118 ++++++++- docs/source/api_ref/hlapiv1/port/eee.rst | 70 +++++- docs/source/api_ref/hlapiv1/port/fault.rst | 21 +- .../api_ref/hlapiv1/port/filter/config.rst | 86 ++++++- .../api_ref/hlapiv1/port/filter/create.rst | 15 +- .../api_ref/hlapiv1/port/histogram/config.rst | 94 ++++++- .../api_ref/hlapiv1/port/histogram/create.rst | 16 +- .../api_ref/hlapiv1/port/identification.rst | 28 ++- docs/source/api_ref/hlapiv1/port/latency.rst | 27 +- .../hlapiv1/port/lengthterm/config.rst | 17 +- .../hlapiv1/port/lengthterm/create.rst | 17 +- docs/source/api_ref/hlapiv1/port/linkflap.rst | 22 +- .../api_ref/hlapiv1/port/matchterm/config.rst | 34 ++- .../api_ref/hlapiv1/port/matchterm/create.rst | 19 +- .../source/api_ref/hlapiv1/port/multicast.rst | 125 +++++++++- docs/source/api_ref/hlapiv1/port/payload.rst | 105 +++++++- .../api_ref/hlapiv1/port/pcs_pma/aneg.rst | 38 ++- .../api_ref/hlapiv1/port/pcs_pma/fec.rst | 16 +- .../hlapiv1/port/pcs_pma/linktrain.rst | 54 +++- .../port/pcs_pma/pulse_error_inject.rst | 27 +- .../hlapiv1/port/pcs_pma/rx_status.rst | 55 ++++- .../hlapiv1/port/pcs_pma/tx_config.rst | 50 +++- .../api_ref/hlapiv1/port/phy/eyediagram.rst | 74 +++++- .../api_ref/hlapiv1/port/phy/settings.rst | 23 +- docs/source/api_ref/hlapiv1/port/phy/tap.rst | 56 ++++- .../api_ref/hlapiv1/port/prbs/config.rst | 81 ++++-- .../api_ref/hlapiv1/port/prbs/stats.rst | 10 +- docs/source/api_ref/hlapiv1/port/preamble.rst | 22 +- .../api_ref/hlapiv1/port/reservation.rst | 23 +- docs/source/api_ref/hlapiv1/port/runt.rst | 27 +- docs/source/api_ref/hlapiv1/port/speed.rst | 83 ++++++- .../api_ref/hlapiv1/port/statistics/error.rst | 12 +- .../api_ref/hlapiv1/port/statistics/rx.rst | 177 +++++++++++-- .../api_ref/hlapiv1/port/statistics/tx.rst | 44 +++- docs/source/api_ref/hlapiv1/port/status.rst | 9 +- docs/source/api_ref/hlapiv1/port/tcvr.rst | 71 +++++- docs/source/api_ref/hlapiv1/port/traffic.rst | 69 +++++- .../api_ref/hlapiv1/port/tx_profile.rst | 149 +++++++++-- docs/source/api_ref/hlapiv1/port/uat.rst | 20 +- .../api_ref/hlapiv1/port/vulcan/address.rst | 4 + .../hlapiv1/port/vulcan/capabilities.rst | 2 + .../api_ref/hlapiv1/port/vulcan/capture.rst | 4 + .../port/vulcan/cg/application/index.rst | 2 + .../port/vulcan/cg/application/raw.rst | 32 +++ .../port/vulcan/cg/application/replay.rst | 30 +++ .../api_ref/hlapiv1/port/vulcan/cg/clear.rst | 2 + .../api_ref/hlapiv1/port/vulcan/cg/create.rst | 8 + .../hlapiv1/port/vulcan/cg/description.rst | 2 + .../hlapiv1/port/vulcan/cg/histogram.rst | 6 + .../api_ref/hlapiv1/port/vulcan/cg/l2.rst | 10 + .../api_ref/hlapiv1/port/vulcan/cg/l3.rst | 12 + .../hlapiv1/port/vulcan/cg/l4/index.rst | 2 + .../api_ref/hlapiv1/port/vulcan/cg/l4/tcp.rst | 22 ++ .../api_ref/hlapiv1/port/vulcan/cg/l4/udp.rst | 6 + .../api_ref/hlapiv1/port/vulcan/cg/load.rst | 4 + .../api_ref/hlapiv1/port/vulcan/cg/role.rst | 2 + .../api_ref/hlapiv1/port/vulcan/cg/status.rst | 2 + .../api_ref/hlapiv1/port/vulcan/cg/tls.rst | 16 ++ .../api_ref/hlapiv1/port/vulcan/clear.rst | 2 + .../hlapiv1/port/vulcan/counter/cg/replay.rst | 2 + .../hlapiv1/port/vulcan/counter/cg/tcp.rst | 14 ++ .../hlapiv1/port/vulcan/counter/cg/tls.rst | 8 + .../port/vulcan/counter/cg/transaction.rst | 2 + .../hlapiv1/port/vulcan/counter/cg/udp.rst | 8 + .../hlapiv1/port/vulcan/counter/cg/user.rst | 2 + .../hlapiv1/port/vulcan/counter/port/arp.rst | 6 + .../port/vulcan/counter/port/clear.rst | 2 + .../hlapiv1/port/vulcan/counter/port/eth.rst | 6 + .../hlapiv1/port/vulcan/counter/port/icmp.rst | 6 + .../hlapiv1/port/vulcan/counter/port/ipv4.rst | 6 + .../hlapiv1/port/vulcan/counter/port/ipv6.rst | 6 + .../hlapiv1/port/vulcan/counter/port/ndp.rst | 6 + .../hlapiv1/port/vulcan/counter/port/tcp.rst | 6 + .../port/vulcan/counter/port/total.rst | 6 + .../hlapiv1/port/vulcan/counter/port/udp.rst | 6 + .../hlapiv1/port/vulcan/identification.rst | 8 + .../api_ref/hlapiv1/port/vulcan/pps.rst | 2 + docs/source/api_ref/hlapiv1/stream/cdf.rst | 37 ++- .../api_ref/hlapiv1/stream/connectivity.rst | 51 +++- .../source/api_ref/hlapiv1/stream/content.rst | 81 +++++- docs/source/api_ref/hlapiv1/stream/create.rst | 14 +- .../stream/error_handling/error_inject.rst | 39 +++ .../stream/error_handling/insert_fcs.rst | 10 +- docs/source/api_ref/hlapiv1/stream/header.rst | 122 ++++++++- .../api_ref/hlapiv1/stream/identification.rst | 41 +++- .../hlapiv1/stream/modifier/modifier.rst | 49 +++- .../hlapiv1/stream/modifier/modifier_ext.rst | 51 +++- .../api_ref/hlapiv1/stream/tx_profile.rst | 118 +++++++-- docs/source/api_ref/hlapiv1/summary.py | 46 +++- docs/source/api_ref/hlapiv1/tester/action.rst | 32 ++- .../source/api_ref/hlapiv1/tester/address.rst | 37 ++- .../api_ref/hlapiv1/tester/capabilities.rst | 24 +- .../api_ref/hlapiv1/tester/identification.rst | 65 ++++- .../api_ref/hlapiv1/tester/reservation.rst | 32 ++- .../source/api_ref/hlapiv1/tester/session.rst | 6 + docs/source/api_ref/hlapiv1/tester/time.rst | 50 +++- .../source/api_ref/hlapiv1/tester/traffic.rst | 16 ++ 142 files changed, 5215 insertions(+), 767 deletions(-) rename docs/source/api_ref/hlapiv1/module/{ => vulcan}/capture.rst (99%) create mode 100644 docs/source/api_ref/hlapiv1/module/vulcan/index.rst rename docs/source/api_ref/hlapiv1/module/{ => vulcan}/license.rst (99%) rename docs/source/api_ref/hlapiv1/module/{ => vulcan}/pe.rst (99%) rename docs/source/api_ref/hlapiv1/module/{ => vulcan}/replay.rst (99%) rename docs/source/api_ref/hlapiv1/module/{ => vulcan}/system.rst (99%) rename docs/source/api_ref/hlapiv1/module/{ => vulcan}/tls.rst (99%) create mode 100644 docs/source/api_ref/hlapiv1/port/chimera/corruption/scheduling.rst create mode 100644 docs/source/api_ref/hlapiv1/port/chimera/drop/scheduling.rst create mode 100644 docs/source/api_ref/hlapiv1/port/chimera/duplication/scheduling.rst create mode 100644 docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/scheduling.rst create mode 100644 docs/source/api_ref/hlapiv1/port/chimera/misorder/scheduling.rst diff --git a/docs/source/api_ref/hlapiv1/module/capabilities.rst b/docs/source/api_ref/hlapiv1/module/capabilities.rst index 197241fe..4d50bc79 100644 --- a/docs/source/api_ref/hlapiv1/module/capabilities.rst +++ b/docs/source/api_ref/hlapiv1/module/capabilities.rst @@ -1,6 +1,17 @@ Capabilities ========================= +Gets the module capabilities. + +Corresponding CLI command: ``M_CAPABILITIES`` .. code-block:: python - await module.capabilities.get() \ No newline at end of file + # Capabilities + resp = await module.capabilities.get() + resp.can_advanced_timing + resp.can_local_time_adjust + resp.can_media_config + resp.can_ppm_sweep + resp.can_tsn + resp.is_chimera + resp.max_clock_ppm \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/identification.rst b/docs/source/api_ref/hlapiv1/module/identification.rst index 6f00f788..70649315 100644 --- a/docs/source/api_ref/hlapiv1/module/identification.rst +++ b/docs/source/api_ref/hlapiv1/module/identification.rst @@ -3,61 +3,110 @@ Identification Name ---------- +Gets the name of a module. + +Corresponding CLI command: ``M_NAME`` .. code-block:: python - await module.name.get() + # Name + resp = await module.name.get() + resp.name Description ----------- +Gets the user-defined description string of a module. + +Corresponding CLI command: ``M_COMMENT`` .. code-block:: python + # Description await module.comment.set(comment="description") - await module.comment.get() + + resp = await module.comment.get() + resp.comment Legacy Model ------------ +Gets the legacy model P/N name of a Xena test module. + +Corresponding CLI command: ``M_MODEL`` .. code-block:: python - await module.model.get() + # Legacy Model + resp = await module.model.get() + resp.model Model ------------- +Gets the model P/N name of a Xena test module. + +Corresponding CLI command: ``M_REVISION`` .. code-block:: python - await module.revision.get() + # Model + resp = await module.revision.get() + resp.revision Serial Number ----------------- +Gets the unique serial number of a module. + +Corresponding CLI command: ``M_SERIALNO`` .. code-block:: python - await module.serial_number.get() + # Serial Number + resp = await module.serial_number.get() + resp.serial_number -Firmeware Version +Firmware Version ----------------- +Gets the version number of the hardware image installed on a module. + +Corresponding CLI command: ``M_VERSIONNO`` .. code-block:: python - await module.version_number.get() + # Firmware Version + resp = await module.version_number.get() + resp.version Port Count ------------ +Gets the maximum number of ports on a module. + +.. note:: + + For a CFP-type module this number refers to the maximum number of ports possible on the module regardless of the media configuration. + + So if a CFP-type module can be set in for instance either 1x100G mode or 8x10G mode then this command will always return 8. + + If you want the current number of ports for a CFP-type module you need to read the M_CFPCONFIGEXT command which returns the number of current ports. + +Corresponding CLI command: ``M_PORTCOUNT`` .. code-block:: python - await module.port_count.get() + # Port Count + resp = await module.port_count.get() + resp.port_count Status ------ +Get status readings for the test module itself. + +Corresponding CLI command: ``M_STATUS`` .. code-block:: python - await module.status.get() \ No newline at end of file + # Status + resp = await module.status.get() + resp.temperature \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/impairment.rst b/docs/source/api_ref/hlapiv1/module/impairment.rst index 9792190f..a3009372 100644 --- a/docs/source/api_ref/hlapiv1/module/impairment.rst +++ b/docs/source/api_ref/hlapiv1/module/impairment.rst @@ -8,44 +8,89 @@ Impairment Bypass Mode -------------------- +Set emulator bypass mode. Emulator bypass mode will bypass the entire emulator +for minimum latency. + +Corresponding CLI command: ``M_EMULBYPASS`` .. code-block:: python - await module.emulator_bypass_mode.set_on() - await module.emulator_bypass_mode.set_off() - await module.emulator_bypass_mode.get() + # Chimera - Bypass Mode + if isinstance(module, modules.ModuleChimera): + await module.emulator_bypass_mode.set(on_off=enums.OnOff.ON) + await module.emulator_bypass_mode.set_on() + await module.emulator_bypass_mode.set(on_off=enums.OnOff.OFF) + await module.emulator_bypass_mode.set_off() + + resp = await module.emulator_bypass_mode.get() + resp.on_off Latency Mode -------------------- +Configures the latency mode for Chimera module. In extended latency mode, the FPGA allows all latency parameters to be 10 times higher, at the cost of reduced latency precision. + +.. note:: + + When change the latency mode, all latency configurations are reset on all ports in chimera module. + +Corresponding CLI command: ``M_LATENCYMODE`` .. code-block:: python - await module.latency_mode.set_normal() - await module.latency_mode.set_extended() - await module.latency_mode.get() + # Chimera - Latency Mode + if isinstance(module, modules.ModuleChimera): + await module.latency_mode.set(mode=enums.ImpairmentLatencyMode.NORMAL) + await module.latency_mode.set_normal() + await module.latency_mode.set(mode=enums.ImpairmentLatencyMode.EXTENDED) + await module.latency_mode.set_extended() + + resp = await module.latency_mode.get() + resp.mode TX Clock Source -------------------- +For test modules with advanced timing features, select what clock drives the port TX rates. + +Corresponding CLI command: ``M_TXCLOCKSOURCE_NEW`` .. code-block:: python - await module.tx_clock.source.set_modulelocalclock() - await module.tx_clock.source.set_p0rxclk() - await module.tx_clock.source.set_p1rxclk() - await module.tx_clock.source.set_p2rxclk() - await module.tx_clock.source.set_p3rxclk() - await module.tx_clock.source.set_p4rxclk() - await module.tx_clock.source.set_p5rxclk() - await module.tx_clock.source.set_p6rxclk() - await module.tx_clock.source.set_p7rxclk() - await module.tx_clock.source.get() + # Chimera - TX Clock Source + if isinstance(module, modules.ModuleChimera): + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.MODULELOCALCLOCK) + await module.tx_clock.source.set_modulelocalclock() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P0RXCLK) + await module.tx_clock.source.set_p0rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P1RXCLK) + await module.tx_clock.source.set_p1rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P2RXCLK) + await module.tx_clock.source.set_p2rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P3RXCLK) + await module.tx_clock.source.set_p3rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P4RXCLK) + await module.tx_clock.source.set_p4rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P5RXCLK) + await module.tx_clock.source.set_p5rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P6RXCLK) + await module.tx_clock.source.set_p6rxclk() + await module.tx_clock.source.set(tx_clock=enums.TXClockSource.P7RXCLK) + await module.tx_clock.source.set_p7rxclk() + + resp = await module.tx_clock.source.get() + resp.tx_clock TX Clock Status ---------------------------- +For test modules with advanced timing features, check whether a valid clock is present. + +Corresponding CLI command: ``M_TXCLOCKSTATUS_NEW`` .. code-block:: python - await module.tx_clock.status.get() \ No newline at end of file + # Chimera - TX Clock Status + if isinstance(module, modules.ModuleChimera): + resp = await module.tx_clock.status.get() + resp.status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/index.rst b/docs/source/api_ref/hlapiv1/module/index.rst index f17f29ca..ccc79596 100644 --- a/docs/source/api_ref/hlapiv1/module/index.rst +++ b/docs/source/api_ref/hlapiv1/module/index.rst @@ -6,4 +6,5 @@ Module .. toctree:: :glob: - * \ No newline at end of file + * + vulcan/index \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/media.rst b/docs/source/api_ref/hlapiv1/module/media.rst index 4c8601b9..748b5a73 100644 --- a/docs/source/api_ref/hlapiv1/module/media.rst +++ b/docs/source/api_ref/hlapiv1/module/media.rst @@ -3,35 +3,75 @@ Media Media Configuration ------------------- +For the test modules that support media configuration (check M_CAPABILITIES), this command sets the desired media type (front port). + +Corresponding CLI command: ``M_MEDIA`` .. code-block:: python - await module.media.set() - await module.media.get() + # Media Configuration + await module.media.set(media_config=enums.MediaConfigurationType.BASE_T1) + await module.media.set(media_config=enums.MediaConfigurationType.BASE_T1S) + await module.media.set(media_config=enums.MediaConfigurationType.CFP) + await module.media.set(media_config=enums.MediaConfigurationType.CFP4) + await module.media.set(media_config=enums.MediaConfigurationType.CXP) + await module.media.set(media_config=enums.MediaConfigurationType.OSFP800) + await module.media.set(media_config=enums.MediaConfigurationType.OSFP800_ANLT) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP112) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP112_ANLT) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP28_NRZ) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP28_PAM4) + await module.media.set(media_config=enums.MediaConfigurationType.QSFP56_PAM4) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD_NRZ) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD_PAM4) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD800) + await module.media.set(media_config=enums.MediaConfigurationType.QSFPDD800_ANLT) + await module.media.set(media_config=enums.MediaConfigurationType.SFP112) + await module.media.set(media_config=enums.MediaConfigurationType.SFP28) + await module.media.set(media_config=enums.MediaConfigurationType.SFP56) + await module.media.set(media_config=enums.MediaConfigurationType.SFPDD) + + resp = await module.media.get() + resp.media_config Supported Media --------------- +Shows the available speeds on a module. The structure of the returned value is +``[ [ ] ]``. +``[ ]`` is repeated until all speeds supported by the ```` has been listed. +``[ ]`` is repeated for all cage types on the module including the related `` `` information. + +Corresponding CLI command: ``M_MEDIASUPPORT`` .. code-block:: python - await module.available_speeds.get() + resp = await module.available_speeds.get() + resp.media_info_list Port Configuration ------------------ +This property defines the current number of ports and the speed of each of them +on a CFP test module. The following combinations are possible: 2x10G, 4x10G, 8x10G, +2x25G, 4x25G, 8x25G, 1x40G, 2x40G, 2x50G, 4x50G, 8x50G, 1x100G, 2x100G, 4x100G, 2x200G, and 1x400G. + +.. note:: + + ```` is a list of integers, where the first element is the number of ports followed by a number of port speeds in Mbps. + + The number of port speeds equals the value of the number of ports. + + For example if the configuration is 4x25G, ```` will be ``[4, 25000, 25000, 25000, 25000]``. + +Corresponding CLI command: ``M_CFPCONFIGEXT`` .. code-block:: python + # Port Configuration await module.cfp.config.set(portspeed_list=[1, 800000]) await module.cfp.config.set(portspeed_list=[2, 400000, 400000]) await module.cfp.config.set(portspeed_list=[4, 200000, 200000, 200000, 200000]) await module.cfp.config.set(portspeed_list=[8, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000]) - await module.cfp.config.get() - - -CFP Type ---------------- - -.. code-block:: python - await module.cfp.type.get() \ No newline at end of file + resp = await module.cfp.config.get() + resp.portspeed_list diff --git a/docs/source/api_ref/hlapiv1/module/reservation.rst b/docs/source/api_ref/hlapiv1/module/reservation.rst index edeecb2e..85ffd7cf 100644 --- a/docs/source/api_ref/hlapiv1/module/reservation.rst +++ b/docs/source/api_ref/hlapiv1/module/reservation.rst @@ -1,25 +1,43 @@ Reservation ========================= -Action ------------ +Reservation Action +------------------- +Set this command to reserve, release, or relinquish a module itself (as +opposed to its ports). The module must be reserved before its hardware image can +be upgraded. The owner of the session must already have been specified. +Reservation will fail if the chassis or any ports are reserved for other users. + +.. note:: + + The reservation parameters are slightly asymmetric with respect to set/get. When querying for the current reservation state, the chassis will use these values. + +Corresponding CLI command: ``M_RESERVATION`` .. code-block:: python + # Reservation + await module.reservation.set(operation=enums.ReservedAction.RELEASE) await module.reservation.set_release() + await module.reservation.set(operation=enums.ReservedAction.RELINQUISH) await module.reservation.set_relinquish() + await module.reservation.set(operation=enums.ReservedAction.RESERVE) await module.reservation.set_reserve() - await module.reservation.get() - module.is_released() - module.on_reservation_change(_callback_func()) + + resp = await module.reservation.get() + resp.operation Reserved By ----------- +Identify the user who has a module reserved. Returns an empty string if the +module is not currently reserved by anyone. + +Corresponding CLI command: ``M_RESERVEDBY`` .. code-block:: python - await module.reserved_by.get() - module.is_reserved_by_me() - module.on_reserved_by_change(_callback_func()) + # Reserved By + resp = await module.reserved_by.get() + resp.username diff --git a/docs/source/api_ref/hlapiv1/module/time.rst b/docs/source/api_ref/hlapiv1/module/time.rst index 010efda3..0e10c560 100644 --- a/docs/source/api_ref/hlapiv1/module/time.rst +++ b/docs/source/api_ref/hlapiv1/module/time.rst @@ -3,44 +3,102 @@ Time and Clock Local Clock Adjust ------------------ +Makes small adjustments to the local clock of the test module, which drives the +TX rate of the test ports. + +Corresponding CLI command: ``M_CLOCKPPB`` .. code-block:: python - await module.timing.clock_local_adjust.set() - await module.timing.clock_local_adjust.get() + # Local Clock Adjust + await module.timing.clock_local_adjust.set(ppb=10) + + resp = await module.timing.clock_local_adjust.get() + resp.ppb Clock Sync Status ---------------------------- +Get module's clock sync status. + +Corresponding CLI command: ``M_CLOCKSYNCSTATUS`` .. code-block:: python - await module.timing.clock_sync_status.get() + # Clock Sync Status + resp = await module.timing.clock_sync_status.get() + resp.m_clock_diff + resp.m_correction + resp.m_is_steady_state + resp.m_tune_is_increase + resp.m_tune_value Clock Source ---------------------------- +Control how the test module timestamp clock is running, either freely in the +chassis or locked to an external system time. Running with free chassis time +allows nano-second precision measurements of latencies, but only when the +transmitting and receiving ports are in the same chassis. Running with locked +external time enables inter-chassis latency measurements, but can introduce +small time discontinuities as the test module time is adjusted. + +Corresponding CLI command: ``M_TIMESYNC`` .. code-block:: python + # Clock Source + await module.timing.source.set(source=enums.TimingSource.CHASSIS) await module.timing.source.set_chassis() + await module.timing.source.set(source=enums.TimingSource.EXTERNAL) await module.timing.source.set_external() + await module.timing.source.set(source=enums.TimingSource.MODULE) await module.timing.source.set_module() - await module.timing.source.get() + + resp = await module.timing.source.get() + resp.source Clock PPM Sweep Configuration ----------------------------- +.. important:: + + For Freya modules only + +Start and stop deviation sweep the local clock of the test module, which drives the TX rate of the test ports. + +The sweep is independent of the M_CLOCKPPB parameter, i.e. the sweep uses the deviation set by M_CLOCKPPB as its zero point. + +Corresponding CLI command: ``M_CLOCKPPBSWEEP`` + .. code-block:: python - await module.clock_sweep.config.set() - await module.clock_sweep.config.get() + # Clock PPM Sweep Configuration + FREYA_MODULES = (modules.MFreya800G4S1P_a, modules.MFreya800G4S1P_b, modules.MFreya800G4S1POSFP_a, modules.MFreya800G4S1POSFP_b) + if isinstance(module, FREYA_MODULES): + await module.clock_sweep.config.set(mode=enums.PPMSweepMode.OFF, ppb_step=10, step_delay=10, max_ppb=10, loops=1) + await module.clock_sweep.config.set(mode=enums.PPMSweepMode.TRIANGLE, ppb_step=10, step_delay=10, max_ppb=10, loops=1) + + resp = await module.clock_sweep.config.get() + resp.mode + resp.ppb_step + resp.step_delay + resp.max_ppb + resp.loops Clock PPM Sweep Status ----------------------------- +Return the current status of the M_CLOCKPPBSWEEP command. + +Corresponding CLI command: ``M_CLOCKSWEEPSTATUS`` .. code-block:: python - await module.clock_sweep.status.get() + # Clock PPM Sweep Status + if isinstance(module, FREYA_MODULES): + resp = await module.clock_sweep.status.get() + resp.curr_step + resp.curr_sweep + resp.max_steps diff --git a/docs/source/api_ref/hlapiv1/module/time_adv.rst b/docs/source/api_ref/hlapiv1/module/time_adv.rst index 244950ad..29ca9cdb 100644 --- a/docs/source/api_ref/hlapiv1/module/time_adv.rst +++ b/docs/source/api_ref/hlapiv1/module/time_adv.rst @@ -3,77 +3,143 @@ Advanced Timing TX Clock Filter Loop Bandwidth ------------------------------ +For test modules with advanced timing features, the loop bandwidth on the TX +clock filter. + +Corresponding CLI command: ``M_TXCLOCKFILTER_NEW`` .. code-block:: python + # TX Clock Filter Loop Bandwidth + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW103HZ) await module.advanced_timing.clock_tx.filter.set_bw103hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW1683HZ) await module.advanced_timing.clock_tx.filter.set_bw1683hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW207HZ) await module.advanced_timing.clock_tx.filter.set_bw207hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW416HZ) await module.advanced_timing.clock_tx.filter.set_bw416hz() + await module.advanced_timing.clock_tx.filter.set(filter_bandwidth=enums.LoopBandwidth.BW7019HZ) await module.advanced_timing.clock_tx.filter.set_bw7019hz() - await module.advanced_timing.clock_tx.filter.get() + + resp = await module.advanced_timing.clock_tx.filter.get() + resp.filter_bandwidth TX Clock Source ---------------------------- +For test modules with advanced timing features, select what clock drives the port TX +rates. + +Corresponding CLI command: ``M_TXCLOCKSOURCE_NEW`` .. code-block:: python + # TX Clock Source + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.MODULELOCALCLOCK) await module.advanced_timing.clock_tx.source.set_modulelocalclock() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P0RXCLK) await module.advanced_timing.clock_tx.source.set_p0rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P1RXCLK) await module.advanced_timing.clock_tx.source.set_p1rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P2RXCLK) await module.advanced_timing.clock_tx.source.set_p2rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P3RXCLK) await module.advanced_timing.clock_tx.source.set_p3rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P4RXCLK) await module.advanced_timing.clock_tx.source.set_p4rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P5RXCLK) await module.advanced_timing.clock_tx.source.set_p5rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P6RXCLK) await module.advanced_timing.clock_tx.source.set_p6rxclk() + await module.advanced_timing.clock_tx.source.set(tx_clock=enums.TXClockSource.P7RXCLK) await module.advanced_timing.clock_tx.source.set_p7rxclk() - await module.advanced_timing.clock_tx.source.get() + + resp = await module.advanced_timing.clock_tx.source.get() + resp.tx_clock TX Clock Status ---------------------------- +For test modules with advanced timing features, check whether a valid clock is present. + +Corresponding CLI command: ``M_TXCLOCKSTATUS_NEW`` .. code-block:: python - await module.advanced_timing.clock_tx.status.get() + # TX Clock Status + resp = await module.advanced_timing.clock_tx.status.get() + resp.status SMA Status ---------------------------- +For test modules with SMA connectors, this returns the status of the SMA input. + +Corresponding CLI command: ``M_SMASTATUS`` .. code-block:: python - await module.advanced_timing.sma.status.get() + # SMA Status + resp = await module.advanced_timing.sma.status.get() + resp.status SMA Input ---------------------------- +For test modules with SMA (SubMiniature version A) connectors, selects the function of the SMA input. + +Corresponding CLI command: ``M_SMAINPUT`` .. code-block:: python + # SMA Input + await module.advanced_timing.sma.input.set(sma_in=enums.SMAInputFunction.NOT_USED) await module.advanced_timing.sma.input.set_notused() + await module.advanced_timing.sma.input.set(sma_in=enums.SMAInputFunction.TX10MHZ) await module.advanced_timing.sma.input.set_tx10mhz() + await module.advanced_timing.sma.input.set(sma_in=enums.SMAInputFunction.TX2MHZ) await module.advanced_timing.sma.input.set_tx2mhz() - await module.advanced_timing.sma.input.get() + + resp = await module.advanced_timing.sma.input.get() + resp.sma_in SMA Output ---------------------------- +For test modules with SMA (SubMiniature version A) connectors, selects the function of the SMA output. + +Corresponding CLI command: ``M_SMAOUTPUT`` .. code-block:: python + # SMA Output + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.DISABLED) await module.advanced_timing.sma.output.set_disabled() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P0RXCLK) await module.advanced_timing.sma.output.set_p0rxclk() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P0RXCLK2MHZ) await module.advanced_timing.sma.output.set_p0rxclk2mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P0SOF) await module.advanced_timing.sma.output.set_p0sof() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P1RXCLK) await module.advanced_timing.sma.output.set_p1rxclk() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P1RXCLK2MHZ) await module.advanced_timing.sma.output.set_p1rxclk2mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.P1SOF) await module.advanced_timing.sma.output.set_p1sof() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.PASSTHROUGH) await module.advanced_timing.sma.output.set_passthrough() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF10MHZ) await module.advanced_timing.sma.output.set_ref10mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF125MHZ) await module.advanced_timing.sma.output.set_ref125mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF156MHZ) await module.advanced_timing.sma.output.set_ref156mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.REF2MHZ) await module.advanced_timing.sma.output.set_ref2mhz() + await module.advanced_timing.sma.output.set(sma_out=enums.SMAOutputFunction.TS_PPS) await module.advanced_timing.sma.output.set_ts_pps() - await module.advanced_timing.sma.output.get() \ No newline at end of file + + resp = await module.advanced_timing.sma.output.get() + resp.sma_out \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/capture.rst b/docs/source/api_ref/hlapiv1/module/vulcan/capture.rst similarity index 99% rename from docs/source/api_ref/hlapiv1/module/capture.rst rename to docs/source/api_ref/hlapiv1/module/vulcan/capture.rst index 72fab147..cf9644cd 100644 --- a/docs/source/api_ref/hlapiv1/module/capture.rst +++ b/docs/source/api_ref/hlapiv1/module/vulcan/capture.rst @@ -9,6 +9,7 @@ Capture List PCAP Files -------------------- + .. code-block:: python await module.capture.file_list.get() @@ -17,6 +18,7 @@ List PCAP Files List PCAP BSON Files -------------------- + .. code-block:: python await module.capture.file_list_bson.get() @@ -25,6 +27,7 @@ List PCAP BSON Files Delete PCAP Files -------------------- + .. code-block:: python await module.capture.file_delete.set() @@ -33,6 +36,7 @@ Delete PCAP Files PCAP Parser Configuration ------------------------- + .. code-block:: python await module.capture.parse.parser_params.set() @@ -42,6 +46,7 @@ PCAP Parser Configuration Start PCAP Parser -------------------- + .. code-block:: python await module.capture.parse.start.set() @@ -50,6 +55,7 @@ Start PCAP Parser Stop PCAP Parser -------------------- + .. code-block:: python await module.capture.parse.stop.set() @@ -58,6 +64,7 @@ Stop PCAP Parser PCAP Parser State -------------------- + .. code-block:: python await module.capture.parse.state.get() @@ -66,6 +73,7 @@ PCAP Parser State Buffer Size -------------------- + .. code-block:: python await module.capture.size.set_full() diff --git a/docs/source/api_ref/hlapiv1/module/vulcan/index.rst b/docs/source/api_ref/hlapiv1/module/vulcan/index.rst new file mode 100644 index 00000000..90dac3e0 --- /dev/null +++ b/docs/source/api_ref/hlapiv1/module/vulcan/index.rst @@ -0,0 +1,11 @@ +Vulcan +========================= + +.. note:: + + Applicable to Vulcan module only. + +.. toctree:: + :glob: + + * \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/license.rst b/docs/source/api_ref/hlapiv1/module/vulcan/license.rst similarity index 99% rename from docs/source/api_ref/hlapiv1/module/license.rst rename to docs/source/api_ref/hlapiv1/module/vulcan/license.rst index 1fe5c612..098ad995 100644 --- a/docs/source/api_ref/hlapiv1/module/license.rst +++ b/docs/source/api_ref/hlapiv1/module/vulcan/license.rst @@ -9,6 +9,7 @@ License Clock Windback -------------------- + .. code-block:: python await module.license.clock_windback.get() @@ -17,6 +18,7 @@ Clock Windback Demo Information -------------------- + .. code-block:: python await module.license.demo_info.get() @@ -25,6 +27,7 @@ Demo Information Online Mode -------------------- + .. code-block:: python await module.license.online_mode.set_offline() @@ -35,6 +38,7 @@ Online Mode Update ---------------------------- + .. code-block:: python await module.license.update.set() @@ -43,6 +47,7 @@ Update Update Status ---------------------------- + .. code-block:: python await module.license.update_status.get() @@ -51,6 +56,7 @@ Update Status Management Information ---------------------------- + .. code-block:: python await module.license.management_info.get() @@ -59,6 +65,7 @@ Management Information List License BSON Files ---------------------------- + .. code-block:: python await module.license.list_bson.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/pe.rst b/docs/source/api_ref/hlapiv1/module/vulcan/pe.rst similarity index 99% rename from docs/source/api_ref/hlapiv1/module/pe.rst rename to docs/source/api_ref/hlapiv1/module/vulcan/pe.rst index cd60bc0e..d8f7d281 100644 --- a/docs/source/api_ref/hlapiv1/module/pe.rst +++ b/docs/source/api_ref/hlapiv1/module/vulcan/pe.rst @@ -9,6 +9,7 @@ Packet Engine License Information -------------------- + .. code-block:: python await module.packet_engine.license_info.get() @@ -17,6 +18,7 @@ License Information Mode -------------------- + .. code-block:: python await module.packet_engine.mode.set_advanced() @@ -27,6 +29,7 @@ Mode Reservation -------------------- + .. code-block:: python await module.packet_engine.reserve.set() @@ -36,6 +39,7 @@ Reservation Update ---------------------------- + .. code-block:: python await module.license.update.set() @@ -44,6 +48,7 @@ Update Update Status ---------------------------- + .. code-block:: python await module.license.update_status.get() @@ -52,6 +57,7 @@ Update Status Management Information ---------------------------- + .. code-block:: python await module.license.management_info.get() @@ -60,6 +66,7 @@ Management Information List License BSON Files ---------------------------- + .. code-block:: python await module.license.list_bson.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/replay.rst b/docs/source/api_ref/hlapiv1/module/vulcan/replay.rst similarity index 99% rename from docs/source/api_ref/hlapiv1/module/replay.rst rename to docs/source/api_ref/hlapiv1/module/vulcan/replay.rst index 9a43df14..a1a5610d 100644 --- a/docs/source/api_ref/hlapiv1/module/replay.rst +++ b/docs/source/api_ref/hlapiv1/module/vulcan/replay.rst @@ -9,6 +9,7 @@ PCAP Replay List Replay Files -------------------- + .. code-block:: python await module.replay.file.list.get() @@ -17,6 +18,7 @@ List Replay Files List Replay BSON Files ---------------------- + .. code-block:: python await module.replay.file.list_bson.get() @@ -25,6 +27,7 @@ List Replay BSON Files Delete Replay File -------------------- + .. code-block:: python await module.replay.file.delete.set() diff --git a/docs/source/api_ref/hlapiv1/module/system.rst b/docs/source/api_ref/hlapiv1/module/vulcan/system.rst similarity index 99% rename from docs/source/api_ref/hlapiv1/module/system.rst rename to docs/source/api_ref/hlapiv1/module/vulcan/system.rst index ff379d18..3622d81c 100644 --- a/docs/source/api_ref/hlapiv1/module/system.rst +++ b/docs/source/api_ref/hlapiv1/module/vulcan/system.rst @@ -9,6 +9,7 @@ System Memory Information -------------------- + .. code-block:: python await module.memory_info.get() @@ -17,6 +18,7 @@ Memory Information Identifier -------------------- + .. code-block:: python await module.module_system.id.get() @@ -25,6 +27,7 @@ Identifier Status -------------------- + .. code-block:: python await module.module_system.status.get() @@ -33,6 +36,7 @@ Status Time ---------------------------- + .. code-block:: python await module.module_system.time.set() @@ -42,6 +46,7 @@ Time Compatible Client Version ---------------------------- + .. code-block:: python await module.compatible_client_version.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/module/tls.rst b/docs/source/api_ref/hlapiv1/module/vulcan/tls.rst similarity index 99% rename from docs/source/api_ref/hlapiv1/module/tls.rst rename to docs/source/api_ref/hlapiv1/module/vulcan/tls.rst index 0816f342..8a53c687 100644 --- a/docs/source/api_ref/hlapiv1/module/tls.rst +++ b/docs/source/api_ref/hlapiv1/module/vulcan/tls.rst @@ -5,6 +5,7 @@ TLS Cipher For Vulcan module only. + .. code-block:: python await module.tls_cipher.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/action.rst b/docs/source/api_ref/hlapiv1/port/action.rst index ac9d17ef..10ff2303 100644 --- a/docs/source/api_ref/hlapiv1/port/action.rst +++ b/docs/source/api_ref/hlapiv1/port/action.rst @@ -3,17 +3,32 @@ Action Reset ---------------- +Reset port-level parameters to default values, and delete all streams, filters, +capture, and dataset definitions. + +Corresponding CLI command: ``P_RESET`` .. code-block:: python + # Reset await port.reset.set() Flash ---------------- +Make the test port LED for a particular port flash on and off with a 1-second +interval. This is helpful when you need to identify a specific port within a +chassis. + +Corresponding CLI command: ``P_FLASH`` .. code-block:: python + # Flash + await port.flash.set(on_off=enums.OnOff.ON) await port.flash.set_on() + await port.flash.set(on_off=enums.OnOff.OFF) await port.flash.set_off() - await port.flash.get() \ No newline at end of file + + resp = await port.flash.get() + resp.on_off \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/address.rst b/docs/source/api_ref/hlapiv1/port/address.rst index c5178843..e4621deb 100644 --- a/docs/source/api_ref/hlapiv1/port/address.rst +++ b/docs/source/api_ref/hlapiv1/port/address.rst @@ -3,80 +3,178 @@ Port Address MAC Address ----------- +A 48-bit Ethernet MAC address specified for a port. This address is used as the +default source MAC field in the header of generated traffic for the port, and is +also used for support of the ARP protocol. + +Corresponding CLI command: ``P_MACADDRESS`` .. code-block:: python - await port.net_config.mac_address.set() - await port.net_config.mac_address.get() + # MAC Address + await port.net_config.mac_address.set(mac_address=Hex("000000000000")) + + resp = await port.net_config.mac_address.get() + resp.mac_address IPv4 Address ------------ +An IPv4 network configuration specified for a port. The address is used as the +default source address field in the IP header of generated traffic, and the +configuration is also used for support of the ARP and PING protocols. + +Corresponding CLI command: ``P_IPADDRESS`` .. code-block:: python - await port.net_config.ipv4.address.set() - await port.net_config.ipv4.address.get() + # IPv4 Address + await port.net_config.ipv4.address.set( + ipv4_address=ipaddress.IPv4Address("10.10.10.10"), + subnet_mask=ipaddress.IPv4Address("255.255.255.0"), + gateway=ipaddress.IPv4Address("10.10.1.1"), + wild=ipaddress.IPv4Address("0.0.0.0")) + + resp = await port.net_config.ipv4.address.get() + resp.ipv4_address + resp.gateway + resp.subnet_mask + resp.wild ARP Reply ----------- +Whether the port replies to ARP requests. The +port can reply to incoming ARP requests by mapping the IP address specified for +the port to the MAC address specified for the port. ARP/NDP reply generation is +independent of whether traffic and capture is on for the port. + +Corresponding CLI command: ``P_ARPREPLY`` .. code-block:: python - await port.net_config.ipv4.arp_reply.set() - await port.net_config.ipv4.arp_reply.get() + # ARP Reply + await port.net_config.ipv4.arp_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv4.arp_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv4.arp_reply.get() + resp.on_off Ping Reply ----------- +Whether the port replies to IPv4/IPv6 PING. The port can +reply to incoming IPv4/IPv6 PING requests to the IP address specified for the port. IPv4/IPv6 PING +reply generation is independent of whether traffic and capture is on for the port. + +Corresponding CLI command: ``P_PINGREPLY`` .. code-block:: python - await port.net_config.ipv4.ping_reply.set() - await port.net_config.ipv4.ping_reply.get() + # Ping Reply + await port.net_config.ipv4.ping_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv4.ping_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv4.ping_reply.get() + resp.on_off IPv6 Address ------------ +An IPv6 network configuration specified for a port. The address is used as the +default source address field in the IP header of generated traffic, and the +configuration is also used for support of the NDP and PINGv6 protocols. + +Corresponding CLI command: ``P_IPV6ADDRESS`` .. code-block:: python - await port.net_config.ipv6.address.set() - await port.net_config.ipv6.address.get() + # IPv6 Address + await port.net_config.ipv6.address.set( + ipv6_address=ipaddress.IPv6Address("fc00::0002"), + gateway=ipaddress.IPv6Address("fc00::0001"), + subnet_prefix=7, + wildcard_prefix=0 + ) + + resp = await port.net_config.ipv6.address.get() + resp.ipv6_address + resp.gateway + resp.subnet_prefix + resp.wildcard_prefix NDP Reply ----------- +Whether the port generates replies using the IPv6 Network Discovery Protocol. +The port can reply to incoming NDP Neighbor Solicitations by mapping the IPv6 address +specified for the port to the MAC address specified for the port. NDP reply +generation is independent of whether traffic and capture is on for the port. + +Corresponding CLI command: ``P_ARPV6REPLY`` .. code-block:: python - await port.net_config.ipv6.arp_reply.set() - await port.net_config.ipv6.arp_reply.get() + # NDP Reply + await port.net_config.ipv6.arp_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv6.arp_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv6.arp_reply.get() + resp.on_off IPv6 Ping Reply --------------- +Whether the port generates PINGv6 replies using the ICMP protocol received over +IPv6. The port can reply to incoming PINGv6 requests to the IPv6 address +specified for the port. PINGv6 reply generation is independent of whether +traffic and capture is on for the port. + +Corresponding CLI command: ``P_PINGV6REPLY`` .. code-block:: python - await port.net_config.ipv6.ping_reply.set() - await port.net_config.ipv6.ping_reply.get() + # IPv6 Ping Reply + await port.net_config.ipv6.ping_reply.set(on_off=enums.OnOff.ON) + await port.net_config.ipv6.ping_reply.set(on_off=enums.OnOff.OFF) + + resp = await port.net_config.ipv6.ping_reply.get() + resp.on_off ARP Table ------------ +Port ARP table used to reply to incoming ARP requests. + +Corresponding CLI command: ``P_ARPRXTABLE`` + +.. seealso:: + + Detailed script example can be found at `ip_streams_arp_table `_ .. code-block:: python - await port.arp_rx_table.set() - await port.arp_rx_table.get() + # ARP Table + await port.arp_rx_table.set(chunks=[]) + + resp = await port.arp_rx_table.get() + resp.chunks NDP Table ------------ +Port NDP table used to reply to incoming NDP Neighbor Solicitation. + +Corresponding CLI command: ``P_NDPRXTABLE`` + +.. seealso:: + + Detailed script example can be found at `ip_streams_arp_table `_ .. code-block:: python - await port.ndp_rx_table.set() - await port.ndp_rx_table.get() \ No newline at end of file + # NDP Table + await port.ndp_rx_table.set(chunks=[]) + + resp = await port.ndp_rx_table.get() + resp.chunks \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/capabilities.rst b/docs/source/api_ref/hlapiv1/port/capabilities.rst index 26abb7a3..69879a16 100644 --- a/docs/source/api_ref/hlapiv1/port/capabilities.rst +++ b/docs/source/api_ref/hlapiv1/port/capabilities.rst @@ -1,5 +1,8 @@ Capabilities ========================= +A series of integer values specifying various internal limits of a port. + +Corresponding CLI command: ``P_CAPABILITIES`` .. code-block:: python diff --git a/docs/source/api_ref/hlapiv1/port/capture.rst b/docs/source/api_ref/hlapiv1/port/capture.rst index 2c2c26e7..5b54844f 100644 --- a/docs/source/api_ref/hlapiv1/port/capture.rst +++ b/docs/source/api_ref/hlapiv1/port/capture.rst @@ -3,50 +3,118 @@ Capture Trigger Criteria ---------------- +The criteria for when to start and stop the capture process for a port. Even +when capture is enabled with ``P_CAPTURE``, the actual capturing of packets can be +delayed until a particular start criteria is met by a received packet. +Likewise, a stop criteria can be specified, based on a received packet. If no +explicit stop criteria is specified, capture stops when the internal buffer +runs full. In buffer overflow situations, if there is an explicit stop +criteria, then the latest packets will be retained (and the early ones +discarded), and otherwise, the earliest packets are retained (and the later +ones discarded). + +Corresponding CLI command: ``PC_TRIGGER`` + +.. seealso:: + + Detailed script example can be found in `here `_ .. code-block:: python - await port.capturer.trigger.set() - await port.capturer.trigger.get() + # Capture Trigger Criteria, + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.ON, start_criteria_filter=0, stop_criteria=enums.StopTrigger.FULL, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.ON, start_criteria_filter=0, stop_criteria=enums.StopTrigger.USERSTOP, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.FCSERR, start_criteria_filter=0, stop_criteria=enums.StopTrigger.FCSERR, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.PLDERR, start_criteria_filter=0, stop_criteria=enums.StopTrigger.PLDERR, stop_criteria_filter=0) + await port.capturer.trigger.set(start_criteria=enums.StartTrigger.FILTER, start_criteria_filter=0, stop_criteria=enums.StopTrigger.FILTER, stop_criteria_filter=0) + + resp = await port.capturer.trigger.get() + resp.start_criteria + resp.start_criteria_filter + resp.stop_criteria + resp.stop_criteria_filter Frame to Keep -------------- +Which packets to keep once the start criteria has been triggered for a port. +Also how big a portion of each packet to retain, saving space for more packets +in the capture buffer. + +.. seealso:: + + Detailed script example can be found in `here `_ + +Corresponding CLI command: ``PC_KEEP`` .. code-block:: python + # Capture - Frame to Keep, + await port.capturer.keep.set(kind=enums.PacketType.ALL, index=0, byte_count=0) await port.capturer.keep.set_all() + await port.capturer.keep.set(kind=enums.PacketType.FCSERR, index=0, byte_count=0) await port.capturer.keep.set_fcserr() + await port.capturer.keep.set(kind=enums.PacketType.FILTER, index=0, byte_count=0) await port.capturer.keep.set_filter() + await port.capturer.keep.set(kind=enums.PacketType.NOTPLD, index=0, byte_count=0) await port.capturer.keep.set_notpld() + await port.capturer.keep.set(kind=enums.PacketType.PLDERR, index=0, byte_count=0) await port.capturer.keep.set_plderr() + await port.capturer.keep.set(kind=enums.PacketType.TPLD, index=0, byte_count=0) await port.capturer.keep.set_tpld() - await port.capturer.keep.get() + + resp = await port.capturer.keep.get() + resp.kind + resp.index + resp.byte_count State ----------- +Whether a port is capturing packets. When on, the port retains the received +packets and makes them available for inspection. The capture criteria are +configured using the ``PC_xxx`` parameters. While capture is on the capture +parameters cannot be changed. + +Corresponding CLI command: ``P_CAPTURE`` .. code-block:: python + # Capture - State + await port.capturer.state.set(on_off=enums.StartOrStop.START) await port.capturer.state.set_start() + await port.capturer.state.set(on_off=enums.StartOrStop.STOP) await port.capturer.state.set_stop() - await port.capturer.state.get() + + resp = await port.capturer.state.get() + resp.on_off Statistics ----------- +Obtains the number of packets currently in the capture buffer for a port. The +count is reset to zero when capture is turned on. + +Corresponding CLI command: ``PC_STATS`` .. code-block:: python - await port.capturer.stats.get() + # Capture - Statistics + resp = await port.capturer.stats.get() + resp.start_time + resp.status Read Captured Packets --------------------- +Obtains the raw bytes of a captured packet for a port. The packet data may be +truncated if the :class:`PC_KEEP` command specified a limit on the number of bytes kept. + +Corresponding CLI command: ``PC_PACKET`` .. code-block:: python + # Read Captured Packets pkts = await port.capturer.obtain_captured() for i in range(len(pkts)): resp = await pkts[i].packet.get() diff --git a/docs/source/api_ref/hlapiv1/port/chimera/config.rst b/docs/source/api_ref/hlapiv1/port/chimera/config.rst index 3e8ef336..86f308c2 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/config.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/config.rst @@ -3,30 +3,45 @@ Impairment Configuration Impairment On/OFF ------------------------- +The action determines if emulation functionality is enabled or disabled. + +Corresponding CLI command: ``P_EMULATE`` .. code-block:: python - await port.emulate.set_on() - await port.emulate.set_off() - await port.emulate.get() - port.on_emulate_change(_callback_func) + await port.emulate.set(action=enums.OnOff.ON) + await port.emulate.set(action=enums.OnOff.OFF) + + resp = await port.emulate.get() + resp.action FCS Error Action ------------------------- +The action on packets with FCS errors on a port. + +Corresponding CLI command: ``PE_FCSDROP`` .. code-block:: python - await port.emulation.drop_fcs_errors.set_on() - await port.emulation.drop_fcs_errors.set_off() - await port.emulation.drop_fcs_errors.get() + await port.emulation.drop_fcs_errors.set(action=enums.OnOff.ON) + await port.emulation.drop_fcs_errors.set(action=enums.OnOff.OFF) + + resp = await port.emulation.drop_fcs_errors.get() + resp.action TPLD Mode ------------------------- +The action indicates the TPLD mode to be used per port. + +Corresponding CLI command: ``PE_TPLDMODE`` .. code-block:: python - await port.emulation.tpld_mode.set_normal() - await port.emulation.tpld_mode.set_micro() - await port.emulation.tpld_mode.get() + # Set TPLD mode + await port.emulation.tpld_mode.set(mode=enums.TPLDMode.NORMAL) + await port.emulation.tpld_mode.set(mode=enums.TPLDMode.MICRO) + + resp = await port.emulation.tpld_mode.get() + resp.mode diff --git a/docs/source/api_ref/hlapiv1/port/chimera/corruption/configuration.rst b/docs/source/api_ref/hlapiv1/port/chimera/corruption/configuration.rst index 55346b65..047ca2fe 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/corruption/configuration.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/corruption/configuration.rst @@ -1,12 +1,28 @@ -Configuration +Corruption Configuration ========================= Type ------------------------- +Configures impairment corruption type. + +.. note:: + + IP / TCP / UDP corruption modes are not supported on default flow (0) + +Corresponding CLI command: ``PE_CORRUPT`` .. code-block:: python - await port.emulation.flows[flow_idx].corruption.set_off() - await port.emulation.flows[flow_idx].corruption.set_eth() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.corruption.set(corruption_type=enums.CorruptionType.OFF) + await flow.corruption.set(corruption_type=enums.CorruptionType.ETH) + await flow.corruption.set(corruption_type=enums.CorruptionType.IP) + await flow.corruption.set(corruption_type=enums.CorruptionType.TCP) + await flow.corruption.set(corruption_type=enums.CorruptionType.UDP) + await flow.corruption.set(corruption_type=enums.CorruptionType.BER) + + resp = await flow.corruption.get() + resp.corruption_type + diff --git a/docs/source/api_ref/hlapiv1/port/chimera/corruption/distribution.rst b/docs/source/api_ref/hlapiv1/port/chimera/corruption/distribution.rst index 44724faf..c82f7fb1 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/corruption/distribution.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/corruption/distribution.rst @@ -1,117 +1,283 @@ -Distribution +Corruption Distribution ========================= -Off +Enable/Disable ----------------------- +Control whether this impairment distribution is enabled. + +.. note:: + + This command is not applicable for PE_BANDPOLICER and PE_BANDSHAPER because they have a separate ``ON / OFF`` parameter. + +Corresponding CLI command: ``PED_ENABLE`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.off.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.off.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.enable.set(action=enums.OnOff.ON) + await flow.impairment_distribution.corruption_type_config.enable.set_on() + await flow.impairment_distribution.corruption_type_config.enable.set(action=enums.OnOff.OFF) + await flow.impairment_distribution.corruption_type_config.enable.set_off() -Enable + resp = await flow.impairment_distribution.corruption_type_config.off.get() + resp.action + +Off Distribution ----------------------- +Configure Impairments Distribution to OFF. Assigning a different distribution than OFF to an impairment +will activate the impairment. To de-activate the impairment assign distribution OFF. + +Corresponding CLI command: ``PED_OFF`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.enable.set_on() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.enable.set_off() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.enable.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.off.set() + + resp = await flow.impairment_distribution.corruption_type_config.off.get() + resp.action Fixed Rate Distribution ----------------------- +Configuration of Fixed Rate distribution. This is predictable distribution with +nearly equal distance between impairments, to match the configured probability. + +.. note:: + + In case of misordering, a special limit applies, probability * (depth + 1) should be less than 1000000. + +Corresponding CLI command: ``PED_FIXED`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.fixed_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.fixed_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.fixed_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.corruption_type_config.fixed_rate.get() + resp.probability Random Rate Distribution ------------------------ +Configuration of Random Rate distribution. Packets are impaired randomly based +on a per packet probability. This way the impaired fraction of packets will be +equal to the configured probability over time. Random probability in ppm (i.e. 1 +means 0.0001%) + +Corresponding CLI command: ``PED_RANDOM`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.random_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.random_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.random_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.corruption_type_config.random_rate.get() + resp.probability Bit Error Rate Distribution --------------------------- +Configuration of Bit Error Rate distribution. + +Corresponding CLI command: ``PED_BER`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.bit_error_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.bit_error_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.bit_error_rate.set(coef=1, exp=1) + + resp = await flow.impairment_distribution.corruption_type_config.bit_error_rate.get() + resp.coef + resp.exp Fixed Burst Distribution ------------------------- +Configuration of Fixed Burst distribution. + +Corresponding CLI command: ``PED_FIXEDBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.fixed_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.fixed_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.fixed_burst.set(burst_size=1300) + + resp = await flow.impairment_distribution.corruption_type_config.fixed_burst.get() + resp.burst_size Random Burst Distribution -------------------------- +Configuration of Random Burst distribution. + +Corresponding CLI command: ``PED_RANDOMBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.random_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.random_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.random_burst.set(minimum=1, maximum=10, probability=10_000) + + resp = await flow.impairment_distribution.corruption_type_config.random_burst.get() + resp.minimum + resp.maximum + resp.probability Gilbert Elliott Distribution ---------------------------- +Configuration of Gilbert-Elliot distribution. + +Corresponding CLI command: ``PED_GE`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.ge.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.ge.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.ge.set(good_state_prob=0, good_state_trans_prob=0, bad_state_prob=0, bad_state_trans_prob=0) + + resp = await flow.impairment_distribution.corruption_type_config.ge.get() + resp.good_state_prob + resp.good_state_trans_prob + resp.bad_state_prob + resp.bad_state_trans_prob Uniform Distribution -------------------------- +Configuration of Uniform distribution. + +.. note:: + + If minimum is less than minimum latency, value is set to minimum latency. If minimum is greater than maximum latency, value is set to maximum latency. + +Corresponding CLI command: ``PED_UNI`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.uniform.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.uniform.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.uniform.set(minimum=1, maximum=1) + + resp = await flow.impairment_distribution.corruption_type_config.uniform.get() + resp.minimum + resp.maximum Gaussian Distribution -------------------------- +Configuration of Gaussian distribution. + +.. note:: + + In case of ``_impairment_type_xindex != DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + (2) mean should always be at least 3 times the standard deviation, this to ensure that the impairment distance is always positive. + + In case of ``_impairment_type_xindex = DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to the maximum latency. + (2) mean minus 3 times the standard deviation should be greater than or equal to minimum latency. + +Corresponding CLI command: ``PED_GAUSS`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.gaussian.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.gaussian.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.gaussian.set(mean=1, std_deviation=1) + + resp = await flow.impairment_distribution.corruption_type_config.gaussian.get() + resp.mean + resp.std_deviation Poisson Distribution -------------------------- +Configuration of "Poisson" distribution. + +.. note:: + + Standard deviation is derived from mean, i.e., standard deviation = SQRT(mean). + + In case of ``_impairment_type_xindex != DELAY``, mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + + In case of ``_impairment_type_xindex = DELAY``, mean plus 3 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_POISSON`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.poisson.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.poisson.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.poisson.set(mean=100) + + resp = await flow.impairment_distribution.corruption_type_config.poisson.get() + resp.mean Gamma Distribution -------------------------- +Configuration of Gamma distribution. + +.. note:: + + Mean and Standard deviation are calculated from Shape and Scale parameters and validation is performed using those. + standard deviation = [SQRT(shape * scale * scale)]mean = [shape * scale]. + + In case of ``_impairment_type_xindex != DELAY``, + (1) mean plus 4 times standard deviation should be less than or equal to max allowed(4194288). + (2)shape and scale should be greater than or equal to 0. + + In case of ``_impairment_type_xindex = DELAY``, mean plus 4 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_GAMMA`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.gamma.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.gamma.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.gamma.set(shape=1, scale=1) + + resp = await flow.impairment_distribution.corruption_type_config.gamma.get() + resp.shape + resp.scale Custom Distribution -------------------------- +Associate a custom distribution to a flow and impairment type. + +.. note:: + + Before associating a custom distribution, the below validation checks are applied. + + In case of ``_impairment_type_xindex != DELAY``, + (1) Custom values should be less than or equal to max allowed (4194288). + (2) Custom distribution bust contain 512 values. + + In case of ``_impairment_type_xindex = DELAY``, + (1) Custom values should be less than or equal to the maximum latency. + (2) Custom values should be greater than or equal to minimum latency. + (3) Custom distribution should contain 1024 values. + +Corresponding CLI command: ``PED_CUST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.custom.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.custom.get() + # Custom distribution for impairment Corruption + flow = port.emulation.flows[1] # e.g. flow_id = 1 + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await flow.impairment_distribution.corruption_type_config.custom.set(cust_id=0) + + resp = await flow.impairment_distribution.corruption_type_config.custom.get() + resp.cust_id Scheduling -------------------------- +Configure the impairment scheduler function. The configuration of the scheduler +depends on the kind of distribution to schedule: + +1. Burst distributions: "Fixed Burst" and "Accumulate and Burst". +2. Non-Burst distributions: All others. For burst distributions, the scheduler can be configured for "One-shot" operation or "Repeat Operation". When running in "Repeat Operation" the "Repeat Period" must be configured. For non-burst distributions, the scheduler can be configured operate in either "Continuous" or "Repeat Period" modes. When running in "Repeat Period" configuration of "Duration" and "Repeat Period" is required. + +Corresponding CLI command: ``PED_SCHEDULE`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.schedule.set() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.schedule.get() - await port.emulation.flows[flow_idx].impairment_distribution.corruption_type_config.one_shot_status.get() \ No newline at end of file + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1) # repeat pattern + await flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0) # continuous + + resp = await flow.impairment_distribution.corruption_type_config.schedule.get() + + await flow.impairment_distribution.corruption_type_config.one_shot_status.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/corruption/scheduling.rst b/docs/source/api_ref/hlapiv1/port/chimera/corruption/scheduling.rst new file mode 100644 index 00000000..5e1f9af2 --- /dev/null +++ b/docs/source/api_ref/hlapiv1/port/chimera/corruption/scheduling.rst @@ -0,0 +1,37 @@ +Corruption Scheduling +========================= + +Schedule +-------------------------- +Configure the impairment scheduler function. The configuration of the scheduler +depends on the kind of distribution to schedule: + +1. Burst distributions: "Fixed Burst" and "Accumulate and Burst". +2. Non-Burst distributions: All others. For burst distributions, the scheduler can be configured for "One-shot" operation or "Repeat Operation". When running in "Repeat Operation" the "Repeat Period" must be configured. For non-burst distributions, the scheduler can be configured operate in either "Continuous" or "Repeat Period" modes. When running in "Repeat Period" configuration of "Duration" and "Repeat Period" is required. + +Corresponding CLI command: ``PED_SCHEDULE`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1) # repeat pattern + await flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0) # continuous + + resp = await flow.impairment_distribution.corruption_type_config.schedule.get() + + +One-Shot Status +-------------------------- +Retrieves the one-shot completion status. + +.. note:: + + The return value is only valid, if the configured distribution is either accumulate & burst (DELAY) or fixed burst (non-DELAY). + +Corresponding CLI command: ``PED_ONESHOTSTATUS`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + resp = await flow.impairment_distribution.corruption_type_config.one_shot_status.get() + resp.one_shot_status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/drop/distribution.rst b/docs/source/api_ref/hlapiv1/port/chimera/drop/distribution.rst index 96422bdb..d0c7906b 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/drop/distribution.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/drop/distribution.rst @@ -1,116 +1,265 @@ -Distribution +Drop Distribution ========================= -Off +Enable/Disable ----------------------- +Control whether this impairment distribution is enabled. + +.. note:: + + This command is not applicable for PE_BANDPOLICER and PE_BANDSHAPER because they have a separate ``ON / OFF`` parameter. + +Corresponding CLI command: ``PED_ENABLE`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.off.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.off.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.enable.set(action=enums.OnOff.ON) + await flow.impairment_distribution.drop_type_config.enable.set_on() + await flow.impairment_distribution.drop_type_config.enable.set(action=enums.OnOff.OFF) + await flow.impairment_distribution.drop_type_config.enable.set_off() -Enable + resp = await flow.impairment_distribution.drop_type_config.off.get() + resp.action + +Off Distribution ----------------------- +Configure Impairments Distribution to OFF. Assigning a different distribution than OFF to an impairment +will activate the impairment. To de-activate the impairment assign distribution OFF. + +Corresponding CLI command: ``PED_OFF`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.enable.set_on() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.enable.set_off() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.enable.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.off.set() + + resp = await flow.impairment_distribution.drop_type_config.off.get() + resp.action + Fixed Rate Distribution ----------------------- +Configuration of Fixed Rate distribution. This is predictable distribution with +nearly equal distance between impairments, to match the configured probability. + +.. note:: + + In case of misordering, a special limit applies, probability * (depth + 1) should be less than 1000000. + +Corresponding CLI command: ``PED_FIXED`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.fixed_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.fixed_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.fixed_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.drop_type_config.fixed_rate.get() + resp.probability Random Rate Distribution ------------------------ +Configuration of Random Rate distribution. Packets are impaired randomly based +on a per packet probability. This way the impaired fraction of packets will be +equal to the configured probability over time. Random probability in ppm (i.e. 1 +means 0.0001%) + +Corresponding CLI command: ``PED_RANDOM`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.random_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.random_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.random_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.drop_type_config.random_rate.get() + resp.probability Bit Error Rate Distribution --------------------------- +Configuration of Bit Error Rate distribution. + +Corresponding CLI command: ``PED_BER`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.bit_error_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.bit_error_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.bit_error_rate.set(coef=1, exp=1) + + resp = await flow.impairment_distribution.drop_type_config.bit_error_rate.get() + resp.coef + resp.exp Fixed Burst Distribution ------------------------- +Configuration of Fixed Burst distribution. + +Corresponding CLI command: ``PED_FIXEDBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.fixed_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.fixed_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.fixed_burst.set(burst_size=1300) + + resp = await flow.impairment_distribution.drop_type_config.fixed_burst.get() + resp.burst_size Random Burst Distribution -------------------------- +Configuration of Random Burst distribution. + +Corresponding CLI command: ``PED_RANDOMBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.random_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.random_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.random_burst.set(minimum=1, maximum=10, probability=10_000) + + resp = await flow.impairment_distribution.drop_type_config.random_burst.get() + resp.minimum + resp.maximum + resp.probability Gilbert Elliott Distribution ---------------------------- +Configuration of Gilbert-Elliot distribution. + +Corresponding CLI command: ``PED_GE`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.ge.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.ge.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.ge.set(good_state_prob=0, good_state_trans_prob=0, bad_state_prob=0, bad_state_trans_prob=0) + + resp = await flow.impairment_distribution.drop_type_config.ge.get() + resp.good_state_prob + resp.good_state_trans_prob + resp.bad_state_prob + resp.bad_state_trans_prob + Uniform Distribution -------------------------- +Configuration of Uniform distribution. + +.. note:: + + If minimum is less than minimum, value is set to minimum. If minimum is greater than maximum, value is set to maximum. + +Corresponding CLI command: ``PED_UNI`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.uniform.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.uniform.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.uniform.set(minimum=1, maximum=1) + + resp = await flow.impairment_distribution.drop_type_config.uniform.get() + resp.minimum + resp.maximum Gaussian Distribution -------------------------- +Configuration of Gaussian distribution. + +.. note:: + + In case of ``_impairment_type_xindex != DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + (2) mean should always be at least 3 times the standard deviation, this to ensure that the impairment distance is always positive. + + In case of ``_impairment_type_xindex = DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to the maximum latency. + (2) mean minus 3 times the standard deviation should be greater than or equal to minimum latency. + +Corresponding CLI command: ``PED_GAUSS`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.gaussian.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.gaussian.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.gaussian.set(mean=1, std_deviation=1) + + resp = await flow.impairment_distribution.drop_type_config.gaussian.get() + resp.mean + resp.std_deviation Poisson Distribution -------------------------- +Configuration of "Poisson" distribution. + +.. note:: + + Standard deviation is derived from mean, i.e., standard deviation = SQRT(mean). + + In case of ``_impairment_type_xindex != DELAY``, mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + + In case of ``_impairment_type_xindex = DELAY``, mean plus 3 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_POISSON`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.poisson.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.poisson.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.poisson.set(mean=100) + + resp = await flow.impairment_distribution.drop_type_config.poisson.get() + resp.mean Gamma Distribution -------------------------- +Configuration of Gamma distribution. + +.. note:: + + Mean and Standard deviation are calculated from Shape and Scale parameters and validation is performed using those. + standard deviation = [SQRT(shape * scale * scale)]mean = [shape * scale]. + + In case of ``_impairment_type_xindex != DELAY``, + (1) mean plus 4 times standard deviation should be less than or equal to max allowed(4194288). + (2)shape and scale should be greater than or equal to 0. + + In case of ``_impairment_type_xindex = DELAY``, mean plus 4 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_GAMMA`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.gamma.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.gamma.get() - + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.gamma.set(shape=1, scale=1) + + resp = await flow.impairment_distribution.drop_type_config.gamma.get() + resp.shape + resp.scale + Custom Distribution -------------------------- +Associate a custom distribution to a flow and impairment type. -.. code-block:: python +.. note:: - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.custom.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.custom.get() + Before associating a custom distribution, the below validation checks are applied. -Scheduling --------------------------- + In case of ``_impairment_type_xindex != DELAY``, + (1) Custom values should be less than or equal to max allowed (4194288). + (2) Custom distribution bust contain 512 values. + + In case of ``_impairment_type_xindex = DELAY``, + (1) Custom values should be less than or equal to the maximum latency. + (2) Custom values should be greater than or equal to minimum latency. + (3) Custom distribution should contain 1024 values. + +Corresponding CLI command: ``PED_CUST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.schedule.set() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.schedule.get() - await port.emulation.flows[flow_idx].impairment_distribution.drop_type_config.one_shot_status.get() \ No newline at end of file + # Custom distribution for impairment Corruption + flow = port.emulation.flows[1] # e.g. flow_id = 1 + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await flow.impairment_distribution.drop_type_config.custom.set(cust_id=0) + + resp = await flow.impairment_distribution.drop_type_config.custom.get() + resp.cust_id + \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/drop/scheduling.rst b/docs/source/api_ref/hlapiv1/port/chimera/drop/scheduling.rst new file mode 100644 index 00000000..875e562b --- /dev/null +++ b/docs/source/api_ref/hlapiv1/port/chimera/drop/scheduling.rst @@ -0,0 +1,37 @@ +Drop Scheduling +========================= + +Schedule +-------------------------- +Configure the impairment scheduler function. The configuration of the scheduler +depends on the kind of distribution to schedule: + +1. Burst distributions: "Fixed Burst" and "Accumulate and Burst". +2. Non-Burst distributions: All others. For burst distributions, the scheduler can be configured for "One-shot" operation or "Repeat Operation". When running in "Repeat Operation" the "Repeat Period" must be configured. For non-burst distributions, the scheduler can be configured operate in either "Continuous" or "Repeat Period" modes. When running in "Repeat Period" configuration of "Duration" and "Repeat Period" is required. + +Corresponding CLI command: ``PED_SCHEDULE`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1) # repeat pattern + await flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0) # continuous + + resp = await flow.impairment_distribution.drop_type_config.schedule.get() + + +One-Shot Status +-------------------------- +Retrieves the one-shot completion status. + +.. note:: + + The return value is only valid, if the configured distribution is either accumulate & burst (DELAY) or fixed burst (non-DELAY). + +Corresponding CLI command: ``PED_ONESHOTSTATUS`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + resp = await flow.impairment_distribution.drop_type_config.one_shot_status.get() + resp.one_shot_status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/duplication/distribution.rst b/docs/source/api_ref/hlapiv1/port/chimera/duplication/distribution.rst index 6f219e57..fc94b1bb 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/duplication/distribution.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/duplication/distribution.rst @@ -1,117 +1,264 @@ -Distribution +Duplication Distribution ========================= -Off +Enable/Disable ----------------------- +Control whether this impairment distribution is enabled. + +.. note:: + + This command is not applicable for PE_BANDPOLICER and PE_BANDSHAPER because they have a separate ``ON / OFF`` parameter. + +Corresponding CLI command: ``PED_ENABLE`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.off.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.off.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.enable.set(action=enums.OnOff.ON) + await flow.impairment_distribution.duplication_type_config.enable.set_on() + await flow.impairment_distribution.duplication_type_config.enable.set(action=enums.OnOff.OFF) + await flow.impairment_distribution.duplication_type_config.enable.set_off() -Enable + resp = await flow.impairment_distribution.duplication_type_config.off.get() + resp.action + +Off Distribution ----------------------- +Configure Impairments Distribution to OFF. Assigning a different distribution than OFF to an impairment +will activate the impairment. To de-activate the impairment assign distribution OFF. + +Corresponding CLI command: ``PED_OFF`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.enable.set_on() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.enable.set_off() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.enable.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.off.set() + + resp = await flow.impairment_distribution.duplication_type_config.off.get() + resp.action + Fixed Rate Distribution ----------------------- +Configuration of Fixed Rate distribution. This is predictable distribution with +nearly equal distance between impairments, to match the configured probability. + +.. note:: + + In case of misordering, a special limit applies, probability * (depth + 1) should be less than 1000000. + +Corresponding CLI command: ``PED_FIXED`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.fixed_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.fixed_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.fixed_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.duplication_type_config.fixed_rate.get() + resp.probability Random Rate Distribution ------------------------ +Configuration of Random Rate distribution. Packets are impaired randomly based +on a per packet probability. This way the impaired fraction of packets will be +equal to the configured probability over time. Random probability in ppm (i.e. 1 +means 0.0001%) + +Corresponding CLI command: ``PED_RANDOM`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.random_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.random_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.random_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.duplication_type_config.random_rate.get() + resp.probability Bit Error Rate Distribution --------------------------- +Configuration of Bit Error Rate distribution. + +Corresponding CLI command: ``PED_BER`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.bit_error_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.bit_error_rate.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.bit_error_rate.set(coef=1, exp=1) + + resp = await flow.impairment_distribution.duplication_type_config.bit_error_rate.get() + resp.coef + resp.exp Fixed Burst Distribution ------------------------- +Configuration of Fixed Burst distribution. + +Corresponding CLI command: ``PED_FIXEDBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.fixed_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.fixed_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.fixed_burst.set(burst_size=1300) + + resp = await flow.impairment_distribution.duplication_type_config.fixed_burst.get() + resp.burst_size Random Burst Distribution -------------------------- +Configuration of Random Burst distribution. + +Corresponding CLI command: ``PED_RANDOMBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.random_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.random_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.random_burst.set(minimum=1, maximum=10, probability=10_000) + + resp = await flow.impairment_distribution.duplication_type_config.random_burst.get() + resp.minimum + resp.maximum + resp.probability Gilbert Elliott Distribution ---------------------------- +Configuration of Gilbert-Elliot distribution. + +Corresponding CLI command: ``PED_GE`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.ge.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.ge.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.ge.set(good_state_prob=0, good_state_trans_prob=0, bad_state_prob=0, bad_state_trans_prob=0) + + resp = await flow.impairment_distribution.duplication_type_config.ge.get() + resp.good_state_prob + resp.good_state_trans_prob + resp.bad_state_prob + resp.bad_state_trans_prob + Uniform Distribution -------------------------- +Configuration of Uniform distribution. + +.. note:: + + If minimum is less than minimum, value is set to minimum. If minimum is greater than maximum, value is set to maximum. + +Corresponding CLI command: ``PED_UNI`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.uniform.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.uniform.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.uniform.set(minimum=1, maximum=1) + + resp = await flow.impairment_distribution.duplication_type_config.uniform.get() + resp.minimum + resp.maximum Gaussian Distribution -------------------------- +Configuration of Gaussian distribution. + +.. note:: + + In case of ``_impairment_type_xindex != DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + (2) mean should always be at least 3 times the standard deviation, this to ensure that the impairment distance is always positive. + + In case of ``_impairment_type_xindex = DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to the maximum latency. + (2) mean minus 3 times the standard deviation should be greater than or equal to minimum latency. + +Corresponding CLI command: ``PED_GAUSS`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.gaussian.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.gaussian.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.gaussian.set(mean=1, std_deviation=1) + + resp = await flow.impairment_distribution.duplication_type_config.gaussian.get() + resp.mean + resp.std_deviation Poisson Distribution -------------------------- +Configuration of "Poisson" distribution. + +.. note:: + + Standard deviation is derived from mean, i.e., standard deviation = SQRT(mean). + + In case of ``_impairment_type_xindex != DELAY``, mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + + In case of ``_impairment_type_xindex = DELAY``, mean plus 3 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_POISSON`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.poisson.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.poisson.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.poisson.set(mean=100) + + resp = await flow.impairment_distribution.duplication_type_config.poisson.get() + resp.mean Gamma Distribution -------------------------- +Configuration of Gamma distribution. + +.. note:: + + Mean and Standard deviation are calculated from Shape and Scale parameters and validation is performed using those. + standard deviation = [SQRT(shape * scale * scale)]mean = [shape * scale]. + + In case of ``_impairment_type_xindex != DELAY``, + (1) mean plus 4 times standard deviation should be less than or equal to max allowed(4194288). + (2)shape and scale should be greater than or equal to 0. + + In case of ``_impairment_type_xindex = DELAY``, mean plus 4 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_GAMMA`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.gamma.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.gamma.get() - + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.gamma.set(shape=1, scale=1) + + resp = await flow.impairment_distribution.duplication_type_config.gamma.get() + resp.shape + resp.scale + Custom Distribution -------------------------- +Associate a custom distribution to a flow and impairment type. -.. code-block:: python +.. note:: - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.custom.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.custom.get() + Before associating a custom distribution, the below validation checks are applied. + In case of ``_impairment_type_xindex != DELAY``, + (1) Custom values should be less than or equal to max allowed (4194288). + (2) Custom distribution bust contain 512 values. -Scheduling --------------------------- + In case of ``_impairment_type_xindex = DELAY``, + (1) Custom values should be less than or equal to the maximum latency. + (2) Custom values should be greater than or equal to minimum latency. + (3) Custom distribution should contain 1024 values. + +Corresponding CLI command: ``PED_CUST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.schedule.set() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.schedule.get() - await port.emulation.flows[flow_idx].impairment_distribution.duplication_type_config.one_shot_status.get() \ No newline at end of file + # Custom distribution for impairment Corruption + flow = port.emulation.flows[1] # e.g. flow_id = 1 + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await flow.impairment_distribution.duplication_type_config.custom.set(cust_id=0) + + resp = await flow.impairment_distribution.duplication_type_config.custom.get() + resp.cust_id diff --git a/docs/source/api_ref/hlapiv1/port/chimera/duplication/scheduling.rst b/docs/source/api_ref/hlapiv1/port/chimera/duplication/scheduling.rst new file mode 100644 index 00000000..9e06b37c --- /dev/null +++ b/docs/source/api_ref/hlapiv1/port/chimera/duplication/scheduling.rst @@ -0,0 +1,37 @@ +Duplication Scheduling +========================= + +Schedule +-------------------------- +Configure the impairment scheduler function. The configuration of the scheduler +depends on the kind of distribution to schedule: + +1. Burst distributions: "Fixed Burst" and "Accumulate and Burst". +2. Non-Burst distributions: All others. For burst distributions, the scheduler can be configured for "One-shot" operation or "Repeat Operation". When running in "Repeat Operation" the "Repeat Period" must be configured. For non-burst distributions, the scheduler can be configured operate in either "Continuous" or "Repeat Period" modes. When running in "Repeat Period" configuration of "Duration" and "Repeat Period" is required. + +Corresponding CLI command: ``PED_SCHEDULE`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1) # repeat pattern + await flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0) # continuous + + resp = await flow.impairment_distribution.duplication_type_config.schedule.get() + + +One-Shot Status +-------------------------- +Retrieves the one-shot completion status. + +.. note:: + + The return value is only valid, if the configured distribution is either accumulate & burst (DELAY) or fixed burst (non-DELAY). + +Corresponding CLI command: ``PED_ONESHOTSTATUS`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + resp = await flow.impairment_distribution.duplication_type_config.one_shot_status.get() + resp.one_shot_status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/any.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/any.rst index c1f1472a..3b3c3ebe 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/any.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/any.rst @@ -8,17 +8,51 @@ Any Configuration ------------------- +Basic mode only. Defines the ANY field filter configuration. The "ANY field" +filter will match 6 consecutive bytes in the incoming packets at a programmable +offset. Applying a mask, allows to only filter based on selected bits within the +6 bytes. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_ANYCONFIG`` .. code-block:: python - await filter.any.config.set() - await filter.any.config.get() + from xoa_driver import misc + + filter = await port.emulation.flows[1].shadow_filter.get_mode() # e.g. flow_id = 1 + if isinstance(filter, misc.BasicImpairmentFlowFilter): + await filter.any.config.set(position=0, value=Hex("112233445566"), mask=Hex("112233445566")) + + resp = await filter.any.config.get() + resp.position + resp.value + resp.mask Settings ------------------- +Basic mode only. Defines if filtering on ANY field in a packet is used for flow filtering. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_ANYSETTINGS`` .. code-block:: python - await filter.any.settings.set() - await filter.any.settings.get() + from xoa_driver import misc + + filter = await port.emulation.flows[1].shadow_filter.get_mode() # e.g. flow_id = 1 + if isinstance(filter, misc.BasicImpairmentFlowFilter): + await filter.any.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.any.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = filter.any.settings.get() + resp.use + resp.action + diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/index.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/index.rst index fd371f6a..63cb63db 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/index.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/index.rst @@ -5,15 +5,6 @@ Basic Filter Configuration Applicable to Chimera port only. -.. note:: - - Use to verify the filter mode first. - - .. code-block:: python - - from xoa_driver import misc - filter = await port.emulation.flows[flow_idx].shadow_filter.get_mode() - if isinstance(filter, misc.BasicImpairmentFlowFilter): .. toctree:: :glob: diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2.rst index 3eec3d2e..79f66c6a 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2.rst @@ -8,27 +8,61 @@ L2 Ethernet DST ------------------- +Defines the Ethernet Destination Address settings for the Ethernet filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_ETHDESTADDR`` .. code-block:: python - await filter.ethernet.dest_address.set_on() - await filter.ethernet.dest_address.set_off() - await filter.ethernet.dest_address.get() + await filter.ethernet.dest_address.set(use=enums.OnOff.OFF, value=Hex("BBBBBBBBBBBB"), mask=Hex("FFFFFFFFFFFF")) + await filter.ethernet.dest_address.set(use=enums.OnOff.ON, value=Hex("BBBBBBBBBBBB"), mask=Hex("FFFFFFFFFFFF")) + + resp = await filter.ethernet.dest_address.get() + resp.use + resp.value + resp.mask Ethernet SRC ------------------- +Defines the Ethernet Source Address settings for the Ethernet filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_ETHSRCADDR`` .. code-block:: python - await filter.ethernet.src_address.set_on() - await filter.ethernet.src_address.set_off() - await filter.ethernet.src_address.get() + await filter.ethernet.src_address.set(use=enums.OnOff.OFF, value=Hex("AAAAAAAAAAAA"), mask=Hex("FFFFFFFFFFFF")) + await filter.ethernet.src_address.set(use=enums.OnOff.ON, value=Hex("AAAAAAAAAAAA"), mask=Hex("FFFFFFFFFFFF")) + + resp = await filter.ethernet.src_address.get() + resp.use + resp.value + resp.mask Ethernet Settings ------------------- +Defines what filter action is performed on the Ethernet header. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_ETHSETTINGS`` .. code-block:: python - await filter.ethernet.settings.set() - await filter.ethernet.settings.get() + await filter.ethernet.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.ethernet.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.ethernet.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + + resp = await filter.ethernet.settings.get() + resp.use + resp.action diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2plus.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2plus.rst index 1d372b5e..a790b94c 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2plus.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l2plus.rst @@ -8,76 +8,192 @@ L2+ Type ------------------- +Defines what Layer 2+ protocols that are present and may be used for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_L2PUSE`` .. code-block:: python + await filter.l2plus_use.set(use=enums.L2PlusPresent.VLAN1) await filter.l2plus_use.set_vlan1() + await filter.l2plus_use.set(use=enums.L2PlusPresent.VLAN2) await filter.l2plus_use.set_vlan2() + await filter.l2plus_use.set(use=enums.L2PlusPresent.MPLS) await filter.l2plus_use.set_mpls() + await filter.l2plus_use.set(use=enums.L2PlusPresent.NA) await filter.l2plus_use.set_na() - await filter.l2plus_use.get() + + resp = await filter.l2plus_use.get() + resp.use VLAN Inner Tag ------------------- +Basic mode only. Defines the VLAN TAG settings for the VLAN filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_VLANTAG`` .. code-block:: python + await filter.vlan.inner.tag.set(use=enums.OnOff.ON, value=1234, mask=Hex("0FFF")) + await filter.vlan.inner.tag.set_on() + await filter.vlan.inner.tag.set(use=enums.OnOff.OFF, value=1234, mask=Hex("0FFF")) + await filter.vlan.inner.tag.set_off() + + resp = await filter.vlan.inner.tag.get() + resp.use + resp.value + resp.mask + + +VLAN Inner PCP +------------------- +Basic mode only. Defines the VLAN PCP settings for the VLAN filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_VLANPCP`` + +.. code-block:: python + + await filter.vlan.inner.pcp.set(use=enums.OnOff.ON, value=3, mask=Hex("07")) await filter.vlan.inner.pcp.set_on() + await filter.vlan.inner.pcp.set(use=enums.OnOff.OFF, value=3, mask=Hex("07")) await filter.vlan.inner.pcp.set_off() - await filter.vlan.inner.pcp.get() - await filter.vlan.inner.tag.set_on() - await filter.vlan.inner.tag.set_off() - await filter.vlan.inner.tag.get() + resp = await filter.vlan.inner.pcp.get() + resp.use + resp.value + resp.mask + VLAN Outer Tag ------------------- +Basic mode only. Defines the VLAN TAG settings for the VLAN filter. -.. code-block:: python +.. note:: - await filter.vlan.outer.pcp.set_on() - await filter.vlan.outer.pcp.set_off() - await filter.vlan.outer.pcp.get() + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_VLANTAG`` +.. code-block:: python + + await filter.vlan.outer.tag.set(use=enums.OnOff.ON, value=1234, mask=Hex("0FFF")) await filter.vlan.outer.tag.set_on() + await filter.vlan.outer.tag.set(use=enums.OnOff.OFF, value=1234, mask=Hex("0FFF")) await filter.vlan.outer.tag.set_off() - await filter.vlan.outer.tag.get() + resp = await filter.vlan.outer.tag.get() + resp.use + resp.value + resp.mask + +VLAN Outer PCP +------------------- +Basic mode only. Defines the VLAN PCP settings for the VLAN filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_VLANPCP`` + +.. code-block:: python + + await filter.vlan.outer.pcp.set(use=enums.OnOff.ON, value=3, mask=Hex("07")) + await filter.vlan.outer.pcp.set_on() + await filter.vlan.outer.pcp.set(use=enums.OnOff.OFF, value=3, mask=Hex("07")) + await filter.vlan.outer.pcp.set_off() + + resp = await filter.vlan.outer.pcp.get() + resp.use + resp.value + resp.mask VLAN Settings ------------------- +Defines what filter action is performed on the VLAN header. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_VLANSETTINGS`` .. code-block:: python - await filter.vlan.settings.set() - await filter.vlan.settings.get() + await filter.vlan.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.vlan.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.vlan.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = await filter.vlan.settings.get() + resp.use + resp.action MPLS Label ------------------- +Basic mode only. Defines the MPLS label settings for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_MPLSLABEL`` .. code-block:: python - await filter.mpls.label.set_on() - await filter.mpls.label.set_off() - await filter.mpls.label.get() + await filter.mpls.label.set(use=enums.OnOff.ON, value=1000, mask=Hex("FFFFF")) + await filter.mpls.label.set(use=enums.OnOff.OFF, value=1000, mask=Hex("FFFFF")) + + resp = await filter.mpls.label.get() + resp.use + resp.value MPLS TOC ------------------- +Basic mode only. Defines the MPLS TOC settings for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_MPLSTOC`` .. code-block:: python - await filter.mpls.toc.set_on() - await filter.mpls.toc.set_off() - await filter.mpls.toc.get() + await filter.mpls.toc.set(use=enums.OnOff.ON, value=0, mask=Hex("07")) + await filter.mpls.toc.set(use=enums.OnOff.OFF, value=0, mask=Hex("07")) + + resp = await filter.mpls.toc.get() + resp.use + resp.value MPLS Settings ------------------- +Basic mode only. Defines what filter action is performed on the MPLS header. + +Corresponding CLI command: ``PEF_MPLSSETTINGS`` .. code-block:: python - await filter.mpls.settings.set() - await filter.mpls.settings.get() \ No newline at end of file + await filter.mpls.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.mpls.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.mpls.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = await filter.mpls.settings.get() + resp.use + resp.action \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l3.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l3.rst index 34f9175f..c9db5fb4 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l3.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l3.rst @@ -8,81 +8,184 @@ L3 Type ------------------- +Basic mode only. Defines what Layer 3 protocols that are present and may be used +for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_L3USE`` .. code-block:: python + await filter.l3_use.set(use=enums.L3Present.IP4) await filter.l3_use.set_ip4() + await filter.l3_use.set(use=enums.L3Present.IP6) await filter.l3_use.set_ip6() + await filter.l3_use.set(use=enums.L3Present.NA) await filter.l3_use.set_na() - await filter.l3_use.get() + + resp = await filter.l3_use.get() + resp.use IPv4 DST ------------------- +Basic mode only. Defines the IPv4 Destination Address settings for the IPv4 filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV4DESTADDR`` .. code-block:: python - await filter.ip.v4.dest_address.set_on() - await filter.ip.v4.dest_address.set_off() - await filter.ip.v4.dest_address.get() + await filter.ip.v4.dest_address.set(use=enums.OnOff.ON, value=ipaddress.IPv4Address("10.0.0.2"), mask=Hex("FFFFFFFF")) + await filter.ip.v4.dest_address.set(use=enums.OnOff.OFF, value=ipaddress.IPv4Address("10.0.0.2"), mask=Hex("FFFFFFFF")) + + resp = await filter.ip.v4.dest_address.get() + resp.use + resp.value + resp.mask IPv4 SRC ------------------- +Basic mode only. Defines the IPv4 Source Address settings for the IPv4 filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV4SRCADDR`` .. code-block:: python - await filter.ip.v4.src_address.set_on() - await filter.ip.v4.src_address.set_off() - await filter.ip.v4.src_address.get() + await filter.ip.v4.src_address.set(use=enums.OnOff.ON, value=ipaddress.IPv4Address("10.0.0.2"), mask=Hex("FFFFFFFF")) + await filter.ip.v4.src_address.set(use=enums.OnOff.OFF, value=ipaddress.IPv4Address("10.0.0.2"), mask=Hex("FFFFFFFF")) + + resp = await filter.ip.v4.src_address.get() + resp.use + resp.value + resp.mask IPv4 DSCP ------------------- +Basic mode only. Defines if IPv4 DSCP/TOS settings used for the IPv4 filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV4DSCP`` .. code-block:: python - await filter.ip.v4.dscp.set_on() - await filter.ip.v4.dscp.set_off() - await filter.ip.v4.dscp.get() + await filter.ip.v4.dscp.set(use=enums.OnOff.ON, value=0, mask=Hex("FC")) + await filter.ip.v4.dscp.set(use=enums.OnOff.OFF, value=0, mask=Hex("FC")) + + resp = await filter.ip.v4.dscp.get() + resp.use + resp.value + resp.mask IPv4 Settings ------------------- +Basic mode only. Defines what filter action is performed on the IPv4 header. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV4SETTINGS`` .. code-block:: python - await filter.ip.v4.settings.set() - await filter.ip.v4.settings.get() + await filter.ip.v4.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.ip.v4.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.ip.v4.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = await filter.ip.v4.settings.get() + resp.use + resp.action IPv6 DST ------------------- +Basic mode only. Defines the IPv6 Destination Address settings for the IPv6 filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV6DESTADDR`` .. code-block:: python - await filter.ip.v6.dest_address.set_on() - await filter.ip.v6.dest_address.set_off() - await filter.ip.v6.dest_address.get() + await filter.ip.v6.dest_address.set(use=enums.OnOff.OFF, value=ipaddress.IPv6Address("2002::2"), mask=Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + await filter.ip.v6.dest_address.set(use=enums.OnOff.ON, value=ipaddress.IPv6Address("2002::2"), mask=Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + + resp = await filter.ip.v6.dest_address.get() + resp.use + resp.value + resp.mask IPv6 SRC ------------------- +Basic mode only. Defines the IPv6 Source Address settings for the IPv6 filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV6SRCADDR`` .. code-block:: python - await filter.ip.v6.src_address.set_on() - await filter.ip.v6.src_address.set_off() - await filter.ip.v6.src_address.get() + await filter.ip.v6.src_address.set(use=enums.OnOff.OFF, value=ipaddress.IPv6Address("2002::2"), mask=Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + await filter.ip.v6.src_address.set(use=enums.OnOff.ON, value=ipaddress.IPv6Address("2002::2"), mask=Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + + resp = await filter.ip.v6.src_address.get() + resp.use + resp.value + resp.mask IPv6 Traffic Class ------------------- +Basic mode only. Defines the IPv6 Traffic Class settings used for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV6TC`` .. code-block:: python - await filter.ip.v6.traffic_class.set_on() - await filter.ip.v6.traffic_class.set_off() - await filter.ip.v6.traffic_class.get() + await filter.ip.v6.traffic_class.set(use=enums.OnOff.OFF, value=0, mask=Hex("FC")) + await filter.ip.v6.traffic_class.set(use=enums.OnOff.ON, value=0, mask=Hex("FC")) + + resp = await filter.ip.v6.traffic_class.get() + resp.use + resp.value + resp.mask IPv6 Settings ------------------- +Basic mode only. Defines what filter action is performed on the IPv6 header. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_IPV6SETTINGS`` .. code-block:: python - await filter.ip.v6.settings.set() - await filter.ip.v6.settings.get() \ No newline at end of file + await filter.ip.v6.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.ip.v6.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.ip.v6.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = await filter.ip.v6.settings.get() + resp.use + resp.action \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l4.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l4.rst index 29d55f7b..985bd245 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l4.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/l4.rst @@ -7,52 +7,121 @@ L4 TCP DST Port ------------------- +Basic mode only. Defines TCP Destination Port settings used for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_TCPDESTPORT`` .. code-block:: python - await filter.tcp.dest_port.set_on() - await filter.tcp.dest_port.set_off() - await filter.tcp.dest_port.get() + await filter.tcp.dest_port.set(use=enums.OnOff.OFF, value=80, mask=Hex("FFFF")) + await filter.tcp.dest_port.set(use=enums.OnOff.ON, value=80, mask=Hex("FFFF")) + + resp = await filter.tcp.dest_port.get() + resp.use + resp.value + resp.mask TCP SRC Port ------------------- +Basic mode only. Defines TCP Source Port settings used for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_TCPSRCPORT`` .. code-block:: python - await filter.tcp.src_port.set_on() - await filter.tcp.src_port.set_off() - await filter.tcp.src_port.get() + await filter.tcp.src_port.set(use=enums.OnOff.OFF, value=80, mask=Hex("FFFF")) + await filter.tcp.src_port.set(use=enums.OnOff.ON, value=80, mask=Hex("FFFF")) + + resp = await filter.tcp.src_port.get() + resp.use + resp.value + resp.mask TCP Settings ------------------- +Basic mode only. Defines if filtering on TCP information is used for flow +filtering. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_TCPSETTINGS`` .. code-block:: python - await filter.tcp.settings.set() - await filter.tcp.settings.get() + await filter.tcp.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.tcp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.tcp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = await filter.tcp.settings.get() + resp.use + resp.action UDP DST Port ------------------- +Basic mode only. Defines UDP Destination Port settings used for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_UDPDESTPORT`` .. code-block:: python - await filter.udp.dest_port.set_on() - await filter.udp.dest_port.set_off() - await filter.udp.dest_port.get() + await filter.tcp.dest_port.set(use=enums.OnOff.ON, value=80, mask=Hex("FFFF")) + await filter.tcp.dest_port.set(use=enums.OnOff.OFF, value=80, mask=Hex("FFFF")) + + resp = await filter.udp.dest_port.get() + resp.use + resp.value + resp.mask UDP SRC Port ------------------- +Basic mode only. Defines UDP Source Port settings used for the filter. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_UDPSRCPORT`` .. code-block:: python - await filter.udp.src_port.set_on() - await filter.udp.src_port.set_off() - await filter.udp.src_port.get() + await filter.tcp.src_port.set(use=enums.OnOff.ON, value=80, mask=Hex("FFFF")) + await filter.tcp.src_port.set(use=enums.OnOff.OFF, value=80, mask=Hex("FFFF")) + + resp = await filter.udp.src_port.get() + resp.use + resp.value + resp.mask UDP Settings ------------------- +Basic mode only. Controls if UDP packet information is used for flow filtering. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + +Corresponding CLI command: ``PEF_UDPSETTINGS`` .. code-block:: python - await filter.udp.settings.set() - await filter.udp.settings.get() \ No newline at end of file + await filter.udp.settings.set(use=enums.FilterUse.OFF, action=enums.InfoAction.EXCLUDE) + await filter.udp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.EXCLUDE) + await filter.udp.settings.set(use=enums.FilterUse.AND, action=enums.InfoAction.INCLUDE) + + resp = await filter.udp.settings.get() + resp.use + resp.action \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/tpld.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/tpld.rst index 67888cfa..82a3f1d4 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/tpld.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/basic/tpld.rst @@ -8,18 +8,71 @@ TPLD TPLD ID Configuration --------------------- +Defines the TPLD filter configuration. There are only 16 TPLD filter, thus the index values are from 0 to 15. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_TPLDCONFIG`` .. code-block:: python - await filter.tpld.test_payload_filters_config[idx].set_on(tpld_id_value) - await filter.tpld.test_payload_filters_config[idx].set_off(tpld_id_value) - await filter.tpld.test_payload_filters_config[idx].get(tpld_id_value) + await filter.tpld.test_payload_filters_config[0].set(use=enums.OnOff.ON, id = 2) + await filter.tpld.test_payload_filters_config[0].set(use=enums.OnOff.OFF, id = 2) + await filter.tpld.test_payload_filters_config[1].set(use=enums.OnOff.ON, id = 4) + await filter.tpld.test_payload_filters_config[1].set(use=enums.OnOff.OFF, id = 4) + await filter.tpld.test_payload_filters_config[2].set(use=enums.OnOff.ON, id = 6) + await filter.tpld.test_payload_filters_config[2].set(use=enums.OnOff.OFF, id = 6) + await filter.tpld.test_payload_filters_config[3].set(use=enums.OnOff.ON, id = 8) + await filter.tpld.test_payload_filters_config[3].set(use=enums.OnOff.OFF, id = 8) + await filter.tpld.test_payload_filters_config[4].set(use=enums.OnOff.ON, id = 10) + await filter.tpld.test_payload_filters_config[4].set(use=enums.OnOff.OFF, id = 10) + await filter.tpld.test_payload_filters_config[5].set(use=enums.OnOff.ON, id = 20) + await filter.tpld.test_payload_filters_config[5].set(use=enums.OnOff.OFF, id = 20) + await filter.tpld.test_payload_filters_config[6].set(use=enums.OnOff.ON, id = 40) + await filter.tpld.test_payload_filters_config[6].set(use=enums.OnOff.OFF, id = 40) + await filter.tpld.test_payload_filters_config[7].set(use=enums.OnOff.ON, id = 60) + await filter.tpld.test_payload_filters_config[7].set(use=enums.OnOff.OFF, id = 60) + await filter.tpld.test_payload_filters_config[8].set(use=enums.OnOff.ON, id = 80) + await filter.tpld.test_payload_filters_config[8].set(use=enums.OnOff.OFF, id = 80) + await filter.tpld.test_payload_filters_config[9].set(use=enums.OnOff.ON, id = 100) + await filter.tpld.test_payload_filters_config[9].set(use=enums.OnOff.OFF, id = 100) + await filter.tpld.test_payload_filters_config[10].set(use=enums.OnOff.ON, id = 102) + await filter.tpld.test_payload_filters_config[10].set(use=enums.OnOff.OFF, id = 102) + await filter.tpld.test_payload_filters_config[11].set(use=enums.OnOff.ON, id = 104) + await filter.tpld.test_payload_filters_config[11].set(use=enums.OnOff.OFF, id = 104) + await filter.tpld.test_payload_filters_config[12].set(use=enums.OnOff.ON, id = 106) + await filter.tpld.test_payload_filters_config[12].set(use=enums.OnOff.OFF, id = 106) + await filter.tpld.test_payload_filters_config[13].set(use=enums.OnOff.ON, id = 108) + await filter.tpld.test_payload_filters_config[13].set(use=enums.OnOff.OFF, id = 108) + await filter.tpld.test_payload_filters_config[14].set(use=enums.OnOff.ON, id = 110) + await filter.tpld.test_payload_filters_config[14].set(use=enums.OnOff.OFF, id = 110) + await filter.tpld.test_payload_filters_config[15].set(use=enums.OnOff.ON, id = 200) + await filter.tpld.test_payload_filters_config[15].set(use=enums.OnOff.OFF, id = 200) + + resp = await filter.tpld.test_payload_filters_config[0].get() + resp.use + resp.id Settings ------------------- +Defines if filtering on TPLD field in a packet is used for flow filtering. The +TPLD filter allows filtering based on the Xena TPLD ID. The TPLD +ID is meta data, which can be inserted into the Ethernet packets by Xena traffic +generators. For each flow filter, can the filter be based on 16 TPLD ID values. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy``. + +Corresponding CLI command: ``PEF_TPLDSETTINGS`` .. code-block:: python - await filter.tpld.settings.set() - await filter.tpld.settings.get() + await filter.tpld.settings.set(action=enums.InfoAction.EXCLUDE) + await filter.tpld.settings.set(action=enums.InfoAction.INCLUDE) + + resp = await filter.tpld.settings.get() + resp.action diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/extended.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/extended.rst index 98724aa1..2943d7e5 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/extended.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/extended.rst @@ -6,30 +6,139 @@ Working Filter Applicable to Chimera port only. -.. note:: +Use Segments +------------------- +This command is valid only for ``Extended filter mode`` (check PEF_MODE). - Use to verify the filter mode first. +Defines the sequence of protocol segments that can be +matched. The total length of the specified segments cannot exceed 128 bytes. If +an existing sequence of segments is changed (using PEF_PROTOCOL) the underlying +value and mask bytes remain unchanged, even though the semantics of those bytes +may have changed. However, if the total length, in bytes, of the segments is +reduced, then the excess bytes of value and mask are set to zero. I.e. to update +an existing filter, you must first correct the list of segments (using +PEF_PROTOCOL) and subsequently update the filtering value (using PEF_VALUE) and filtering mask (PEF_MASK). - .. code-block:: python - - from xoa_driver import misc - filter = await port.emulation.flows[flow_idx].shadow_filter.get_mode() - if isinstance(filter, misc.ExtendedImpairmentFlowFilter): +Corresponding CLI command: ``PEF_PROTOCOL`` -Use Segments +.. code-block:: python + + # Configure shadow filter to EXTENDED mode + await flow.shadow_filter.use_extended_mode() + + # Query the mode of the filter (either basic or extended) + filter = await flow.shadow_filter.get_mode() + + if isinstance(filter, misc.ExtendedImpairmentFlowFilter): + # Ethernet is the default mandatory + # Adding VLAN after Ethernet + await filter.use_segments( + enums.ProtocolOption.VLAN + ) + protocol_segments = await filter.get_protocol_segments() + + await protocol_segments[0].value.set(value=Hex("AAAAAAAAAAAABBBBBBBBBBBB8100")) + await protocol_segments[0].mask.set(masks=Hex("0000000000000000000000000000")) + await protocol_segments[1].value.set(value=Hex("0064FFFF")) + await protocol_segments[1].mask.set(masks=Hex("00000000")) + +Segment Value ------------------- +This command is valid only for ``Extended filter mode`` (check PEF_MODE). + +Defines the byte values that can be matched if selected by PEF_MASK. + +If `` = 0`` the maximum number of match value +bytes that can be set is determined by the total length of the protocol segments +specified with PEF_PROTOCOL. + +E.g. if PEF_PROTOCOL is set to ETHERNET then only +12 bytes can be set. In order to set the full 128 bytes, either specify a +detailed protocol segment list, or use the raw protocol segment type. This specifies 12 + 116 = 128 bytes. + +If `` != 0`` only the bytes covered by that segment are manipulated, +so if PEF_PROTOCOL is set to ``ETHERNET VLAN ETHERTYPE eCPRI`` then `` = 4`` selects the 8 +bytes of the eCPRI header starting at byte position (12 + 2 + 4) = 18. + +For ``set`` command where fewer value bytes are provided than specified by the protocol segment, those unspecified bytes are set to zero. + +The ``get`` command always returns the number of bytes specified by the protocol segment. + +Corresponding CLI command: ``PEF_VALUE`` .. code-block:: python - await filter.use_segments([...]) + # Configure shadow filter to EXTENDED mode + await flow.shadow_filter.use_extended_mode() + + # Query the mode of the filter (either basic or extended) + filter = await flow.shadow_filter.get_mode() + + if isinstance(filter, misc.ExtendedImpairmentFlowFilter): + # Ethernet is the default mandatory + # Adding VLAN after Ethernet + await filter.use_segments( + enums.ProtocolOption.VLAN + ) + protocol_segments = await filter.get_protocol_segments() + + await protocol_segments[0].value.set(value=Hex("AAAAAAAAAAAABBBBBBBBBBBB8100")) + await protocol_segments[0].mask.set(masks=Hex("0000000000000000000000000000")) + await protocol_segments[1].value.set(value=Hex("0064FFFF")) + await protocol_segments[1].mask.set(masks=Hex("00000000")) -Get Segments + resp = await protocol_segments[0].value.get() + resp.value + resp = await protocol_segments[1].value.get() + resp.value + +Segment Mask ------------------- +This command is valid only for ``Extended filter mode`` (check PEF_MODE). + +Defines the mask byte values that select the values specified by PEF_VALUE. + +For a chosen ```` the first byte in the value masks the +first byte of the corresponding PEF_VALUE and so on. + +If `` = 0`` the maximum number of match value +bytes that can be set is determined by the total length of the protocol segments +specified with PEF_PROTOCOL`. + +E.g. if PEF_PROTOCOL is set to ETHERNET then only +12 bytes can be set. In order to set the full 128 bytes, either specify a +detailed protocol segment list, or use the raw protocol segment type. This specifies 12 + 116 = 128 bytes. + +If `` != 0`` only the bytes covered by that segment are manipulated, +so if PEF_PROTOCOL is set to ``ETHERNET VLAN ETHERTYPE eCPRI`` then `` = 4`` selects the 8 +bytes of the eCPRI header starting at byte position (12 + 2 + 4) = 18. + +``get/set`` semantics are similar to PEF_VALUE. + +Corresponding CLI command: ``PEF_MASK`` .. code-block:: python - segs = await filter.get_protocol_segments() - segs.count - segs[idx].segment_type - segs[idx].mask - segs[idx].value + # Configure shadow filter to EXTENDED mode + await flow.shadow_filter.use_extended_mode() + + # Query the mode of the filter (either basic or extended) + filter = await flow.shadow_filter.get_mode() + + if isinstance(filter, misc.ExtendedImpairmentFlowFilter): + # Ethernet is the default mandatory + # Adding VLAN after Ethernet + await filter.use_segments( + enums.ProtocolOption.VLAN + ) + protocol_segments = await filter.get_protocol_segments() + + await protocol_segments[0].value.set(value=Hex("AAAAAAAAAAAABBBBBBBBBBBB8100")) + await protocol_segments[0].mask.set(masks=Hex("0000000000000000000000000000")) + await protocol_segments[1].value.set(value=Hex("0064FFFF")) + await protocol_segments[1].mask.set(masks=Hex("00000000")) + + resp = await protocol_segments[0].mask.get() + resp.value + resp = await protocol_segments[1].mask.get() + resp.value \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/filter/properties.rst b/docs/source/api_ref/hlapiv1/port/chimera/filter/properties.rst index 5605f4b6..275a5343 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/filter/properties.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/filter/properties.rst @@ -3,53 +3,109 @@ Properties Description --------------- +Flow description. + +Corresponding CLI command: ``PE_COMMENT`` .. code-block:: python - await port.emulation.flows[0].comment.set() - await port.emulation.flows[0].comment.get() + flow = port.emulation.flows[0] + await flow.comment.set(comment="Flow description") + + resp = await port.emulation.flows[0].comment.get() + resp.comment Initiation --------------- +Prepares for setting up a filter definition. When called, all filter +definitions in the shadow-set which are not applied are discarded and replaced +with the default values (DEFAULT). + +.. note:: + + There are 2 register copies used to configure the filters: + + (1) ``Shadow-copy (type value = 0)`` temporary copy configured by sever. + Values stored in ``shadow-copy`` have no immediate effect on the flow filters. PEF_APPLY will pass the values from the ``shadow-copy`` to the ``working-copy``. + + (2) ``Working-copy (type value = 1)`` reflects what is currently used for filtering in the FPGA. + ``Working-copy`` cannot be written directly. Only ``shadow-copy`` allows direct write. + + (3) All ``set`` actions are performed on ``shadow-copy`` ONLY. + + (4) Only when PEF_APPLY is called, ``working-copy`` and FPGA are updated with values from the ``shadow-copy``. + +Corresponding CLI command: ``PEF_INIT`` .. code-block:: python - await port.emulation.flows[flow_idx].shadow_filter.initiating.set() + flow = port.emulation.flows[0] + await flow.shadow_filter.initiating.set() Apply ------ +Applies filter definitions from "shadow-copy" to "working-copy". This +also pushes these settings to the FPGA. + +Corresponding CLI command: ``PEF_APPLY`` .. code-block:: python - await port.emulation.flows[flow_idx].shadow_filter.apply.set() + flow = port.emulation.flows[0] + await flow.shadow_filter.apply.set() Enable ------ +Defines if filtering is enabled for the flow. + +.. note:: + + For SET, the only allowed ``_filter_type`` is ``shadow-copy`` + + +Corresponding CLI command: ``PEF_ENABLE`` .. code-block:: python - await port.emulation.flows[flow_idx].shadow_filter.enable.set_on() - await port.emulation.flows[flow_idx].shadow_filter.enable.set_off() - await port.emulation.flows[flow_idx].shadow_filter.enable.get() + flow = port.emulation.flows[0] + await flow.shadow_filter.enable.set(state=enums.OnOff.ON) + await flow.shadow_filter.enable.set(state=enums.OnOff.OFF) + + resp = await flow.shadow_filter.enable.get() + resp.state + Cancel ------ +Undo updates to shadow filter settings, sets dirty false. + +Corresponding CLI command: ``PEF_CANCEL`` .. code-block:: python - await port.emulation.flows[flow_idx].shadow_filter.cancel.set() + flow = port.emulation.flows[0] + await flow.shadow_filter.cancel.set() Filter Mode ----------- +Control the filter mode. + +Corresponding CLI command: ``PEF_MODE`` .. code-block:: python - await port.emulation.flows[flow_idx].shadow_filter.use_basic_mode() - await port.emulation.flows[flow_idx].shadow_filter.use_extended_mode() - await port.emulation.flows[flow_idx].shadow_filter.get_mode() + flow = port.emulation.flows[0] + await flow.shadow_filter.use_basic_mode() + await flow.shadow_filter.use_extended_mode() + + filter = await flow.shadow_filter.get_mode() + + if isinstance(filter, misc.BasicImpairmentFlowFilter): + ... - await port.emulation.flows[flow_idx].working_filter.get_mode() + if isinstance(filter, misc.ExtendedImpairmentFlowFilter): + ... diff --git a/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/configuration.rst b/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/configuration.rst index c838f8d2..2da6ca3f 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/configuration.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/configuration.rst @@ -1,9 +1,19 @@ -Range -========================= +Latency & Jitter Configuration +============================== + +Latency Range +-------------- + +Retrieve minimum and maximum configurable latency per flow in nanoseconds. + +Corresponding CLI command: ``PE_LATENCYRANGE`` .. code-block:: python - await port.emulation.flows[flow_idx].latency_range.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + resp = await flow.latency_range.get() + resp.min + resp.max diff --git a/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/distribution.rst b/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/distribution.rst index 0fbd28b3..5c8f6e9b 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/distribution.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/distribution.rst @@ -1,92 +1,221 @@ -Distribution -========================= +Latency & Jitter Distribution +============================= -Off +Enable/Disable ----------------------- +Control whether this impairment distribution is enabled. + +.. note:: + + This command is not applicable for PE_BANDPOLICER and PE_BANDSHAPER because they have a separate ``ON / OFF`` parameter. + +Corresponding CLI command: ``PED_ENABLE`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.off.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.off.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.enable.set(action=enums.OnOff.ON) + await flow.impairment_distribution.latency_jitter_type_config.enable.set_on() + await flow.impairment_distribution.latency_jitter_type_config.enable.set(action=enums.OnOff.OFF) + await flow.impairment_distribution.latency_jitter_type_config.enable.set_off() -Enable + resp = await flow.impairment_distribution.latency_jitter_type_config.off.get() + resp.action + +Off Distribution ----------------------- +Configure Impairments Distribution to OFF. Assigning a different distribution than OFF to an impairment +will activate the impairment. To de-activate the impairment assign distribution OFF. + +Corresponding CLI command: ``PED_OFF`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.enable.set_on() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.enable.set_off() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.enable.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.off.set() + + resp = await flow.impairment_distribution.latency_jitter_type_config.off.get() + resp.action Constant ----------------------- +Configuration of Constant Delay distribution (DELAY only). Unit is ns (must be +multiples of 100ns). Default value: Minimum supported per speed and FEC mode. + +.. note:: + + If the latency is less than minimum latency, value is set to minimum latency. If the latency is greater than maximum latency, value is set to maximum latency. + +Corresponding CLI command: ``PED_CONST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.constant_delay.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.constant_delay.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.constant_delay.set(delay=100) + + resp = await flow.impairment_distribution.latency_jitter_type_config.constant_delay.get() + resp.delay Accumulative Burst Distribution ------------------------------- +Configuration of Accumulate & Burst distribution (DELAY only). + +.. note:: + + If the delay is less than minimum latency, value is set to minimum latency. If the delay is greater than maximum latency, value is set to maximum latency. + +Corresponding CLI command: ``PED_ACCBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.accumulate_and_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.accumulate_and_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.accumulate_and_burst.set(delay=1300) + + resp = await flow.impairment_distribution.latency_jitter_type_config.accumulate_and_burst.get() + resp.delay Step Distribution --------------------------- +Configuration of Step distribution (DELAY only). + +.. note:: + + If the low/high is less than minimum latency, value is set to minimum latency. If the low/high is greater than maximum latency, value is set to maximum latency. + + +Corresponding CLI command: ``PED_STEP`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.step.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.step.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.step.set(low=1300, high=77000) + + resp = await flow.impairment_distribution.latency_jitter_type_config.step.get() + resp.low + resp.high Uniform Distribution -------------------------- +Configuration of Uniform distribution. + +.. note:: + + If minimum is less than minimum, value is set to minimum. If minimum is greater than maximum, value is set to maximum. + +Corresponding CLI command: ``PED_UNI`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.uniform.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.uniform.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.uniform.set(minimum=1, maximum=1) + + resp = await flow.impairment_distribution.latency_jitter_type_config.uniform.get() + resp.minimum + resp.maximum Gaussian Distribution -------------------------- +Configuration of Gaussian distribution. + +.. note:: + + In case of ``_impairment_type_xindex != DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + (2) mean should always be at least 3 times the standard deviation, this to ensure that the impairment distance is always positive. + + In case of ``_impairment_type_xindex = DELAY``: + (1) mean plus 3 times standard deviation should be less than or equal to the maximum latency. + (2) mean minus 3 times the standard deviation should be greater than or equal to minimum latency. + +Corresponding CLI command: ``PED_GAUSS`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.gaussian.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.gaussian.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.gaussian.set(mean=1, std_deviation=1) + + resp = await flow.impairment_distribution.latency_jitter_type_config.gaussian.get() + resp.mean + resp.std_deviation Poisson Distribution -------------------------- +Configuration of "Poisson" distribution. + +.. note:: + + Standard deviation is derived from mean, i.e., standard deviation = SQRT(mean). + + In case of ``_impairment_type_xindex != DELAY``, mean plus 3 times standard deviation should be less than or equal to max allowed (4194288). + + In case of ``_impairment_type_xindex = DELAY``, mean plus 3 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_POISSON`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.poisson.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.poisson.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.poisson.set(mean=100) + + resp = await flow.impairment_distribution.latency_jitter_type_config.poisson.get() + resp.mean Gamma Distribution -------------------------- +Configuration of Gamma distribution. + +.. note:: + + Mean and Standard deviation are calculated from Shape and Scale parameters and validation is performed using those. + standard deviation = [SQRT(shape * scale * scale)]mean = [shape * scale]. + + In case of ``_impairment_type_xindex != DELAY``, + (1) mean plus 4 times standard deviation should be less than or equal to max allowed(4194288). + (2)shape and scale should be greater than or equal to 0. + + In case of ``_impairment_type_xindex = DELAY``, mean plus 4 times standard deviation should be less than or equal to the maximum latency. + +Corresponding CLI command: ``PED_GAMMA`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.gamma.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.gamma.get() - + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.gamma.set(shape=1, scale=1) + + resp = await flow.impairment_distribution.latency_jitter_type_config.gamma.get() + resp.shape + resp.scale + Custom Distribution -------------------------- +Associate a custom distribution to a flow and impairment type. -.. code-block:: python +.. note:: - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.custom.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.custom.get() + Before associating a custom distribution, the below validation checks are applied. -Scheduling --------------------------- + In case of ``_impairment_type_xindex != DELAY``, + (1) Custom values should be less than or equal to max allowed (4194288). + (2) Custom distribution bust contain 512 values. + + In case of ``_impairment_type_xindex = DELAY``, + (1) Custom values should be less than or equal to the maximum latency. + (2) Custom values should be greater than or equal to minimum latency. + (3) Custom distribution should contain 1024 values. + +Corresponding CLI command: ``PED_CUST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.schedule.set() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.schedule.get() - await port.emulation.flows[flow_idx].impairment_distribution.latency_jitter_type_config.one_shot_status.get() \ No newline at end of file + # Custom distribution for impairment Corruption + flow = port.emulation.flows[1] # e.g. flow_id = 1 + data_x=[0, 1] * 256 + await port.custom_distributions.assign(0) + await port.custom_distributions[0].comment.set(comment="Example Custom Distribution") + await port.custom_distributions[0].definition.set(linear=enums.OnOff.OFF, symmetric=enums.OnOff.OFF, entry_count=len(data_x), data_x=data_x) + await flow.impairment_distribution.latency_jitter_type_config.custom.set(cust_id=0) + + resp = await flow.impairment_distribution.latency_jitter_type_config.custom.get() + resp.cust_id diff --git a/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/scheduling.rst b/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/scheduling.rst new file mode 100644 index 00000000..80576210 --- /dev/null +++ b/docs/source/api_ref/hlapiv1/port/chimera/latencyjitter/scheduling.rst @@ -0,0 +1,37 @@ +Latency & Jitter Scheduling +============================ + +Schedule +-------------------------- +Configure the impairment scheduler function. The configuration of the scheduler +depends on the kind of distribution to schedule: + +1. Burst distributions: "Fixed Burst" and "Accumulate and Burst". +2. Non-Burst distributions: All others. For burst distributions, the scheduler can be configured for "One-shot" operation or "Repeat Operation". When running in "Repeat Operation" the "Repeat Period" must be configured. For non-burst distributions, the scheduler can be configured operate in either "Continuous" or "Repeat Period" modes. When running in "Repeat Period" configuration of "Duration" and "Repeat Period" is required. + +Corresponding CLI command: ``PED_SCHEDULE`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=1, period=1) # repeat pattern + await flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0) # continuous + + resp = await flow.impairment_distribution.latency_jitter_type_config.schedule.get() + + +One-Shot Status +-------------------------- +Retrieves the one-shot completion status. + +.. note:: + + The return value is only valid, if the configured distribution is either accumulate & burst (DELAY) or fixed burst (non-DELAY). + +Corresponding CLI command: ``PED_ONESHOTSTATUS`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + resp = await flow.impairment_distribution.latency_jitter_type_config.one_shot_status.get() + resp.one_shot_status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/misorder/configuration.rst b/docs/source/api_ref/hlapiv1/port/chimera/misorder/configuration.rst index 4bd26c88..630b40d3 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/misorder/configuration.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/misorder/configuration.rst @@ -1,9 +1,24 @@ -Depth +Misorder Configuration ========================= +Misorder Depth +--------------- + +Configures the misordering depth in number of packets. + +.. note:: + + probability * (depth + 1) should be less than 1,000,000. (see PED_FIXED) + +Corresponding CLI command: ``PE_MISORDER`` + .. code-block:: python - await port.emulation.flows[flow_idx].misordering.set() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.misordering.set(depth=1) + + resp = await flow.misordering.get() + resp.depth diff --git a/docs/source/api_ref/hlapiv1/port/chimera/misorder/distribution.rst b/docs/source/api_ref/hlapiv1/port/chimera/misorder/distribution.rst index 8b01c712..59113d77 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/misorder/distribution.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/misorder/distribution.rst @@ -1,44 +1,74 @@ -Distribution +Misorder Distribution ========================= -Off +Enable/Disable ----------------------- +Control whether this impairment distribution is enabled. + +.. note:: + + This command is not applicable for PE_BANDPOLICER and PE_BANDSHAPER because they have a separate ``ON / OFF`` parameter. + +Corresponding CLI command: ``PED_ENABLE`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.off.set() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.off.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.misorder_type_config.enable.set(action=enums.OnOff.ON) + await flow.impairment_distribution.misorder_type_config.enable.set_on() + await flow.impairment_distribution.misorder_type_config.enable.set(action=enums.OnOff.OFF) + await flow.impairment_distribution.misorder_type_config.enable.set_off() + + resp = await flow.impairment_distribution.misorder_type_config.off.get() + resp.action -Enable +Off Distribution ----------------------- +Configure Impairments Distribution to OFF. Assigning a different distribution than OFF to an impairment +will activate the impairment. To de-activate the impairment assign distribution OFF. + +Corresponding CLI command: ``PED_OFF`` + .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.enable.set_on() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.enable.set_off() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.enable.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.misorder_type_config.off.set() + + resp = await flow.impairment_distribution.misorder_type_config.off.get() + resp.action + Fixed Rate Distribution ----------------------- +Configuration of Fixed Rate distribution. This is predictable distribution with +nearly equal distance between impairments, to match the configured probability. -.. code-block:: python +.. note:: - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.fixed_rate.set() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.fixed_rate.get() + In case of misordering, a special limit applies, probability * (depth + 1) should be less than 1000000. -Fixed Burst Distribution -------------------------- +Corresponding CLI command: ``PED_FIXED`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.fixed_burst.set() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.fixed_burst.get() + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.misorder_type_config.fixed_rate.set(probability=10_000) + + resp = await flow.impairment_distribution.misorder_type_config.fixed_rate.get() + resp.probability -Scheduling --------------------------- +Fixed Burst Distribution +------------------------- +Configuration of Fixed Burst distribution. + +Corresponding CLI command: ``PED_FIXEDBURST`` .. code-block:: python - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.schedule.set() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.schedule.get() - await port.emulation.flows[flow_idx].impairment_distribution.misorder_type_config.one_shot_status.get() \ No newline at end of file + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.misorder_type_config.fixed_burst.set(burst_size=1300) + + resp = await flow.impairment_distribution.misorder_type_config.fixed_burst.get() + resp.burst_size diff --git a/docs/source/api_ref/hlapiv1/port/chimera/misorder/scheduling.rst b/docs/source/api_ref/hlapiv1/port/chimera/misorder/scheduling.rst new file mode 100644 index 00000000..d535c132 --- /dev/null +++ b/docs/source/api_ref/hlapiv1/port/chimera/misorder/scheduling.rst @@ -0,0 +1,37 @@ +Misorder Scheduling +========================= + +Schedule +-------------------------- +Configure the impairment scheduler function. The configuration of the scheduler +depends on the kind of distribution to schedule: + +1. Burst distributions: "Fixed Burst" and "Accumulate and Burst". +2. Non-Burst distributions: All others. For burst distributions, the scheduler can be configured for "One-shot" operation or "Repeat Operation". When running in "Repeat Operation" the "Repeat Period" must be configured. For non-burst distributions, the scheduler can be configured operate in either "Continuous" or "Repeat Period" modes. When running in "Repeat Period" configuration of "Duration" and "Repeat Period" is required. + +Corresponding CLI command: ``PED_SCHEDULE`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.impairment_distribution.misorder_type_config.schedule.set(duration=1, period=1) # repeat pattern + await flow.impairment_distribution.misorder_type_config.schedule.set(duration=0, period=0) # continuous + + resp = await flow.impairment_distribution.misorder_type_config.schedule.get() + + +One-Shot Status +-------------------------- +Retrieves the one-shot completion status. + +.. note:: + + The return value is only valid, if the configured distribution is either accumulate & burst (DELAY) or fixed burst (non-DELAY). + +Corresponding CLI command: ``PED_ONESHOTSTATUS`` + +.. code-block:: python + + flow = port.emulation.flows[1] # e.g. flow_id = 1 + resp = await flow.impairment_distribution.misorder_type_config.one_shot_status.get() + resp.one_shot_status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/policer/index.rst b/docs/source/api_ref/hlapiv1/port/chimera/policer/index.rst index ef04b9f4..b1509fd5 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/policer/index.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/policer/index.rst @@ -5,10 +5,21 @@ Policer Applicable to Chimera port only. -Configuration +Policer Configuration ----------------------- +Configures the bandwidth policer. + +Corresponding CLI command: ``PE_BANDPOLICER`` .. code-block:: python - await port.emulation.flows[flow_idx].bandwidth_control.policer.set() - await port.emulation.flows[flow_idx].bandwidth_control.policer.get() \ No newline at end of file + # Configure bandwidth control - Policer + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.bandwidth_control.policer.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L1, cir=10_000, cbs=1_000) + await flow.bandwidth_control.policer.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L2, cir=10_000, cbs=1_000) + + resp = await flow.bandwidth_control.policer.get() + resp.on_off + resp.mode + resp.cir + resp.cbs \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/shaper/index.rst b/docs/source/api_ref/hlapiv1/port/chimera/shaper/index.rst index cba85a79..230b975b 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/shaper/index.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/shaper/index.rst @@ -5,10 +5,22 @@ Shaper Applicable to Chimera port only. -Configuration +Shaper Configuration ----------------------- +Configures the bandwidth shaper. L1 (0) (Shaper performed at Layer 1 level. I.e. including the preamble and min interpacket gap) L2 (1) (Shaper performed at Layer 2 level. I.e. excluding the preamble and min interpacket gap) Default value: L2 (0) + +Corresponding CLI command: ``PE_BANDSHAPER`` .. code-block:: python - await port.emulation.flows[flow_idx].bandwidth_control.shaper.set() - await port.emulation.flows[flow_idx].bandwidth_control.shaper.get() \ No newline at end of file + # Configure bandwidth control - Shaper + flow = port.emulation.flows[1] # e.g. flow_id = 1 + await flow.bandwidth_control.shaper.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L1, cir=10_000, cbs=1_000, buffer_size=1_000) + await flow.bandwidth_control.shaper.set(on_off=enums.OnOff.ON, mode=enums.PolicerMode.L2, cir=10_000, cbs=1_000, buffer_size=1_000) + + resp = await flow.bandwidth_control.shaper.get() + resp.on_off + resp.mode + resp.cir + resp.cbs + resp.buffer_size \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/chimera/statistics/index.rst b/docs/source/api_ref/hlapiv1/port/chimera/statistics/index.rst index b316d3fe..15808884 100644 --- a/docs/source/api_ref/hlapiv1/port/chimera/statistics/index.rst +++ b/docs/source/api_ref/hlapiv1/port/chimera/statistics/index.rst @@ -5,6 +5,11 @@ Statistics for Chimera ports. Clear Counter ------------- +Clear all the impairment (duplicate, drop, mis-ordered, corrupted, latency and +jitter) statistics for a Chimera port and flows on the port. The byte and packet +counts will restart at zero. + +Corresponding CLI command: ``PE_CLEAR`` .. code-block:: python @@ -12,47 +17,93 @@ Clear Counter Corruption ------------- +Obtains statistics concerning all the packets corrupted on between this receive port and its partner TX port. + +Corresponding CLI command: ``PE_CORTOTAL`` .. code-block:: python - await port.emulation.statistics.corrupted.get() + port_corrupted = await port.emulation.statistics.corrupted.get() + port_corrupted.fcs_corrupted_pkt_count + port_corrupted.fcs_corrupted_pkt_ratio + port_corrupted.ip_corrupted_pkt_count + port_corrupted.ip_corrupted_pkt_ratio + port_corrupted.tcp_corrupted_pkt_count + port_corrupted.tcp_corrupted_pkt_ratio + port_corrupted.total_corrupted_pkt_count + port_corrupted.total_corrupted_pkt_ratio + port_corrupted.udp_corrupted_pkt_count + port_corrupted.udp_corrupted_pkt_ratio Drop Counter ------------- +Obtains statistics concerning all the packets dropped between this receive port and its partner TX port. + +Corresponding CLI command: ``PE_DROPTOTAL`` .. code-block:: python - await port.emulation.statistics.drop.get() + port_drop = await port.emulation.statistics.drop.get() + port_drop.pkt_drop_count_total + port_drop.pkt_drop_count_programmed + port_drop.pkt_drop_count_bandwidth + port_drop.pkt_drop_count_other + port_drop.pkt_drop_ratio_total + port_drop.pkt_drop_ratio_programmed + port_drop.pkt_drop_ratio_bandwidth + port_drop.pkt_drop_ratio_other Duplication Counter ------------------- +Obtains statistics concerning all the packets duplicated between this receive port and its partner TX port. + +Corresponding CLI command: ``PE_DUPTOTAL`` .. code-block:: python - await port.emulation.statistics.duplicated.get() + port_duplicated = await port.emulation.statistics.duplicated.get() + port_duplicated.pkt_count + port_duplicated.ratio Jittered Counter ---------------- +Obtains statistics concerning all the packets jittered between this receive port +and its partner TX port. + +Corresponding CLI command: ``PE_JITTERTOTAL`` .. code-block:: python - await port.emulation.statistics.jittered.get() + port_jittered = await port.emulation.statistics.jittered.get() + port_jittered.pkt_count + port_jittered.ratio Delay Counter ------------- +Obtains statistics concerning all the packets delayed this receive port and its partner TX port. + +Corresponding CLI command: ``PE_LATENCYTOTAL`` .. code-block:: python - await port.emulation.statistics.latency.get() + port_delayed = await port.emulation.statistics.latency.get() + port_delayed.pkt_count + port_delayed.ratio Misordering Counter ------------------- +Obtains statistics concerning all the packets mis-ordered between this receive +port and its partner TX port. + +Corresponding CLI command: ``PE_MISTOTAL`` .. code-block:: python - await port.emulation.statistics.mis_ordered.get() \ No newline at end of file + port_misordered = await port.emulation.statistics.mis_ordered.get() + port_misordered.pkt_count + port_misordered.ratio \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/control.rst b/docs/source/api_ref/hlapiv1/port/control.rst index 9175a3f6..1029fccc 100644 --- a/docs/source/api_ref/hlapiv1/port/control.rst +++ b/docs/source/api_ref/hlapiv1/port/control.rst @@ -3,81 +3,175 @@ Control Inter-frame Gap --------------- +The minimum gap between packets in the traffic generated for a port. The gap includes the Ethernet preamble. + +Corresponding CLI command: ``P_INTERFRAMEGAP`` .. code-block:: python - await port.interframe_gap.set() - await port.interframe_gap.get() + # Inter-frame Gap + await port.interframe_gap.set(min_byte_count=20) + + resp = await port.interframe_gap.get() + resp.min_byte_count PAUSE Frames --------------- +Whether a port responds to incoming Ethernet PAUSE frames by holding back outgoing traffic. + +Corresponding CLI command: ``P_PAUSE`` .. code-block:: python + # PAUSE Frames + await port.pause.set(on_off=enums.OnOff.ON) await port.pause.set_on() + await port.pause.set(on_off=enums.OnOff.OFF) await port.pause.set_off() - await port.pause.get() + + resp = await port.pause.get() + resp.on_off Auto-Train ----------- +The interval between sending out training packets, allowing a switch to learn +the port's MAC address. Layer-2 switches configure themselves automatically by +detecting the source MAC addresses of packets received on each port. If a port +only receives, and does not itself transmit test traffic, then the switch will +never learn its MAC address. Also, if transmission is very rare the switch will +age-out the learned MAC address. By setting the auto-train interval you instruct +the port to send switch training packets, independent of whether the port is +transmitting test traffic. + +Corresponding CLI command: ``P_AUTOTRAIN`` .. code-block:: python - await port.autotrain.set() - await port.autotrain.get() + # Auto-Train + await port.autotrain.set(interval=1) + + resp = await port.autotrain.get() + resp.interval Gap Monitor ----------- +The gap-start and gap-stop criteria for the port's gap monitor. The gap monitor +expects a steady stream of incoming packets, and detects larger-than-allowed +gaps between them. Once a gap event is encountered it requires a certain number +of consecutive packets below the threshold to end the event. + +Corresponding CLI command: ``P_GAPMONITOR`` .. code-block:: python - await port.gap_monitor.set() - await port.gap_monitor.get() + # Gap Monitor + await port.gap_monitor.set(start=100, stop=10) + + resp = await port.gap_monitor.get() + resp.start + resp.stop Priority Flow Control --------------------- +This setting control whether a port responds to incoming Ethernet Priority Flow Control (PFC) frames, by holding back outgoing traffic for that priority. + +Corresponding CLI command: ``P_PFCENABLE`` .. code-block:: python - await port.pfc_enable.set() - await port.pfc_enable.get() + # Priority Flow Control + await port.pfc_enable.set( + cos_0=enums.OnOff.ON, + cos_1=enums.OnOff.OFF, + cos_2=enums.OnOff.ON, + cos_3=enums.OnOff.OFF, + cos_4=enums.OnOff.ON, + cos_5=enums.OnOff.OFF, + cos_6=enums.OnOff.ON, + cos_7=enums.OnOff.OFF, + ) + + resp = await port.pfc_enable.get() + resp.cos_0 + resp.cos_1 + resp.cos_2 + resp.cos_3 + resp.cos_4 + resp.cos_5 + resp.cos_6 + resp.cos_7 Loopback -------- +The loopback mode for a port. Ports can be configured to perform two different +kinds of loopback: (1) External RX-to-TX loopback, where the received packets +are re-transmitted immediately. The packets are still processed by the receive +logic, and can be captured and analyzed. (2) Internal TX-to-RX loopback, where +the transmitted packets are received directly by the port itself. This is mainly +useful for testing the generated traffic patterns before actual use. + +Corresponding CLI command: ``P_LOOPBACK`` .. code-block:: python + # Loopback + await port.loop_back.set(mode=enums.LoopbackMode.L1RX2TX) await port.loop_back.set_l1rx2tx() + await port.loop_back.set(mode=enums.LoopbackMode.L2RX2TX) await port.loop_back.set_l2rx2tx() + await port.loop_back.set(mode=enums.LoopbackMode.L3RX2TX) await port.loop_back.set_l3rx2tx() + await port.loop_back.set(mode=enums.LoopbackMode.NONE) await port.loop_back.set_none() + await port.loop_back.set(mode=enums.LoopbackMode.PORT2PORT) await port.loop_back.set_port2port() + await port.loop_back.set(mode=enums.LoopbackMode.TXOFF2RX) await port.loop_back.set_txoff2rx() + await port.loop_back.set(mode=enums.LoopbackMode.TXON2RX) await port.loop_back.set_txon2rx() - await port.loop_back.get() + + resp = await port.loop_back.get() + resp.mode BRR Mode -------- +Selects the Master/Slave setting of 100 Mbit/s, 1000 Mbit/s BroadR-Reach copper interfaces. + +Corresponding CLI command: ``P_BRRMODE`` .. code-block:: python + # BRR Mode + await port.brr_mode.set(mode=enums.BRRMode.MASTER) await port.brr_mode.set_master() + await port.brr_mode.set(mode=enums.BRRMode.SLAVE) await port.brr_mode.set_slave() - await port.brr_mode.get() + + resp = await port.brr_mode.get() + resp.mode MDI/MDIX Mode ------------- +Selects the MDI/MDIX behavior of copper interfaces. + +Corresponding CLI command: ``P_MDIXMODE`` .. code-block:: python + # MDI/MDIX Mode + await port.mdix_mode.set(mode=enums.MDIXMode.AUTO) await port.mdix_mode.set_auto() + await port.mdix_mode.set(mode=enums.MDIXMode.MDI) await port.mdix_mode.set_mdi() + await port.mdix_mode.set(mode=enums.MDIXMode.MDIX) await port.mdix_mode.set_mdix() - await port.mdix_mode.get() \ No newline at end of file + + resp = await port.mdix_mode.get() + resp.mode \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/eee.rst b/docs/source/api_ref/hlapiv1/port/eee.rst index be681c97..93c9e179 100644 --- a/docs/source/api_ref/hlapiv1/port/eee.rst +++ b/docs/source/api_ref/hlapiv1/port/eee.rst @@ -4,60 +4,116 @@ Energy Efficiency Ethernet Capabilities ------------ +Read EEE capabilities of the port (variable size, one for each supported speed, returns 0s if no EEE). + +Corresponding CLI command: ``P_LPSUPPORT`` .. code-block:: python - await port.eee.capabilities.get() + # EEE- Capabilities + resp = await port.eee.capabilities.get() + resp.eee_capabilities Partner Capabilities -------------------- +Displays the EEE capabilities advertised during auto-negotiation by the far side (link partner). + +Corresponding CLI command: ``P_LPPARTNERAUTONEG`` .. code-block:: python - await port.eee.partner_capabilities.get() + # EEE - Partner Capabilities + resp = await port.eee.partner_capabilities.get() + resp.cap_1000base_t + resp.cap_100base_kx + resp.cap_10gbase_kr + resp.cap_10gbase_kx4 + resp.cap_10gbase_t Control ------------ +Enables/disables Energy Efficient Ethernet (EEE) on the port. + +Corresponding CLI command: ``P_LPENABLE`` .. code-block:: python + # EEE - Control + await port.eee.enable.set(on_off=enums.OnOff.OFF) await port.eee.enable.set_off() + await port.eee.enable.set(on_off=enums.OnOff.ON) await port.eee.enable.set_on() - await port.eee.enable.get() + + resp = await port.eee.enable.get() + resp.on_off Low Power TX Mode ----------------- +Enables/disables the transmission of Low Power Idles (LPIs) on the port. When enabled, the transmit side of the port will automatically enter low-power mode (and leave) low-power mode in periods of low or no traffic. LPIs will only be transmitted if the Link Partner (receiving port) has advertised EEE capability +for the selected port speed during EEE auto-negotiation. + +Corresponding CLI command: ``P_LPTXMODE`` .. code-block:: python + # EEE - Low Power TX Mode + await port.eee.mode.set(on_off=enums.OnOff.ON) await port.eee.mode.set_off() + await port.eee.mode.set(on_off=enums.OnOff.OFF) await port.eee.mode.set_on() - await port.eee.mode.get() + + resp = await port.eee.mode.get() + resp.on_off RX Power ------------ +Obtain the RX power recorded during training for the four channels. + +Corresponding CLI command: ``P_LPRXPOWER`` .. code-block:: python - await port.eee.rx_power.get() + # EEE - RX Power + resp = await port.eee.rx_power.get() + resp.channel_a + resp.channel_b + resp.channel_c + resp.channel_d SNR Margin ------------ +Displays the SNR margin on the four link channels (Channel A-D) as reported by the PHY. It is displayed in units of 0.1dB. + +Corresponding CLI command: ``P_LPSNRMARGIN`` .. code-block:: python - await port.eee.snr_margin.get() + # EEE - SNR Margin + resp = await port.eee.snr_margin.get() + resp.channel_a + resp.channel_b + resp.channel_c + resp.channel_d Status ------------ +Displays the Energy Efficient Ethernet (EEE) status as reported by the PHY. + +Corresponding CLI command: ``P_LPSTATUS`` .. code-block:: python - await port.eee.status.get() + # EEE - Status + resp = await port.eee.status.get() + resp.link_up + resp.rxc + resp.rxh + resp.txc + resp.txh diff --git a/docs/source/api_ref/hlapiv1/port/fault.rst b/docs/source/api_ref/hlapiv1/port/fault.rst index b9c6658a..b374743b 100644 --- a/docs/source/api_ref/hlapiv1/port/fault.rst +++ b/docs/source/api_ref/hlapiv1/port/fault.rst @@ -3,19 +3,36 @@ Fault Signaling ------------ +Sets the remote/local fault signaling behavior of the port (performed by the Reconciliation Sub-layer). By default, the port acts according to the standard, i.e. when receiving a bad signal, it transmits "Remote Fault indications"on the output and when receiving a "Remote Fault indication"from the far-side it will +transmit IDLE sequences. + +Corresponding CLI command: ``P_FAULTSIGNALING`` .. code-block:: python + # Fault - Signaling + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.DISABLED) await port.fault.signaling.set_disabled() + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.FORCE_LOCAL) await port.fault.signaling.set_force_local() + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.FORCE_REMOTE) await port.fault.signaling.set_force_remote() + await port.fault.signaling.set(fault_signaling=enums.FaultSignaling.NORMAL) await port.fault.signaling.set_normal() - await port.fault.signaling.get() + + resp = await port.fault.signaling.get() + resp.fault_signaling Status ------------ +Shows if a local or remote fault is currently being detected by the Reconciliation Sub-layer of the port. + +Corresponding CLI command: ``P_FAULTSTATUS`` .. code-block:: python - await port.fault.status.get() \ No newline at end of file + # Fault - Status + resp = await port.fault.status.get() + resp.local_fault_status + resp.remote_fault_status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/filter/config.rst b/docs/source/api_ref/hlapiv1/port/filter/config.rst index 886c7940..4cc77e8b 100644 --- a/docs/source/api_ref/hlapiv1/port/filter/config.rst +++ b/docs/source/api_ref/hlapiv1/port/filter/config.rst @@ -3,36 +3,108 @@ Configuration Enable ----------------- +Whether a filter is currently active on a port. While a filter is enabled its +condition cannot be changed, nor can any match term or length terms used by it. + +Corresponding CLI command: ``PF_ENABLE`` .. code-block:: python + await filter.enable.set(on_off=enums.OnOff.ON) await filter.enable.set_on() + await filter.enable.set(on_off=enums.OnOff.OFF) await filter.enable.set_off() - await filter.enable.get() + + resp = await filter.enable.get() + resp.on_off Description ----------- +The description of a filter. + +Corresponding CLI command: ``PF_COMMENT`` .. code-block:: python - await filter.comment.set() - await filter.comment.get() + await filter.comment.set(comment="this is a comment") + + resp = await filter.comment.get() + resp.comment Condition --------------- +The boolean condition on the terms specifying when the filter is satisfied. The condition uses a canonical and-or-not expression on the match terms and length terms. + +The condition is specified using a number of compound terms, each encoded as an integer value specifying an arbitrary set of the match terms +and length terms defined for the port. Each match or length term has a specific power-of-two value, and the set is encoded as the sum of the values for the contained terms: + +Value for match term ``[match_term_xindex] = 2^match_term_xindex`` + +Value for length term ``[length_term_xindex] = 2^(length_term_xindex+16)`` + +A compound term is true if all the match terms and length terms contained in it are true. This supports the and-part of the condition. +If some compound term is satisfied, the condition as a whole is true. + +This is the or-part of the condition. The first few compound terms at the even positions (second, fourth, ...) are inverted, +and all the contained match terms and length terms must be false at the same time that the those of the preceding compound term are true. +This is the not-part of the condition. + +At the top level, a condition is a bunch of things or-ed together. + +`` = `` + +Two of the or-operands are *general*, two are 'simple'. + +`` = or or or `` + +A 'general' and-expression can include negated terms. + +`` = and and ... and not and ... and not `` + +A 'simple' and-expression can only have non-negated terms. + +`` = and and ... and `` + +`` = `` + +`` = `` + +In practice, the simplest way to generate these encodings is to use the ValkyrieManager, +which supports Boolean expressions using the operators ``&, |, and ~``, and simply query the chassis for the resulting script-level definition. + +Corresponding CLI command: ``PF_CONDITION`` .. code-block:: python - await filter.condition.set() - await filter.condition.get() + await filter.condition.set( + and_expression_0=0, + and_not_expression_0=0, + and_expression_1=0, + and_not_expression_1=0, + and_expression_2=0, + and_expression_3=0 + ) + + resp = await filter.condition.get() + resp.and_expression_0 + resp.and_not_expression_0 + resp.and_expression_1 + resp.and_not_expression_1 + resp.and_expression_2 + resp.and_expression_3 String Representation ---------------------- +The string representation of a filter. + +Corresponding CLI command: ``PF_STRING`` .. code-block:: python - await filter.string.set() - await filter.string.get() \ No newline at end of file + await filter.string.set(string_name="this is a name") + + resp = await filter.string.get() + resp.string_name \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/filter/create.rst b/docs/source/api_ref/hlapiv1/port/filter/create.rst index 10bb336e..d92cbe25 100644 --- a/docs/source/api_ref/hlapiv1/port/filter/create.rst +++ b/docs/source/api_ref/hlapiv1/port/filter/create.rst @@ -6,6 +6,8 @@ Create and Obtain Create a filter on the port, and obtain the filter object. The filter index is automatically assigned by the port. +Corresponding CLI command: ``PF_CREATE`` + .. code-block:: python filter = await port.filters.create() @@ -16,9 +18,10 @@ Obtain One Obtain an existing filter on the port with an explicit filter index. + .. code-block:: python - filter = port.filters.obtain(idx) + filter = port.filters.obtain(position_idx=0) Obtain Multiple @@ -28,7 +31,7 @@ Obtain multiple existing filters on the port with explicit filter indices. .. code-block:: python - filter_list = port.filters.obtain_multiple(*idx_list) + filter_list = port.filters.obtain_multiple(*[0,1,2]) Remove @@ -36,12 +39,8 @@ Remove Remove a filter on the port with an explicit filter index by the index manager of the port. -.. code-block:: python - - await port.filters.remove(idx) - -Remove a filter by deleting the object. +Corresponding CLI command: ``PF_DELETE`` .. code-block:: python - await filter.delete() \ No newline at end of file + await port.filters.remove(position_idx=0) diff --git a/docs/source/api_ref/hlapiv1/port/histogram/config.rst b/docs/source/api_ref/hlapiv1/port/histogram/config.rst index 5cfad75f..12a908d3 100644 --- a/docs/source/api_ref/hlapiv1/port/histogram/config.rst +++ b/docs/source/api_ref/hlapiv1/port/histogram/config.rst @@ -3,37 +3,117 @@ Configuration Enable ----------------- +Whether a histogram is currently active on a port. When turned on, all the bucket +counts are cleared to zero. Subsequently each packet matching the histogram source criteria is counted into one of the buckets. While a histogram is enabled its parameters cannot be changed. + +Corresponding CLI command: ``PD_ENABLE`` .. code-block:: python + await dataset.enable.set(on_off=enums.OnOff.ON) await dataset.enable.set_on() + await dataset.enable.set(on_off=enums.OnOff.OFF) await dataset.enable.set_off() - await dataset.enable.get() + + resp = await dataset.enable.get() + resp.on_off Data Source ----------- +The source criteria specifying what is counted, and for which packets, by a +histogram of a port. + +Corresponding CLI command: ``PD_SOURCE`` .. code-block:: python - await dataset.source.set() - await dataset.source.get() + await dataset.source.set( + source_type=enums.SourceType.TX_IFG, + which_packets=enums.PacketDetailSelection.ALL, + identity=0 + ) + await dataset.source.set( + source_type=enums.SourceType.TX_LEN, + which_packets=enums.PacketDetailSelection.ALL, + identity=0 + ) + await dataset.source.set( + source_type=enums.SourceType.RX_IFG, + which_packets=enums.PacketDetailSelection.ALL, + identity=0 + ) + await dataset.source.set( + source_type=enums.SourceType.RX_LEN, + which_packets=enums.PacketDetailSelection.ALL, + identity=0 + ) + await dataset.source.set( + source_type=enums.SourceType.RX_LATENCY, + which_packets=enums.PacketDetailSelection.ALL, + identity=0 + ) + await dataset.source.set( + source_type=enums.SourceType.RX_JITTER, + which_packets=enums.PacketDetailSelection.ALL, + identity=0 + ) + + resp = await dataset.source.get() + resp.source_type + resp.which_packets + resp.identity Data Range --------------- +The bucket ranges used for classifying the packets counted by a histogram of a +port. The packets are either counted by length, measured in bytes, by inter- +frame gap to the preceding packet, also measured in bytes, or by latency in +transmission measured in nanoseconds. There are a fixed number of buckets, each +middle bucket covering a fixed-size range of values which is a power of two. +The first and last buckets count all the packets that do not fit within the +ranges of the middle buckets. The buckets are placed at a certain offset by +specifying the first value that should be counted by the first middle bucket. + +Corresponding CLI command: ``PD_RANGE`` .. code-block:: python - await dataset.range.set() - await dataset.range.get() + await dataset.range.set( + start=1, #first value going into the second bucket + step=1, # the span of each middle bucket: (1) 1,2,4,8,16,32,64,128,256,512 (bytes, non-latency histograms).(2) 16,32,64,128,...,1048576,2097152 (nanoseconds, latency histograms). + bucket_count=10 # the total number of buckets + ) + + resp = await dataset.range.get() + resp.start + resp.step + resp.bucket_count Data Samples --------------- -Remove a histogram on the port with an explicit histogram index. +The current set of counts collected by a histogram for a port. There is one value +for each bucket, but any trailing zeros are left out. The list is empty if all +counts are zero. + +Corresponding CLI command: ``PD_SAMPLES`` + +.. code-block:: python + + resp = await dataset.samples.get() + resp.packet_counts + +Remove +--------------- + +Delete an existing histogram definition. + +Corresponding CLI command: ``PD_DELETE`` .. code-block:: python - await dataset.samples.get() \ No newline at end of file + # Remove a histogram on the port with an explicit histogram index by the index manager of the port. + await port.datasets.remove(position_idx=0) \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/histogram/create.rst b/docs/source/api_ref/hlapiv1/port/histogram/create.rst index 8ad4b473..a975a5d7 100644 --- a/docs/source/api_ref/hlapiv1/port/histogram/create.rst +++ b/docs/source/api_ref/hlapiv1/port/histogram/create.rst @@ -6,6 +6,8 @@ Create and Obtain Create a histogram on the port, and obtain the histogram object. The histogram index is automatically assigned by the port. +Corresponding CLI command: ``PD_CREATE`` + .. code-block:: python dataset = await port.datasets.create() @@ -16,9 +18,10 @@ Obtain One Obtain an existing histogram on the port with an explicit histogram index. + .. code-block:: python - dataset = port.datasets.obtain(idx) + dataset = port.datasets.obtain(key=0) Obtain Multiple @@ -26,9 +29,10 @@ Obtain Multiple Obtain multiple existing histograms on the port with explicit histogram indices. + .. code-block:: python - dataset_list = port.datasets.obtain_multiple(*idx_list) + dataset_list = port.datasets.obtain_multiple(*[0,1,2]) Remove @@ -36,12 +40,8 @@ Remove Remove a histogram on the port with an explicit histogram index by the index manager of the port. -.. code-block:: python - - await port.datasets.remove(idx) - -Remove a histogram by deleting the object. +Corresponding CLI command: ``PD_DELETE`` .. code-block:: python - await dataset.delete() \ No newline at end of file + await port.datasets.remove(position_idx=0) diff --git a/docs/source/api_ref/hlapiv1/port/identification.rst b/docs/source/api_ref/hlapiv1/port/identification.rst index 73098420..b59d719a 100644 --- a/docs/source/api_ref/hlapiv1/port/identification.rst +++ b/docs/source/api_ref/hlapiv1/port/identification.rst @@ -3,26 +3,40 @@ Identification Interface ---------- +Obtains the name of the physical interface type of a port. -.. code-block:: python +Corresponding CLI command: ``P_INTERFACE`` - await port.interface.get() +.. code-block:: python - port.on_interface_change(_callback_func) + # Interface + resp = await port.interface.get() + resp.interface Description ----------- +The description of a port. + +Corresponding CLI command: ``P_COMMENT`` .. code-block:: python + # Description await port.comment.set(comment="description") - await port.comment.get() + + resp = await port.comment.get() + resp.comment + +Optical Signal Level +--------------------- +Get the received signal level for optical ports. -Status ------- +Corresponding CLI command: ``P_STATUS`` .. code-block:: python - await port.status.get() \ No newline at end of file + # Status + resp = await port.status.get() + resp.optical_power \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/latency.rst b/docs/source/api_ref/hlapiv1/port/latency.rst index 7db7289f..eceb1953 100644 --- a/docs/source/api_ref/hlapiv1/port/latency.rst +++ b/docs/source/api_ref/hlapiv1/port/latency.rst @@ -3,20 +3,41 @@ Latency Mode ------------ +Latency is measured by inserting a time-stamp in each packet when it is transmitted, and relating it to the time when the packet is received. There are four separate modes for calculating the latency: + +1. Last-bit-out to last-bit-in, which measures basic bit-transit time, independent of packet length. +2. First-bit-out to last-bit-in, which adds the time taken to transmit the packet itself. +3. Last-bit-out to first-bit-in, which subtracts the time taken to transmit the packet itself. The same latency mode must be configured for the transmitting port and the receiving port; otherwise invalid measurements will occur. +4. First-bit-out to first-bit-in, which adds the time taken to transmit the packet itself, and subtracts the time taken to transmit the packet itself. The same latency mode must be configured for the transmitting port and the receiving port; otherwise invalid measurements will occur. + +Corresponding CLI command: ``P_LATENCYMODE`` .. code-block:: python + # Latency Mode + await port.latency_config.mode.set(mode=enums.LatencyMode.FIRST2FIRST) await port.latency_config.mode.set_first2first() + await port.latency_config.mode.set(mode=enums.LatencyMode.FIRST2LAST) await port.latency_config.mode.set_first2last() + await port.latency_config.mode.set(mode=enums.LatencyMode.LAST2FIRST) await port.latency_config.mode.set_last2first() + await port.latency_config.mode.set(mode=enums.LatencyMode.LAST2LAST) await port.latency_config.mode.set_last2last() - await port.latency_config.mode.get() + + resp = await port.latency_config.mode.get() + resp.mode Offset -------------- +An offset applied to the latency measurements performed for received traffic containing test payloads. This value affects the minimum, average, and maximum latency values obtained through the PR_TPLDLATENCY command. + +Corresponding CLI command: ``P_LATENCYOFFSET`` .. code-block:: python - await port.latency_config.offset.set() - await port.latency_config.offset.get() \ No newline at end of file + # Latency Offset + await port.latency_config.offset.set(offset=5) + + resp = await port.latency_config.offset.get() + resp.offset \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/lengthterm/config.rst b/docs/source/api_ref/hlapiv1/port/lengthterm/config.rst index 6297bd2e..8dc9458c 100644 --- a/docs/source/api_ref/hlapiv1/port/lengthterm/config.rst +++ b/docs/source/api_ref/hlapiv1/port/lengthterm/config.rst @@ -3,11 +3,22 @@ Configuration Length ----------------- +The specification for a length-based check that is applied on the packets +received on the port. + +Corresponding CLI command: ``PL_LENGTH`` .. code-block:: python - await length_term.length.set_at_least(byte_count) - await length_term.length.set_at_most(byte_count) - await length_term.length.get() + await length_term.length.set( + length_check_type=enums.LengthCheckType.AT_MOST, + size=100) + await length_term.length.set( + length_check_type=enums.LengthCheckType.AT_LEAST, + size=100) + + resp = await length_term.length.get() + resp.length_check_type + resp.size diff --git a/docs/source/api_ref/hlapiv1/port/lengthterm/create.rst b/docs/source/api_ref/hlapiv1/port/lengthterm/create.rst index d21449f0..17d71db5 100644 --- a/docs/source/api_ref/hlapiv1/port/lengthterm/create.rst +++ b/docs/source/api_ref/hlapiv1/port/lengthterm/create.rst @@ -18,7 +18,7 @@ Obtain an existing length term on the port with an explicit length term index. .. code-block:: python - length_term = port.length_terms.obtain(idx) + length_term = port.length_terms.obtain(key=0) Obtain Multiple @@ -28,20 +28,19 @@ Obtain multiple existing length terms on the port with explicit length term indi .. code-block:: python - length_term_list = port.length_terms.obtain_multiple(*idx_list) + length_term_list = port.length_terms.obtain_multiple(*[0,1,2]) Remove --------------- -Remove a length term on the port with an explicit length term index by the index manager of the port. +Deletes the length term definition with the specified sub-index value. A length +term cannot be deleted while it is used in the condition of any filter for the +port. -.. code-block:: python - - await port.length_terms.remove(idx) - -Remove a length term by deleting the object. +Corresponding CLI command: ``PL_DELETE`` .. code-block:: python - await length_term.delete() \ No newline at end of file + # Remove a length term on the port with an explicit length term index by the index manager of the port. + await port.length_terms.remove(position_idx=0) diff --git a/docs/source/api_ref/hlapiv1/port/linkflap.rst b/docs/source/api_ref/hlapiv1/port/linkflap.rst index 7f9ff4d0..d2f3b860 100644 --- a/docs/source/api_ref/hlapiv1/port/linkflap.rst +++ b/docs/source/api_ref/hlapiv1/port/linkflap.rst @@ -3,18 +3,34 @@ Link Flap Control ------------- +Enable / disable port 'link flap'. + +Corresponding CLI command: ``PP_LINKFLAP_ENABLE`` .. code-block:: python + # Link Flap - Control + await port.pcs_pma.link_flap.enable.set(on_off=enums.OnOff.ON) await port.pcs_pma.link_flap.enable.set_on() + await port.pcs_pma.link_flap.enable.set(on_off=enums.OnOff.OFF) await port.pcs_pma.link_flap.enable.set_off() - await port.pcs_pma.link_flap.enable.get() + + resp = await port.pcs_pma.link_flap.enable.get() + resp.on_off Configuration ------------- +Set port 'link flap' parameters. Notice: Period must be larger than duration. + +Corresponding CLI command: ``PP_LINKFLAP_PARAMS`` .. code-block:: python - await port.pcs_pma.link_flap.params.set() - await port.pcs_pma.link_flap.params.get() \ No newline at end of file + # Link Flap - Configuration + await port.pcs_pma.link_flap.params.set(duration=10, period=20, repetition=0) + + resp = await port.pcs_pma.link_flap.params.get() + resp.duration + resp.period + resp.repetition \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/matchterm/config.rst b/docs/source/api_ref/hlapiv1/port/matchterm/config.rst index 27cc7227..d218b1b8 100644 --- a/docs/source/api_ref/hlapiv1/port/matchterm/config.rst +++ b/docs/source/api_ref/hlapiv1/port/matchterm/config.rst @@ -1,29 +1,49 @@ Configuration ========================= -Mask and Value +Match ----------------- +The value that must be found at the match term position for packets received on +the port. The mask can make certain bit positions don't-care. + +Corresponding CLI command: ``PM_MATCH`` .. code-block:: python - await match_term.match.set() - await match_term.match.get() + await match_term.match.set(mask=Hex("FF"), value=Hex("00")) + + resp = await match_term.match.get() + resp.mask + resp.value Position ----------- +The position within each received packet where content matching begins for the port. + +Corresponding CLI command: ``PM_POSITION`` .. code-block:: python - await match_term.position.set() - await match_term.position.get() + await match_term.position.set(byte_offset=0) + + resp = await match_term.position.get() + resp.byte_offset Protocol Segments ----------------- +The protocol segments assumed on the packets received on the port. This is +mainly for information purposes, and helps you identify which portion of the +packet header is being matched. The actual value definition of the match +position is specified with PM_POSITION. + +Corresponding CLI command: ``PM_PROTOCOL`` .. code-block:: python - await match_term.protocol.set() - await match_term.protocol.get() + await match_term.protocol.set(segments=[enums.ProtocolOption.VLAN]) + + resp = await match_term.protocol.get() + resp.segments diff --git a/docs/source/api_ref/hlapiv1/port/matchterm/create.rst b/docs/source/api_ref/hlapiv1/port/matchterm/create.rst index 7a15098c..0f365345 100644 --- a/docs/source/api_ref/hlapiv1/port/matchterm/create.rst +++ b/docs/source/api_ref/hlapiv1/port/matchterm/create.rst @@ -6,6 +6,8 @@ Create and Obtain Create a match term on the port, and obtain the match term object. The match term index is automatically assigned by the port. +Corresponding CLI command: ``PM_CREATE`` + .. code-block:: python match_term = await port.match_terms.create() @@ -18,7 +20,7 @@ Obtain an existing match term on the port with an explicit match term index. .. code-block:: python - match_term = port.match_terms.obtain(idx) + match_term = port.match_terms.obtain(key=0) Obtain Multiple @@ -26,22 +28,21 @@ Obtain Multiple Obtain multiple existing match terms on the port with explicit match term indices. + .. code-block:: python - match_term_list = port.match_terms.obtain_multiple(*idx_list) + match_term_list = port.match_terms.obtain_multiple(*[0,1,2]) Remove --------------- -Remove a match term on the port with an explicit match term index by the index manager of the port. - -.. code-block:: python - - await port.match_terms.remove(idx) +Deletes the match term definition with the specified sub-index value. A match +term cannot be deleted while it is used in the condition of any filter for the +port. -Remove a match term by deleting the object. +Corresponding CLI command: ``PM_DELETE`` .. code-block:: python - await match_term.delete() \ No newline at end of file + await port.match_terms.remove(position_idx=0) diff --git a/docs/source/api_ref/hlapiv1/port/multicast.rst b/docs/source/api_ref/hlapiv1/port/multicast.rst index 98fa8450..716300a4 100644 --- a/docs/source/api_ref/hlapiv1/port/multicast.rst +++ b/docs/source/api_ref/hlapiv1/port/multicast.rst @@ -3,39 +3,142 @@ Multicast Mode ----------- +A multicast mode for a port. Ports can use the IGMPv2 protocol to join or leave multicast groups, either on an on-off basis or repeatedly. + +Corresponding CLI command: ``P_MULTICAST`` .. code-block:: python - await port.multicast.mode.set_join() - await port.multicast.mode.set_leave() - await port.multicast.mode.set_off() - await port.multicast.mode.set_on() - await port.multicast.mode.get() + # Multicast Mode + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.JOIN, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.JOIN, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.LEAVE, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.OFF, + second_count=10) + await port.multicast.mode.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastOperation.ON, + second_count=10) + + resp = await port.multicast.mode.get() + resp.ipv4_multicast_addresses + resp.operation + resp.second_count Extended Mode -------------- +A multicast mode for a port. Ports can use the IGMPv2/IGMPv3 protocol to join or leave multicast groups, either on an on-off basis or repeatedly. + +Corresponding CLI command: ``P_MULTICASTEXT`` .. code-block:: python - await port.multicast.mode_extended.set() - await port.multicast.mode_extended.get() + # Multicast Extended Mode + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.EXCLUDE, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV3 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.INCLUDE, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV3 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.JOIN, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.LEAVE, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.LEAVE_TO_ALL, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.GENERAL_QUERY, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.GROUP_QUERY, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.ON, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + await port.multicast.mode_extended.set( + ipv4_multicast_addresses=[], + operation=enums.MulticastExtOperation.OFF, + second_count=10, + igmp_version=enums.IGMPVersion.IGMPV2 + ) + + resp = await port.multicast.mode_extended.get() + resp.ipv4_multicast_addresses + resp.operation + resp.second_count + resp.igmp_version Source List ----------- +Multicast source list of the port. Only valid if the IGMP protocol version is IGMPv3 set by P_MULTICASTEXT. + +Corresponding CLI command: ``P_MCSRCLIST`` .. code-block:: python - await port.multicast.source_list.set() - await port.multicast.source_list.get() + # Multicast Source List + await port.multicast.source_list.set(ipv4_addresses=[]) + + resp = await port.multicast.source_list.get() + resp.ipv4_addresses Header ----------- +Allows addition of a VLAN tag to IGMPv2 and IGPMv3 packets. + +Corresponding CLI command: ``P_MULTICASTHDR`` .. code-block:: python - await port.multicast.header.set() - await port.multicast.header.get() + # Multicast Header + await port.multicast.header.set(header_count=1, header_format=enums.MulticastHeaderFormat.VLAN, tag=10, pcp=0, dei=0) + await port.multicast.header.set(header_count=0, header_format=enums.MulticastHeaderFormat.NOHDR, tag=10, pcp=0, dei=0) + + resp = await port.multicast.header.get() + resp.header_count + resp.header_format + resp.tag + resp.pcp + resp.dei diff --git a/docs/source/api_ref/hlapiv1/port/payload.rst b/docs/source/api_ref/hlapiv1/port/payload.rst index 9b535e99..9bdc8727 100644 --- a/docs/source/api_ref/hlapiv1/port/payload.rst +++ b/docs/source/api_ref/hlapiv1/port/payload.rst @@ -4,57 +4,136 @@ Payload Random Seed ----------- +A fixed seed value specified for a port. This value is used for a pseudo-random number generator used when generating traffic that requires random variation in packet length, payload, or modified fields. As long as no part of the port configuration is changed, the generated traffic patterns are reproducible when restarting traffic for the port. A specified seed value of -1 instead creates variation by using a new time-based seed value each time traffic generation is restarted. + +Corresponding CLI command: ``P_RANDOMSEED`` .. code-block:: python - await port.random_seed.set() - await port.random_seed.get() + # Random Seed + await port.random_seed.set(seed=1) + + resp = await port.random_seed.get() + resp.seed Checksum Offset ------------------ +Controls an extra payload integrity checksum, which also covers the header +protocols following the Ethernet header. It will therefore catch any +modifications to the protocol fields (which should therefore not have modifiers on them). + +Corresponding CLI command: ``P_CHECKSUM`` .. code-block:: python - await port.checksum.set() - await port.checksum.get() - await port.checksum.set_on() - await port.checksum.set_off() + # Checksum Offset + await port.checksum.set(offset=14) + + resp = await port.checksum.get() + resp.offset Maximum Header Length --------------------- +The maximum number of header content bytes that can be freely specified for each generated stream. The remaining payload bytes of the packet are auto-generated.The default is 128 bytes. When a larger number is select there is a corresponding proportional reduction in the number of stream definitions that are available for the port. Possible values: 128 (default), 256, 512, 1024, 2048. + +Corresponding CLI command: ``P_MAXHEADERLENGTH`` .. code-block:: python - await port.max_header_length.set() - await port.max_header_length.get() + # Maximum Header Length + await port.max_header_length.set(max_header_length=56) + resp = await port.max_header_length.get() + resp.max_header_length MIX Weights --------------------- +Allow changing the distribution of the MIX packet length by specifying the +percentage of each of the 16 possible frame sizes used in the MIX. The sum of the percentage values specified must be 100. The command will affect the mix-distribution for all streams on the port. The possible 16 frame sizes are: 56 (not valid for 40G/100G), 60, 64, 70, 78, 92, 256, 496, 512, 570, 576, 594, 1438, 1518, 9216, and 16360. + +Corresponding CLI command: ``P_MIXWEIGHTS`` .. code-block:: python - await port.mix.weights.set() - await port.mix.weights.get() + # MIX Weights + await port.mix.weights.set( + weight_56_bytes:=0, + weight_60_bytes:=0, + weight_64_bytes:=70, + weight_70_bytes:=15, + weight_78_bytes:=15, + weight_92_bytes:=0, + weight_256_bytes:=0, + weight_496_bytes:=0, + weight_512_bytes:=0, + weight_570_bytes:=0, + weight_576_bytes:=0, + weight_594_bytes:=0, + weight_1438_bytes:=0, + weight_1518_bytes:=0, + weight_9216_bytes:=0, + weight_16360_bytes:=0) + + resp = await port.mix.weights.get() + resp.weight_56_bytes + resp.weight_60_bytes + resp.weight_64_bytes + resp.weight_70_bytes + resp.weight_78_bytes + resp.weight_92_bytes + resp.weight_256_bytes + resp.weight_496_bytes + resp.weight_512_bytes + resp.weight_570_bytes + resp.weight_576_bytes + resp.weight_594_bytes + resp.weight_1438_bytes + resp.weight_1518_bytes + resp.weight_9216_bytes + resp.weight_16360_bytes MIX Lengths --------------------- +Allows inspecting the frame sizes defined for each position of the P_MIXWEIGHTS command. By default, the 16 frame sizes are: 56 (not valid for 40G/100G), 60, 64, 70, 78, 92, 256, 496, 512, 570, 576, 594, 1438, 1518, 9216, and 16360. In addition to inspecting these sizes one by one, it also allows changing frame size for positions 0, 1, 14 and 15 (default values 56, 60, 9216 and 16360). + +Corresponding CLI command: ``P_MIXLENGTH`` .. code-block:: python - await port.mix.lengths.set() - await port.mix.lengths.get() + # MIX Lengths + await port.mix.lengths[0].set(frame_size=56) + await port.mix.lengths[1].set(frame_size=60) + await port.mix.lengths[14].set(frame_size=9216) + await port.mix.lengths[15].set(frame_size=16360) + + resp = await port.mix.lengths[0].get() + resp.frame_size + resp = await port.mix.lengths[1].get() + resp.frame_size + resp = await port.mix.lengths[14].get() + resp.frame_size + resp = await port.mix.lengths[15].get() + resp.frame_size Payload Mode ------------- +Set this command to configure the port to use different payload modes, i.e. normal, extend payload, and custom payload field, for ALL streams on this port. The extended payload feature allows the definition of a much larger (up to MTU) payload buffer for each stream. The custom payload field feature allows you to define a sequence of custom data fields for each stream. The data fields will then be used in a round robin fashion when packets are sent based on the stream definition. + +Corresponding CLI command: ``P_PAYLOADMODE`` .. code-block:: python + # Payload Mode + await port.payload_mode.set(mode=enums.PayloadMode.NORMAL) await port.payload_mode.set_normal() + await port.payload_mode.set(mode=enums.PayloadMode.EXTPL) await port.payload_mode.set_extpl() + await port.payload_mode.set(mode=enums.PayloadMode.CDF) await port.payload_mode.set_cdf() - await port.payload_mode.get() \ No newline at end of file + + resp = await port.payload_mode.get() + resp.mode \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/aneg.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/aneg.rst index 6f8001db..ca6d333c 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/aneg.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/aneg.rst @@ -1,31 +1,59 @@ Auto-Negotiation ========================= -Settings --------- +Configuration +-------------- +Auto-negotiation configuration. + +Corresponding CLI command: ``PP_AUTONEG`` .. code-block:: python - await port.pcs_pma.auto_neg.settings.get() + # Auto-Negotiation Settings + resp = await port.pcs_pma.auto_neg.settings.get() + resp.tec_ability + resp.fec_capable + resp.fec_requested + resp.pause_mode Status -------- +Status of auto-negotiation. + +Corresponding CLI command: ``PP_AUTONEGSTATUS`` .. code-block:: python - await port.pcs_pma.auto_neg.status.get() + a# Auto-Negotiation Status + resp = await port.pcs_pma.auto_neg.status.get() + resp.mode + resp.auto_state + resp.tec_ability + resp.fec_capable + resp.fec_requested + resp.fec + resp.pause_mode Selection ---------- +Whether the port responds to incoming auto-negotiation requests. .. note:: Only applicable to RJ45 ports +Corresponding CLI command: ``P_AUTONEGSELECTION`` + .. code-block:: python + # Auto-Negotiation Selection + # Only applicable to RJ45 ports + await port.autoneg_selection.set(on_off=enums.OnOff.ON) await port.autoneg_selection.set_on() + await port.autoneg_selection.set(on_off=enums.OnOff.OFF) await port.autoneg_selection.set_off() - await port.autoneg_selection.get() + + resp = await port.autoneg_selection.get() + resp.on_off diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/fec.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/fec.rst index c206e9e2..01f3751a 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/fec.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/fec.rst @@ -3,9 +3,19 @@ Forward Error Correction FEC Mode -------- +FEC mode for port that supports FEC. + +Corresponding CLI command: ``PP_FECMODE`` .. code-block:: python - await port.pcs_pma.phy.auto_neg.set() - await port.fec_mode.set() - await port.fec_mode.get() + # FEC Mode + await port.fec_mode.set(mode=enums.FECMode.RS_FEC) + await port.fec_mode.set(mode=enums.FECMode.RS_FEC_KP) + await port.fec_mode.set(mode=enums.FECMode.RS_FEC_KR) + await port.fec_mode.set(mode=enums.FECMode.FC_FEC) + await port.fec_mode.set(mode=enums.FECMode.OFF) + await port.fec_mode.set(mode=enums.FECMode.ON) + + resp = await port.fec_mode.get() + resp.mode diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/linktrain.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/linktrain.rst index e91719b5..2d37211f 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/linktrain.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/linktrain.rst @@ -1,19 +1,59 @@ Link Training ========================= -Settings +Configuration ------------------------- +Link training settings -.. code-block:: python - - await port.pcs_pma.link_training.settings.set() - await port.pcs_pma.link_training.settings.get() +Corresponding CLI command: ``PP_LINKTRAIN`` +.. code-block:: python -Serdes Status + # Link Training Settings + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.DISABLED, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DEFAULT) + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.STANDALONE, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DEFAULT) + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.INTERACTIVE, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DISABLED) + await port.pcs_pma.link_training.settings.set( + mode=enums.LinkTrainingMode.START_AFTER_AUTONEG, + pam4_frame_size=enums.PAM4FrameSize.P4K_FRAME, + nrz_pam4_init_cond=enums.LinkTrainingInitCondition.NO_INIT, + nrz_preset=enums.NRZPreset.NRZ_WITH_PRESET, + timeout_mode=enums.TimeoutMode.DEFAULT) + + resp = await port.pcs_pma.link_training.settings.get() + resp.mode + resp.pam4_frame_size + resp.nrz_pam4_init_cond + resp.nrz_preset + resp.timeout_mode + + +Per Serdes Status ------------------------- +Per lane Link training status + +Corresponding CLI command: ``PP_LINKTRAINSTATUS`` .. code-block:: python - await port.pcs_pma.link_training.per_lane_status[serdes_idx].get() + # Link Training Serdes Status + resp = await port.pcs_pma.link_training.per_lane_status[0].get() # serdes lane 0 + resp.mode + resp.failure + resp.status diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/pulse_error_inject.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/pulse_error_inject.rst index 1443276b..de068415 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/pulse_error_inject.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/pulse_error_inject.rst @@ -3,18 +3,39 @@ PMA Pulse Error Inject Control -------- +Enable / disable 'PMA pulse error inject'. + +Corresponding CLI command: ``PP_PMAERRPUL_ENABLE`` .. code-block:: python + # PMA Pulse Error Inject Control + await port.pcs_pma.pma_pulse_err_inj.enable.set(on_off=enums.OnOff.ON) await port.pcs_pma.pma_pulse_err_inj.enable.set_on() + await port.pcs_pma.pma_pulse_err_inj.enable.set(on_off=enums.OnOff.OFF) await port.pcs_pma.pma_pulse_err_inj.enable.set_off() - await port.pcs_pma.pma_pulse_err_inj.enable.get() + + resp = await port.pcs_pma.pma_pulse_err_inj.enable.get() + resp.on_off Configuration -------------- +The 'PMA pulse error inject'. + +.. note:: + + Period must be > duration. BER will be: coeff * 10exp + +Corresponding CLI command: ``PP_PMAERRPUL_PARAMS`` .. code-block:: python - await port.pcs_pma.pma_pulse_err_inj.params.set() - await port.pcs_pma.pma_pulse_err_inj.params.get() \ No newline at end of file + # PMA Pulse Error Inject Configuration + await port.pcs_pma.pma_pulse_err_inj.params.set(duration=1000, period=1000, repetition=10, coeff=5, exp=-5) + + resp = await port.pcs_pma.pma_pulse_err_inj.params.get() + resp.duration + resp.period + resp.coeff + resp.exp \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst index 37ac8af4..cdd8d695 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/rx_status.rst @@ -3,47 +3,92 @@ RX Status Lane Error Counters ------------------- +Statistics about errors detected at the physical coding sub-layer on the data +received on a specified physical lane. + +Corresponding CLI command: ``PP_RXLANEERRORS`` .. code-block:: python - await port.pcs_pma.lanes[lane_idx].rx_status.errors.get() + # RX Status - Lane Error Counters + resp = await port.pcs_pma.lanes[0].rx_status.errors.get() + resp.alignment_error_count + resp.corrected_fec_error_count + resp.header_error_count Lock Status ---------------- +Whether the receiver has achieved header lock and alignment lock on the data +received on a specified physical lane. + +Corresponding CLI command: ``PP_RXLANELOCK`` .. code-block:: python - await port.pcs_pma.lanes[lane_idx].rx_status.lock.get() + # RX Status - Lock Status + resp = await port.pcs_pma.lanes[0].rx_status.lock.get() + resp.align_lock + resp.header_lock Lane Status ---------------- +The virtual lane index and actual skew for data received on a specified physical +lane. This is only meaningful when the lane is in header lock and alignment +lock. + +Corresponding CLI command: ``PP_RXLANESTATUS`` .. code-block:: python - await port.pcs_pma.lanes[lane_idx].rx_status.status.get() + # RX Status - Lane Status + resp = await port.pcs_pma.lanes[0].rx_status.status.get() + resp.skew + resp.virtual_lane Clear Counters --------------- +Clear all the PCS/PMA receiver statistics for a port. + +Corresponding CLI command: ``PP_RXCLEAR`` .. code-block:: python + # RX Status - Clear Counters await port.pcs_pma.rx.clear.set() RX FEC Stats --------------- +Provides statistics on how many FEC blocks have been seen with a given number of symbol errors. + +Corresponding CLI command: ``PP_RXFECSTATS`` .. code-block:: python - await port.pcs_pma.rx.fec_status.get() + # RX Status - RX FEC Stats + resp = await port.pcs_pma.rx.fec_status.get() + resp.stats_type + resp.data_count # number of values in stats + resp.stats # list of long integers, array of length value_count. The stats array shows how many FEC blocks have been seen with [0, 1, 2, 3....15, >15] symbol errors and the last one is the sum of FEC blocks with <=n symbol errors RX Total Stats --------------- +Provides FEC Total counters. + +Corresponding CLI command: ``PP_RXTOTALSTATS`` .. code-block:: python - await port.pcs_pma.rx.total_status.get() \ No newline at end of file + # RX Status - RX Total Stats + resp = await port.pcs_pma.rx.total_status.get() + resp.total_corrected_codeword_count + resp.total_corrected_symbol_count + resp.total_rx_bit_count + resp.total_rx_codeword_count + resp.total_uncorrectable_codeword_count + post_fec_ber = 1/resp.total_post_fec_ber + pre_fec_ber = 1/resp.total_pre_fec_ber \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/pcs_pma/tx_config.rst b/docs/source/api_ref/hlapiv1/port/pcs_pma/tx_config.rst index c3540360..14b1d572 100644 --- a/docs/source/api_ref/hlapiv1/port/pcs_pma/tx_config.rst +++ b/docs/source/api_ref/hlapiv1/port/pcs_pma/tx_config.rst @@ -3,42 +3,78 @@ TX Configuration Error Counters --------------------- +Obtain the error count of each alarm, PCS Error, FEC Error, Header Error, Align +Error, BIP Error, and High BER Error. + +Corresponding CLI command: ``PP_ALARMS_ERRORS`` .. code-block:: python - await port.pcs_pma.alarms.errors.get() + # TX Configuration - Error Counters + resp = await port.pcs_pma.alarms.errors.get() + resp.total_alarms + resp.los_error_count + resp.total_align_error_count + resp.total_bip_error_count + resp.total_fec_error_count + resp.total_header_error_count + resp.total_higher_error_count + resp.total_pcs_error_count + resp.valid_mask Error Generation Rate --------------------- +The rate of continuous bit-level error injection. Errors are injected evenly +across the SerDes where injection is enabled. + +Corresponding CLI command: ``PP_TXERRORRATE`` .. code-block:: python - await port.pcs_pma.error_gen.error_rate.get() + # TX Configuration - Error Generation Rate + resp = await port.pcs_pma.error_gen.error_rate.get() + resp.rate Error Generation Inject ----------------------- +Inject a single bit-level error into the SerDes where injection has been enabled. + +Corresponding CLI command: ``PP_TXINJECTONE`` .. code-block:: python + # TX Configuration - Error Generation Inject await port.pcs_pma.error_gen.inject_one.set() Error Injection --------------------- +Inject a particular kind of CAUI error into a specific physical lane. + +Corresponding CLI command: ``PP_TXLANEINJECT`` .. code-block:: python - await port.pcs_pma.lanes[lane_idx].tx_error_inject.set_alignerror() - await port.pcs_pma.lanes[lane_idx].tx_error_inject.set_bip8error() - await port.pcs_pma.lanes[lane_idx].tx_error_inject.set_headererror() + # TX Configuration - Error Injection + await port.pcs_pma.lanes[0].tx_error_inject.set_alignerror() + await port.pcs_pma.lanes[0].tx_error_inject.set_bip8error() + await port.pcs_pma.lanes[0].tx_error_inject.set_headererror() Lane Configuration --------------------- +The virtual lane index and artificial skew for data transmitted on a specified +physical lane. + +Corresponding CLI command: ``PP_TXLANECONFIG`` .. code-block:: python - await port.pcs_pma.lanes[lane_idx].tx_config.set() - await port.pcs_pma.lanes[lane_idx].tx_config.get() + # TX Configuration - Lane Configuration + await port.pcs_pma.lanes[0].tx_config.set(virt_lane_index=1, skew=10) + + resp = await port.pcs_pma.lanes[0].tx_config.get() + resp.virt_lane_index + resp.skew diff --git a/docs/source/api_ref/hlapiv1/port/phy/eyediagram.rst b/docs/source/api_ref/hlapiv1/port/phy/eyediagram.rst index 855bce0b..8f2fa275 100644 --- a/docs/source/api_ref/hlapiv1/port/phy/eyediagram.rst +++ b/docs/source/api_ref/hlapiv1/port/phy/eyediagram.rst @@ -3,47 +3,109 @@ Eye Diagram Information ----------------- +Read out BER eye-measurement information such as the vertical and horizontal +bathtub curve information on a 25G serdes. This must be called after "PP_EYEMEASURE" +has run to return valid results. Use "get" to see the status of the data +gathering process. + +Corresponding CLI command: ``PP_EYEINFO`` .. code-block:: python - await port.serdes[serdex_idx].eye_diagram.info.get() + # Eye Diagram Information + resp = await port.serdes[0].eye_diagram.info.get() + resp.width_mui + resp.height_mv + resp.h_slope_left + resp.h_slope_right + resp.y_intercept_left + resp.y_intercept_right + resp.r_squared_fit_left + resp.r_squared_fit_right + resp.est_rj_rms_left + resp.est_rj_rms_right + resp.est_dj_pp + resp.v_slope_bottom + resp.v_slope_top + resp.x_intercept_bottom + resp.x_intercept_top + resp.r_squared_fit_bottom + resp.r_squared_fit_top + resp.est_rj_rms_bottom + resp.est_rj_rms_top Bit Error Rate ----------------- +Obtain BER estimations of an eye diagram. + +Corresponding CLI command: ``PP_EYEBER`` .. code-block:: python - await port.serdes[serdex_idx].eye_diagram.ber.get() + # Eye Diagram Bit Error Rate + resp = await port.serdes[0].eye_diagram.ber.get() + resp.eye_ber_estimation Dwell Bits ----------------- +Min and max dwell bits for an eye capture. + +Corresponding CLI command: ``PP_EYEDWELLBITS`` .. code-block:: python - await port.serdes[serdex_idx].eye_diagram.dwell_bits.get() + # Eye Diagram Dwell Bits + resp = await port.serdes[0].eye_diagram.dwell_bits.get() + resp.max_dwell_bit_count + resp.min_dwell_bit_count Measure ----------------- +Start/stop a new BER eye-measure on a 25G serdes. Use "get" to see the status of +the data gathering process. + +Corresponding CLI command: ``PP_EYEMEASURE`` .. code-block:: python - await port.serdes[serdex_idx].eye_diagram.measure.get() + # Eye Diagram Measure + resp = await port.serdes[0].eye_diagram.measure.get() + resp.status Resolution ----------------- +Set or get the resolution used for the next BER eye-measurement. + +Corresponding CLI command: ``PP_EYERESOLUTION`` .. code-block:: python - await port.serdes[serdex_idx].eye_diagram.resolution.get() + # Eye Diagram Resolution + resp = await port.serdes[0].eye_diagram.resolution.get() + resp.x_resolution + resp.y_resolution Data Columns ----------------- +Read a single column of a measured BER eye on a 25G serdes. Every readout also +returns the resolution (x,y) and the number of valid columns (used to facilitate +reading out the eye while it is being measured). + +.. note:: + The columns of the eye-data will be measured in the order: xres-1, xres-2, xres-3, ... 0. The values show the number of bit errors measured out of a total of 1M bits at each of the individual sampling points (x=timeaxis, y = 0/1 threshold). + +Corresponding CLI command: ``PP_EYEREAD`` .. code-block:: python - await port.serdes[serdex_idx].eye_diagram.read_column \ No newline at end of file + # Eye Diagram Data Columns + resp = await port.serdes[0].eye_diagram.read_column[0].get() + resp.valid_column_count + resp.values + resp.x_resolution + resp.y_resolution \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/phy/settings.rst b/docs/source/api_ref/hlapiv1/port/phy/settings.rst index a2b35660..ad198948 100644 --- a/docs/source/api_ref/hlapiv1/port/phy/settings.rst +++ b/docs/source/api_ref/hlapiv1/port/phy/settings.rst @@ -3,17 +3,34 @@ Settings and Status Signal Status ------------------------- +Obtain the PHY signal status. + +Corresponding CLI command: ``PP_PHYSIGNALSTATUS`` .. code-block:: python - await port.pcs_pma.phy.signal_status.get() + # PHY - Signal Status + resp = await port.pcs_pma.phy.signal_status.get() + resp.phy_signal_status Settings ------------------------- +Get/Set low-level PHY settings. + +Corresponding CLI command: ``PP_PHYSETTINGS`` .. code-block:: python - await port.pcs_pma.phy.settings.set() - await port.pcs_pma.phy.settings.get() + # PHY - Settings + await port.pcs_pma.phy.settings.set( + link_training_on_off=enums.OnOff.ON, + precode_on_off=enums.OnOffDefault.DEFAULT, + graycode_on_off=enums.OnOff.OFF, pam4_msb_lsb_swap=enums.OnOff.OFF) + + resp = await port.pcs_pma.phy.settings.get() + resp.link_training_on_off + resp.precode_on_off + resp.graycode_on_off + resp.pam4_msb_lsb_swap diff --git a/docs/source/api_ref/hlapiv1/port/phy/tap.rst b/docs/source/api_ref/hlapiv1/port/phy/tap.rst index 86d9556a..6bb3fd47 100644 --- a/docs/source/api_ref/hlapiv1/port/phy/tap.rst +++ b/docs/source/api_ref/hlapiv1/port/phy/tap.rst @@ -4,35 +4,75 @@ Tap Configuration TX Tap Autotune ------------------------- +Enable or disable the automatic receiving of PHY retuning (see PP_PHYRETUNE), which +is performed on the 25G interfaces as soon as a signal is detected by the +transceiver. Useful if a bad signal causes the PHY to continuously retune or if +for some other reason it is preferable to use manual retuning (PP_PHYRETUNE). + +Corresponding CLI command: ``PP_PHYAUTOTUNE`` .. code-block:: python - await port.serdes[serdex_idx].phy.autotune.set_on() - await port.serdes[serdex_idx].phy.autotune.set_off() - await port.serdes[serdex_idx].phy.autotune.get() + # TX Tap Autotune + await port.serdes[0].phy.autotune.set(on_off=enums.OnOff.ON) + await port.serdes[0].phy.autotune.set_on() + await port.serdes[0].phy.autotune.set(on_off=enums.OnOff.OFF) + await port.serdes[0].phy.autotune.set_off() + + resp = await port.serdes[0].phy.autotune.get() + resp.on_off TX Tap Retune ------------------------- +Trigger a new retuning of the receive equalizer on the PHY for one of the 25G +serdes. Useful if e.g. a direct attached copper cable or loop transceiver does +not go into sync after insertion. Note that the retuning will cause disruption +of the traffic on all serdes. + +Corresponding CLI command: ``PP_PHYRETUNE`` .. code-block:: python - await port.serdes[serdex_idx].phy.retune.set() + # TX Tap Retune + await port.serdes[0].phy.retune.set(dummy=1) TX Tap Configuration ------------------------- +Control and monitor the equalizer settings of the on-board PHY in the +transmission direction (towards the transceiver cage) on Thor and Loki modules. + +Corresponding CLI command: ``PP_PHYTXEQ`` .. code-block:: python - await port.serdes[serdex_idx].phy.tx_equalizer.set() - await port.serdes[serdex_idx].phy.tx_equalizer.get() + # TX Tap Configuration + await port.serdes[0].phy.tx_equalizer.set(pre2=0, pre1=0, main=86, post1=0, post2=0, post3=0) + resp = await port.serdes[0].phy.tx_equalizer.get() + resp.pre2 + resp.pre + resp.main + resp.post + resp.pre3_post2 # pre3 for Freya (112G Serdes), post2 for Thor (56G Serdes) + resp.post3 RX Tap Configuration ------------------------- +RX EQ parameters. + +.. note:: + + For non-Freya Modules. + +Corresponding CLI command: ``PP_PHYRXEQ`` .. code-block:: python - await port.serdes[serdex_idx].phy.rx_equalizer.set() - await port.serdes[serdex_idx].phy.rx_equalizer.get() + # RX Tap Configuration + await port.serdes[0].phy.rx_equalizer.set(auto=0, ctle=0, reserved=0) + + resp = await port.serdes[0].phy.rx_equalizer.get() + resp.auto + resp.ctle diff --git a/docs/source/api_ref/hlapiv1/port/prbs/config.rst b/docs/source/api_ref/hlapiv1/port/prbs/config.rst index 6afe18a5..2c14aa86 100644 --- a/docs/source/api_ref/hlapiv1/port/prbs/config.rst +++ b/docs/source/api_ref/hlapiv1/port/prbs/config.rst @@ -1,26 +1,73 @@ Configuration ========================= -RX Type +Type ------------------------- +Defines the PRBS type used when the interface is in PRBS mode. -.. code-block:: python - - await port.serdes[serdex_idx].prbs.config.rx_type.set() - await port.serdes[serdex_idx].prbs.config.rx_type.get() - -TX Type -------------------------- +Corresponding CLI command: ``PP_PRBSTYPE`` .. code-block:: python - await port.serdes[serdex_idx].prbs.config.tx_type.set() - await port.serdes[serdex_idx].prbs.config.tx_type.get() - -Type -------------------------- - -.. code-block:: python + # PRBS Configuration + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS7, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.CAUI_VIRTUAL, + polynomial=enums.PRBSPolynomial.PRBS9, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.PERSECOND) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS10, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS11, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS13, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS15, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS20, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS23, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS31, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS49, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) + await port.serdes[0].prbs.config.type.set( + prbs_inserted_type=enums.PRBSInsertedType.PHY_LINE, + polynomial=enums.PRBSPolynomial.PRBS58, + invert=enums.PRBSInvertState.NON_INVERTED, + statistics_mode=enums.PRBSStatisticsMode.ACCUMULATIVE) - await port.serdes[serdex_idx].prbs.config.type.set() - await port.serdes[serdex_idx].prbs.config.type.get() + resp = await port.serdes[0].prbs.config.type.get() + resp.prbs_inserted_type + resp.polynomial + resp.invert + resp.statistics_mode diff --git a/docs/source/api_ref/hlapiv1/port/prbs/stats.rst b/docs/source/api_ref/hlapiv1/port/prbs/stats.rst index 4039c6ce..5425d70b 100644 --- a/docs/source/api_ref/hlapiv1/port/prbs/stats.rst +++ b/docs/source/api_ref/hlapiv1/port/prbs/stats.rst @@ -1,6 +1,14 @@ Statistics ========================= +Statistics about PRBS pattern detection on the data received on a specified +SerDes. + +Corresponding CLI command: ``PP_RXPRBSSTATUS`` .. code-block:: python - await port.serdes[serdex_idx].prbs.status.get() \ No newline at end of file + # PRBS Statistics + resp = await port.serdes[0].prbs.status.get() + resp.byte_count + resp.error_count + resp.lock \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/preamble.rst b/docs/source/api_ref/hlapiv1/port/preamble.rst index a4593498..df0b098a 100644 --- a/docs/source/api_ref/hlapiv1/port/preamble.rst +++ b/docs/source/api_ref/hlapiv1/port/preamble.rst @@ -4,17 +4,31 @@ Preamble RX Preamble Insert ------------------ +Insert preambles to the incoming frames. + +Corresponding CLI command: ``P_RXPREAMBLE_INSERT`` .. code-block:: python - await port.preamble.rx_insert.set() - await port.preamble.rx_insert.get() + # RX Preamble Insert + await port.preamble.rx_insert.set(on_off=enums.OnOff.ON) + await port.preamble.rx_insert.set(on_off=enums.OnOff.OFF) + + resp = await port.preamble.rx_insert.get() + resp.on_off TX Preamble Removal ------------------- +Remove preamble from outgoing frames. + +Corresponding CLI command: ``P_TXPREAMBLE_REMOVE`` .. code-block:: python - await port.preamble.tx_remove.set() - await port.preamble.tx_remove.get() \ No newline at end of file + # TX Preamble Removal + await port.preamble.tx_remove.set(on_off=enums.OnOff.ON) + await port.preamble.tx_remove.set(on_off=enums.OnOff.OFF) + + resp = await port.preamble.tx_remove.get() + resp.on_off \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/reservation.rst b/docs/source/api_ref/hlapiv1/port/reservation.rst index ba9525ea..0b559422 100644 --- a/docs/source/api_ref/hlapiv1/port/reservation.rst +++ b/docs/source/api_ref/hlapiv1/port/reservation.rst @@ -3,23 +3,32 @@ Reservation Action ----------- +You set this command to reserve, release, or relinquish a port. The port must be reserved before any of its configuration can be changed, including streams, filters, capture, and datasets.The owner of the session must already have been specified. Reservation will fail if the chassis or module is reserved to other users. + +Corresponding CLI command: ``P_RESERVATION`` .. code-block:: python + # Reservation + await port.reservation.set(operation=enums.ReservedAction.RELEASE) await port.reservation.set_release() + await port.reservation.set(operation=enums.ReservedAction.RELINQUISH) await port.reservation.set_relinquish() + await port.reservation.set(operation=enums.ReservedAction.RESERVE) await port.reservation.set_reserve() - await port.reservation.get() - port.is_released() - port.on_reservation_change(_callback_func()) + + resp = await port.reservation.get() + resp.status Reserved By ----------- +Identify the user who has a port reserved. The empty string if the port is not currently reserved. Note that multiple connections can specify the same name with C_OWNER, but a resource can only be reserved to one connection. Therefore you cannot count on having the port just because it is reserved in your name. The port is reserved to this connection only if P_RESERVATION returns RESERVED_BY_YOU. + +Corresponding CLI command: ``P_RESERVEDBY`` .. code-block:: python - await port.reserved_by.get() - port.is_reserved_by_me() - port.is_reserved_by_others() - port.on_reserved_by_change(_callback_func()) + # Reserved By + resp = await port.reserved_by.get() + resp.username diff --git a/docs/source/api_ref/hlapiv1/port/runt.rst b/docs/source/api_ref/hlapiv1/port/runt.rst index d229b6f6..78f08b87 100644 --- a/docs/source/api_ref/hlapiv1/port/runt.rst +++ b/docs/source/api_ref/hlapiv1/port/runt.rst @@ -3,25 +3,42 @@ Runt RX Length --------------- +Enable RX runt length detection to flag if packets are seen with length not being I bytes. + +Corresponding CLI command: ``P_RXRUNTLENGTH`` .. code-block:: python - await port.runt.rx_length.set() - await port.runt.rx_length.get() + # Runt - RX Length + await port.runt.rx_length.set(runt_length=40) + + resp = await port.runt.rx_length.get() + resp.runt_length TX Length --------------- +Enable TX runt feature to cut all packets to a number of bytes. + +Corresponding CLI command: ``P_TXRUNTLENGTH`` .. code-block:: python - await port.runt.tx_length.set() - await port.runt.tx_length.get() + # Runt - TX Length + await port.runt.tx_length.set(runt_length=40) + + resp = await port.runt.tx_length.get() + resp.runt_length Length Error --------------------- +Sticky clear on read: Have packets with wrong runt length been detected since last read? + +Corresponding CLI command: ``P_RXRUNTLEN_ERRS`` .. code-block:: python - await port.runt.has_length_errors.get() \ No newline at end of file + # Runt - Length Error + resp = await port.runt.has_length_errors.get() + resp.status \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/speed.rst b/docs/source/api_ref/hlapiv1/port/speed.rst index e2977da1..43a51d51 100644 --- a/docs/source/api_ref/hlapiv1/port/speed.rst +++ b/docs/source/api_ref/hlapiv1/port/speed.rst @@ -3,51 +3,120 @@ Speed Mode Selection ---------------- +The speed mode of an autoneg port with an interface type supporting multiple speeds. + +.. note:: + + This is only a settable command when speed is selected at the port level. Use the M_CFPCONFIGEXT` command when speed is selected at the module level. + +Corresponding CLI command: ``P_SPEEDSELECTION`` .. code-block:: python + # Speed Mode Selection + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.AUTO) await port.speed.mode.selection.set_auto() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10M) await port.speed.mode.selection.set_f10m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10M100M) await port.speed.mode.selection.set_f10m100m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10MHDX) await port.speed.mode.selection.set_f10mhdx() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M) await port.speed.mode.selection.set_f100m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M1G) await port.speed.mode.selection.set_f100m1g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M1G10G) await port.speed.mode.selection.set_f100m1g10g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100M1G2500M) await port.speed.mode.selection.set_f100m1g2500m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100MHDX) await port.speed.mode.selection.set_f100mhdx() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F1G) await port.speed.mode.selection.set_f1g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F2500M) await port.speed.mode.selection.set_f2500m() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F5G) await port.speed.mode.selection.set_f5g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F10G) await port.speed.mode.selection.set_f10g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F40G) await port.speed.mode.selection.set_f40g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F100G) await port.speed.mode.selection.set_f100g() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.UNKNOWN) await port.speed.mode.selection.set_unknown() - await port.speed.mode.selection.get() + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F200G) + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F400G) + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F800G) + await port.speed.mode.selection.set(mode=enums.PortSpeedMode.F1600G) - port.on_speed_change(_callback_func) - port.on_speed_selection_change(_callback_func) + resp = await port.speed.mode.selection.get() + resp.mode Supported Modes ---------------- +Read the speeds supported by the port. The speeds supported by a port depends on +the transceiver inserted into the port. A series of 0/1 values, identifying +which speeds are supported by the port. + +.. note:: + + Ports can support zero (in case of e.g. empty cage), one, or multiple speeds. + +Corresponding CLI command: ``P_SPEEDS_SUPPORTED`` .. code-block:: python - await port.speed.mode.supported.get() + # Supported Speed Modes + resp = await port.speed.mode.supported.get() + resp.auto + resp.f10M + resp.f100M + resp.f1G + resp.f10G + resp.f40G + resp.f100G + resp.f10MHDX + resp.f100MHDX + resp.f10M100M + resp.f100M1G + resp.f100M1G10G + resp.f2500M + resp.f5G + resp.f100M1G2500M + resp.f25G + resp.f50G + resp.f200G + resp.f400G + resp.f800G + resp.f1600G Current Speed ---------------- +Obtains the current physical speed of a port's interface. + +Corresponding CLI command: ``P_SPEED`` .. code-block:: python - await port.speed.current.get() + # Current Speed + resp = await port.speed.current.get() + resp.port_speed Speed Reduction ---------------- +A speed reduction applied to the transmitting side of a port, resulting in an effective traffic rate that is slightly lower than the rate of the physical interface. Speed reduction is effectuated by inserting short idle periods in the generated traffic pattern to consume part of the port's physical bandwidth. The port's clock speed is not altered. + +Corresponding CLI command: ``P_SPEEDREDUCTION`` .. code-block:: python - await port.speed.reduction.set() - await port.speed.reduction.get() \ No newline at end of file + # Speed Reduction + await port.speed.reduction.set(ppm=100) + + resp = await port.speed.reduction.get() + resp.ppm \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/statistics/error.rst b/docs/source/api_ref/hlapiv1/port/statistics/error.rst index d297eaa2..94732de7 100644 --- a/docs/source/api_ref/hlapiv1/port/statistics/error.rst +++ b/docs/source/api_ref/hlapiv1/port/statistics/error.rst @@ -1,7 +1,17 @@ Error Counter ========================= +Obtains the total number of errors detected across all streams on the port, +including lost packets, misorder events, and payload errors. + +.. note:: + + FCS errors are included, which will typically lead to double-counting of lost packets. + +Corresponding CLI command: ``P_ERRORS`` .. code-block:: python - await port.errors_count.get() + # Error Counter + resp = await port.errors_count.get() + resp.error_count diff --git a/docs/source/api_ref/hlapiv1/port/statistics/rx.rst b/docs/source/api_ref/hlapiv1/port/statistics/rx.rst index 7257d532..394723b5 100644 --- a/docs/source/api_ref/hlapiv1/port/statistics/rx.rst +++ b/docs/source/api_ref/hlapiv1/port/statistics/rx.rst @@ -3,112 +3,239 @@ RX Statistics Clear Counter ------------- +Clear all the receive statistics for a port. The byte and packet counts will +restart at zero. + +Corresponding CLI command: ``PR_CLEAR`` .. code-block:: python + # RX Statistics - Clear Counter await port.statistics.rx.clear.set() Calibrate ------------- +Calibrate the latency calculation for packets received on a port. The lowest +detected latency value (across all Test Payload IDs) will be set as the new +base. + +Corresponding CLI command: ``PR_CALIBRATE`` .. code-block:: python + # RX Statistics - Calibrate await port.statistics.rx.calibrate.set() Total Counter ------------- +Obtains statistics concerning all the packets received on a port. + +Corresponding CLI command: ``PR_TOTAL`` .. code-block:: python - await port.statistics.rx.total.get() + # RX Statistics - Total Counter + resp = await port.statistics.rx.total.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec Non-TPLD Counter ----------------- +Obtains statistics concerning the packets without a test payload received on a +port. + +Corresponding CLI command: ``PR_NOTPLD`` .. code-block:: python - await port.statistics.rx.no_tpld.get() + # RX Statistics - Non-TPLD Counter + resp = await port.statistics.rx.no_tpld.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec PFC Counter ------------- +Obtains statistics of received Priority Flow Control (PFC) packets on a port. -.. code-block:: python - - await port.statistics.rx.pfc_stats.get() - - -Extra Counter -------------- +Corresponding CLI command: ``PR_PFCSTATS`` .. code-block:: python - await port.statistics.rx.extra.get() - + # RX Statistics - PFC Counter + resp = await port.statistics.rx.pfc_stats.get() + resp.packet_count + resp.quanta_pri_0 + resp.quanta_pri_1 + resp.quanta_pri_2 + resp.quanta_pri_3 + resp.quanta_pri_4 + resp.quanta_pri_5 + resp.quanta_pri_6 + resp.quanta_pri_7 -UAT Status -------------- - -.. code-block:: python - - await port.statistics.rx.uat.status.get() -UAT Time +Extra Counter ------------- +Obtains statistics concerning special errors received on a port since received statistics were cleared. + +Corresponding CLI command: ``PR_EXTRA`` .. code-block:: python - await port.statistics.rx.uat.time.get() + # RX Statistics - Extra Counter + resp = await port.statistics.rx.extra.get() + resp.fcs_error_count + resp.pause_frame_count + resp.gap_count + resp.gap_duration + resp.pause_frame_count + resp.rx_arp_reply_count + resp.rx_arp_request_count + resp.rx_ping_reply_count + resp.rx_ping_request_count Received TPLDs --------------- +Obtain the set of test payload IDs observed among the received packets since +receive statistics were cleared. Traffic statistics for these test payload +streams will have non-zero byte and packet count. + +Corresponding CLI command: ``PR_TPLDS`` .. code-block:: python + # RX Statistics - Received TPLDs await port.statistics.rx.obtain_available_tplds() TPLD - Error Counter -------------------- +Obtains statistics concerning errors in the packets with a particular test +payload id received on a port. The error information is derived from analyzing +the various fields contained in the embedded test payloads of the received +packets, independent of which chassis and port may have originated the packets. +Note that packet-lost statistics involve both a transmitting port and a +receiving port, and in particular knowing which port originated the packets with +a particular test payload identifier. This information requires knowledge of the +global test environment, and is not supported at the port-level. + +Corresponding CLI command: ``PR_TPLDERRORS`` .. code-block:: python - await port.statistics.rx.access_tpld(tpld_id).errors.get() + # RX Statistics - TPLD - Error Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).errors.get() + resp.non_incre_payload_packet_count + resp.non_incre_seq_event_count + resp.swapped_seq_misorder_event_count TPLD - Latency Counter ----------------------- +Obtains statistics concerning the latency experienced by the packets with a +particular test payload id received on a port. The values are adjusted by the +port-level P_LATENCYOFFSET value. A special value of -1 is returned if latency +numbers are not applicable. Latency is only meaningful when the clocks of the +transmitter and receiver are synchronized. This requires the two ports to be on +the same test module, and it requires knowledge of the global test environment +to ensure that packets are in fact routed between these ports. + +Corresponding CLI command: ``PR_TPLDLATENCY`` .. code-block:: python - await port.statistics.rx.access_tpld(tpld_id=1).latency.get() + # RX Statistics - TPLD - Latency Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).latency.get() + resp.avg_last_sec + resp.max_last_sec + resp.min_last_sec + resp.avg_val + resp.max_val + resp.min_val TPLD - Jitter Counter ----------------------- +Obtains statistics concerning the jitter experienced by the packets with a +particular test payload id received on a port. The values are the difference in +packet-to-packet latency, and the minimum will usually be zero.A special value +of -1 is returned if jitter numbers are not applicable. They are only available +for TID values 0..31. -.. code-block:: python +Corresponding CLI command: ``PR_TPLDJITTER`` - await port.statistics.rx.access_tpld(tpld_id=1).jitter.get() +.. code-block:: python + # RX Statistics - TPLD - Jitter Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).jitter.get() + resp.avg_last_sec + resp.max_last_sec + resp.min_last_sec + resp.avg_val + resp.max_val + resp.min_val TPLD - Traffic Counter ----------------------- +Obtains traffic statistics concerning the packets with a particular test payload +identifier received on a port. + +Corresponding CLI command: ``PR_TPLDTRAFFIC`` .. code-block:: python - await port.statistics.rx.access_tpld(tpld_id=1).traffic.get() + # RX Statistics - TPLD - Traffic Counter + resp = await port.statistics.rx.access_tpld(tpld_id=0).traffic.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec Filter Statistics -------------------- +Obtains statistics concerning the packets satisfying the condition of a +particular filter for a port. + +Corresponding CLI command: ``PR_FILTER`` + +.. code-block:: python + + # RX Statistics - Filter Statistics + resp = await port.statistics.rx.obtain_filter_statistics(filter=0).get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec + +UAT Status +------------- +This command will show the current UAT (UnAvailable Time) state, which is used +in Valkyrie1564. + +Corresponding CLI command: ``PR_UAT_STATUS`` .. code-block:: python - await port.statistics.rx.obtain_filter_statistics(filter_id).get() + await port.statistics.rx.uat.status.get() + +UAT Time +------------- +This command will show the current number of unavailable seconds, which is used in Valkyrie1564. + +Corresponding CLI command: ``PR_UAT_TIME`` + +.. code-block:: python + + await port.statistics.rx.uat.time.get() diff --git a/docs/source/api_ref/hlapiv1/port/statistics/tx.rst b/docs/source/api_ref/hlapiv1/port/statistics/tx.rst index db20d614..d57fce7a 100644 --- a/docs/source/api_ref/hlapiv1/port/statistics/tx.rst +++ b/docs/source/api_ref/hlapiv1/port/statistics/tx.rst @@ -3,40 +3,76 @@ TX Statistics Clear Counter ------------- +Clear all the transmit statistics for a port. The byte and packet counts will +restart at zero. + +Corresponding CLI command: ``PT_CLEAR`` .. code-block:: python + # TX Statistics - Clear Counter await port.statistics.tx.clear.set() Total Counter -------------- +Obtains statistics concerning all the packets transmitted on a port. + +Corresponding CLI command: ``PT_TOTAL`` .. code-block:: python - await port.statistics.tx.total.get() + # TX Statistics - Total Counter + resp = await port.statistics.tx.total.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec Non-TPLD Counter ----------------- +Obtains statistics concerning the packets without a test payload transmitted on +a port. + +Corresponding CLI command: ``PT_NOTPLD`` .. code-block:: python - await port.statistics.tx.no_tpld.get() + # TX Statistics - Non-TPLD Counter + resp = await port.statistics.tx.no_tpld.get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec Extra Counter ------------- +Obtains additional statistics for packets transmitted on a port. + +Corresponding CLI command: ``PT_EXTRA`` .. code-block:: python - await port.statistics.tx.extra.get() + # TX Statistics - Extra Counter + resp = await port.statistics.tx.extra.get() + resp.tx_arp_req_count Stream Counter --------------- +Obtains statistics concerning the packets of a specific stream transmitted on a +port. + +Corresponding CLI command: ``PT_STREAM`` .. code-block:: python - await port.statistics.tx.obtain_from_stream(stream_id).get() + # TX Statistics - Stream Counter + resp = await port.statistics.tx.obtain_from_stream(stream=0).get() + resp.byte_count_since_cleared + resp.packet_count_since_cleared + resp.bit_count_last_sec + resp.packet_count_last_sec diff --git a/docs/source/api_ref/hlapiv1/port/status.rst b/docs/source/api_ref/hlapiv1/port/status.rst index 32dcbdf3..ac23b4c5 100644 --- a/docs/source/api_ref/hlapiv1/port/status.rst +++ b/docs/source/api_ref/hlapiv1/port/status.rst @@ -3,8 +3,13 @@ Status Sync Status ----------- +Obtains the current in-sync status of a port's receive interface. + +Corresponding CLI command: ``P_RECEIVESYNC`` .. code-block:: python - await port.sync_status.get() - port.on_receive_sync_change(_callback_func) + # Sync Status + resp = await port.sync_status.get() + resp.sync_status == enums.SyncStatus.IN_SYNC + resp.sync_status == enums.SyncStatus.NO_SYNC diff --git a/docs/source/api_ref/hlapiv1/port/tcvr.rst b/docs/source/api_ref/hlapiv1/port/tcvr.rst index 71997e37..d6acbf90 100644 --- a/docs/source/api_ref/hlapiv1/port/tcvr.rst +++ b/docs/source/api_ref/hlapiv1/port/tcvr.rst @@ -4,58 +4,107 @@ Transceiver Status ------------------ +Get various tcvr status information. RX loss status of the individual RX optical lanes (only 4 lanes are supported currently). + +Corresponding CLI command: ``P_TCVRSTATUS`` .. code-block:: python - await port.tcvr_status.get() + # Transceiver Status + resp = await port.tcvr_status.get() + resp.rx_loss_lane_0 + resp.rx_loss_lane_1 + resp.rx_loss_lane_2 + resp.rx_loss_lane_3 Read & Write ------------- +Provides read and write access to the register interface supported by the port transceiver. It is possible to both read and write register values. -.. code-block:: python +Corresponding CLI command: ``PX_RW`` - await port.transceiver.access_rw(page_address, register_address).set() - await port.transceiver.access_rw(page_address, register_address).get() +.. code-block:: python + # Transceiver Read & Write + await port.transceiver.access_rw(page_address=0, register_address=0).set(value=Hex("FF")) + + resp = await port.transceiver.access_rw(page_address=0, register_address=0).get() + resp.value Sequential Read & Write ----------------------- +I2C sequential access to a transceiver's register. +When invoked, the ```` number of bytes will be read or written in one I2C transaction, in which the ```` is read or written with only a single register address setup. A subsequent invocation will perform a second I2C transaction in the same manner. + +``<_page_xindex>``: the transceiver page address, integer, 0-255. +``<_register_xaddress>``: the address within the page, integer, 0-255. + +Corresponding CLI command: ``PX_RW_SEQ`` .. code-block:: python - await port.transceiver.access_rw_seq(page_address, register_address, byte_count).set() - await port.transceiver.access_rw_seq(page_address, register_address, byte_count).get() + # Transceiver Sequential Read & Write + await port.transceiver.access_rw_seq(page_address=0, register_address=0, byte_count=4).set(value=Hex("00FF00FF")) + + resp = await port.transceiver.access_rw_seq(page_address=0, register_address=0, byte_count=4).get() + resp.value MII ------------------ +Provides access to the register interface supported by the media-independent interface (MII) transceiver. It is possible to both read and write register values. + +Corresponding CLI command: ``PX_MII`` .. code-block:: python - await port.transceiver.access_mii(register_address).set() - await port.transceiver.access_mii(register_address).get() + # Transceiver MII + await port.transceiver.access_mii(register_address=0).set(value=Hex("00")) + + resp = await port.transceiver.access_mii(register_address=0).get() + resp.value Temperature ------------------ +Transceiver temperature in degrees Celsius. + +Corresponding CLI command: ``PX_TEMPERATURE`` .. code-block:: python - await port.transceiver.access_temperature().get() + # Transceiver Temperature + resp = await port.transceiver.access_temperature().get() + resp.integral_part + resp.fractional_part RX Laser Power -------------- +Reading of the optical power level of the received signal. There is one value +for each laser/wavelength, and the number of these depends on the kind of CFP +transceiver used. The list is empty if the CFP transceiver does not support +optical power read-out. + +Corresponding CLI command: ``PP_RXLASERPOWER`` .. code-block:: python - await port.pcs_pma.transceiver.rx_laser_power.get() + # Transceiver RX Laser Power + resp = await port.pcs_pma.transceiver.rx_laser_power.get() + resp.nanowatts TX Laser Power -------------- +Reading of the optical power level of the transmission signal. There is one +value for each laser/wavelength, and the number of these depends on the kind of CFP transceiver used. The list is empty if the CFP transceiver does not support optical power read-out. + +Corresponding CLI command: ``PP_TXLASERPOWER`` .. code-block:: python - await port.pcs_pma.transceiver.tx_laser_power.get() \ No newline at end of file + # Transceiver TX Laser Power + resp = await port.pcs_pma.transceiver.tx_laser_power.get() + resp.nanowatts diff --git a/docs/source/api_ref/hlapiv1/port/traffic.rst b/docs/source/api_ref/hlapiv1/port/traffic.rst index bf91a694..31c5fb56 100644 --- a/docs/source/api_ref/hlapiv1/port/traffic.rst +++ b/docs/source/api_ref/hlapiv1/port/traffic.rst @@ -3,61 +3,108 @@ Traffic Control Rate Percent ------------ +The port-level rate of the traffic transmitted for a port in sequential tx mode, expressed in millionths of the effective rate for the port. The bandwidth consumption includes the inter-frame gaps, and does not depend on the length of the packets for the streams. + +Corresponding CLI command: ``P_RATEFRACTION`` .. code-block:: python - await port.rate.fraction.set() - await port.rate.fraction.get() + # Traffic Control - Rate Percent + await port.rate.fraction.set(port_rate_ppm=1_000_000) + + resp = await port.rate.fraction.get() + resp.port_rate_ppm Rate L2 Bits Per Second ----------------------- +The port-level rate of the traffic transmitted for a port in sequential tx mode, expressed in units of bits per-second at layer-2, thus including the Ethernet header but excluding the inter-frame gap. The bandwidth consumption is somewhat dependent on the length of the packets generated for the stream, and also on the inter-frame gap for the port. + +Corresponding CLI command: ``P_RATEL2BPS`` .. code-block:: python - await port.rate.l2_bps.set() - await port.rate.l2_bps.get() + # Traffic Control - Rate L2 Bits Per Second + await port.rate.l2_bps.set(port_rate_bps=1_000_000) + + resp = await port.rate.l2_bps.get() + resp.port_rate_bps Rate Frames Per Second ---------------------- +The port-level rate of the traffic transmitted for a port in sequential tx mode, expressed in packets per second. The bandwidth consumption is heavily dependent on the length of the packets generated for the streams, and also on the inter-frame gap for the port. + +Corresponding CLI command: ``P_RATEPPS`` .. code-block:: python - await port.rate.pps.set() - await port.rate.pps.get() + # Traffic Control - Rate Frames Per Second + await port.rate.pps.set(port_rate_pps=10_000) + + resp = await port.rate.pps.get() + resp.port_rate_pps Start and Stop ---------------- +Whether a port is transmitting packets. When on, the port generates a sequence +of packets with contributions from each stream that is enabled. The streams are configured using the PS_xxx parameters. + +.. note:: + + If any of the specified packet sizes cannot fit into the packet generator, this command will return FAILED and not start the traffic. + While traffic is on the streams for this port cannot be enabled or disabled, and the configuration of those streams that are enabled cannot be changed. + +Corresponding CLI command: ``P_TRAFFIC`` .. code-block:: python + # Traffic Control - Start and Stop + await port.traffic.state.set(on_off=enums.StartOrStop.START) await port.traffic.state.set_start() + await port.traffic.state.set(on_off=enums.StartOrStop.STOP) await port.traffic.state.set_stop() - await port.traffic.state.get() - port.on_traffic_change(_callback_func) + + resp = await port.traffic.state.get() + resp.on_off Traffic Error ---------------------------- +Obtain the traffic error which has occurred in the last ``*_TRAFFIC`` or ``C_TRAFFICSYNC`` command. + +Corresponding CLI command: ``P_TRAFFICERR`` .. code-block:: python - await port.traffic.error.get() + # Traffic Control - Traffic Error + resp = await port.traffic.error.get() + resp.error Single Frame TX ---------------------------- +Transmits a single packet from a port, independent of the stream definitions, +and independent of whether traffic is on. A valid Frame Check Sum is written +into the final four bytes. + +Corresponding CLI command: ``P_XMITONE`` .. code-block:: python - await port.tx_single_pkt.send.set() + # Traffic Control - Single Frame TX + await port.tx_single_pkt.send.set(hex_data=Hex("00000000000102030405060800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) Single Frame Time ---------------------------- +The time at which the latest packet was transmitted using the P_XMITONE command. The time reference is the same used by the time stamps of captured packets. + +Corresponding CLI command: ``P_XMITONETIME`` .. code-block:: python - await port.tx_single_pkt.time.get() + # Traffic Control - Single Frame Time + resp = await port.tx_single_pkt.time.get() + resp.nanoseconds diff --git a/docs/source/api_ref/hlapiv1/port/tx_profile.rst b/docs/source/api_ref/hlapiv1/port/tx_profile.rst index aa0581bb..a774185d 100644 --- a/docs/source/api_ref/hlapiv1/port/tx_profile.rst +++ b/docs/source/api_ref/hlapiv1/port/tx_profile.rst @@ -4,94 +4,211 @@ TX Profile TPLD Mode ----------- +Sets the size of the Xena Test Payload (TPLD) used to track streams, perform +latency measurements etc. Default is "Normal", which is a 20 byte TPLD. "Micro" +is a condensed version, which is useful when generating very small packets with +relatively long headers (like IPv6). It has the following characteristics +compared to the "normal" TPLD. When the TPLDMODE is changed, it will affect ALL +streams on the port. 1) Only 6 byte long. 2) Less accurate mechanism to separate +Xena-generated packets from other packets is the network - it is recommended not +to have too much other traffic going into the receive Xena port, when micro TPLD +is used. 3) No sequence checking (packet loss or packet misordering). The number +of received packets for each stream can still be compared to the number of +transmitted packets to detect packet loss once traffic has been stopped. Note: +Currently not available on M6SFP, M2SFPT, M6RJ45+/M2RJ45+, M2CFP40, M1CFP100, +M2SFP+4SFP + +Corresponding CLI command: ``P_TPLDMODE`` .. code-block:: python + # TPLD Mode + await port.tpld_mode.set(mode=enums.TPLDMode.NORMAL) await port.tpld_mode.set_normal() + await port.tpld_mode.set(mode=enums.TPLDMode.MICRO) await port.tpld_mode.set_micro() - await port.tpld_mode.get() + + resp = await port.tpld_mode.get() + resp.mode TX Mode ----------- +The scheduling mode for outgoing traffic from the port, specifying how multiple +logical streams are merged onto one physical port. There are four primary modes: + +* Normal Interleaved: The streams are treated independently, and are merged into a +combined traffic pattern for the port, which honors each stream's ideal packet +placements as well as possible. This is the default mode. +* Strict Uniform: This is a slight variation of normal interleaved scheduling, which emphasizes strict +uniformity of the inter-packet-gaps as more important than hitting the stream +rates absolutely precisely. +* Sequential: Each stream in turn contribute one or +more packets, before continuing to the next stream, in a cyclical pattern. The +count of packets for each stream is obtained from the PS_PACKETLIMIT command +value for the stream. The individual rates for each stream are ignored, and +instead the overall rate is determined at the port-level. This in turn determines +the rates for each stream, taking into account their packet lengths and counts. +The maximum number of packets in a cycle (i.e. the sum of PS_PACKETLIMIT for all +enabled streams) is 500. If the packet number is larger than 500, will be returned +when attempting to start the traffic (P_TRAFFIC ON). +* Burst: When this mode is selected, frames from the streams on a port are sent as bursts as depicted below: + * The Burst Period is defined in the P_TXBURSTPERIOD command. + * For the individual streams the number of packets in a burst is defined by the PS_BURST command, while the Inter Packet Gap and the Inter Burst Gap are defined by the PS_BURSTGAP command. + +Corresponding CLI command: ``P_TXMODE`` .. code-block:: python + # TX Mode + await port.tx_config.mode.set(mode=enums.TXMode.NORMAL) await port.tx_config.mode.set_normal() + await port.tx_config.mode.set(mode=enums.TXMode.BURST) await port.tx_config.mode.set_burst() + await port.tx_config.mode.set(mode=enums.TXMode.SEQUENTIAL) await port.tx_config.mode.set_sequential() + await port.tx_config.mode.set(mode=enums.TXMode.STRICTUNIFORM) await port.tx_config.mode.set_strictuniform() - await port.tx_config.mode.get() + + resp = await port.tx_config.mode.get() + resp.mode Burst Period ------------ +In Burst TX mode this command defines the time from the start of one sequence of +bursts (from a number of streams) to the start of next sequence of bursts. + +.. note:: + + Only used when Port TX Mode is "BURST". + +Corresponding CLI command: ``P_TXBURSTPERIOD`` .. code-block:: python - await port.tx_config.burst_period.set() - await port.tx_config.burst_period.get() + # Burst Period + await port.tx_config.burst_period.set(burst_period=100) + + resp = await port.tx_config.burst_period.get() + resp.burst_period TX Delay ------------ +Sets a variable delay from a traffic start command received by the port until +it starts transmitting. The delay is specified in multiples of 64 microseconds. +Valid values are 0-31250 (0 to 2,000,000 microseconds). + +.. note:: + + You must use C_TRAFFIC instead of P_TRAFFIC to start traffic for P_TXDELAY to take effect. + +Corresponding CLI command: ``P_TXDELAY`` .. code-block:: python - await port.tx_config.delay.set() - await port.tx_config.delay.get() + # TX Delay + await port.tx_config.delay.set(delay_val=100) + + resp = await port.tx_config.delay.get() + resp.delay_val TX Enable ------------ +Whether a port should enable its transmitter, or keep the outgoing link down. + +Corresponding CLI command: ``P_TXENABLE`` .. code-block:: python - await port.tx_config.enable.set() - await port.tx_config.enable.get() + # TX Enable + await port.tx_config.enable.set(on_off=enums.OnOff.ON) + await port.tx_config.enable.set(on_off=enums.OnOff.OFF) + + resp = await port.tx_config.enable.get() + resp.on_off Packet Limit ------------ +The number of packets that will be transmitted from a port when traffic is +started on the port. A value of 0 or -1 makes the port transmit continuously. +Traffic from the streams on the port can however also be set to stop after +transmitting a number of packets. + +Corresponding CLI command: ``P_TXPACKETLIMIT`` .. code-block:: python - await port.tx_config.packet_limit.set() - await port.tx_config.packet_limit.get() + # Packet Limit + await port.tx_config.packet_limit.set(packet_count_limit=1_000_000) + + resp = await port.tx_config.packet_limit.get() + resp.packet_count_limit Time Limit ------------ +A port-level time-limit on how long it keeps transmitting when started. After +the elapsed time traffic must be stopped and restarted. This complements the +stream-level PS_PACKETLIMIT function. + +Corresponding CLI command: ``P_TXTIMELIMIT`` .. code-block:: python - await port.tx_config.time_limit.set() - await port.tx_config.time_limit.get() + # Time Limit + await port.tx_config.time_limit.set(microseconds=1_000_000) + + resp = await port.tx_config.time_limit.get() + resp.microseconds TX Time Elapsed --------------- +How long the port has been transmitting, the elapsed time since traffic was +started. + +Corresponding CLI command: ``P_TXTIME`` .. code-block:: python - await port.tx_config.time.get() + # TX Time Elapsed + resp = await port.tx_config.time.get() + resp.microseconds Prepare TX ------------ +Prepare port for transmission. + +Corresponding CLI command: ``P_TXPREPARE`` .. code-block:: python + # Prepare TX await port.tx_config.prepare.set() Dynamic TX Rate --------------- +Controls if a port with speed higher than 10G supports dynamic changes when the traffic is running. + +.. note:: + + This command is only supported by ports with speed higher than 10G. + +Corresponding CLI command: ``P_DYNAMIC`` .. code-block:: python + # Dynamic Traffic Rate + await port.dynamic.set(on_off=enums.OnOff.OFF) await port.dynamic.set_off() + await port.dynamic.set(on_off=enums.OnOff.ON) await port.dynamic.set_on() - await port.dynamic.get() - - port.on_dynamic_change(_callback_func) \ No newline at end of file + + resp = await port.dynamic.get() + resp.on_off \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/uat.rst b/docs/source/api_ref/hlapiv1/port/uat.rst index 95c14940..82ab08e7 100644 --- a/docs/source/api_ref/hlapiv1/port/uat.rst +++ b/docs/source/api_ref/hlapiv1/port/uat.rst @@ -3,17 +3,29 @@ Unavailable Time Mode ------------- +This command defines if a port is currently used by test suite Valkyrie1564, which means that UAT (UnAvailable Time) will be detected for the port. + +Corresponding CLI command: ``P_UAT_MODE`` .. code-block:: python - await port.uat.mode.set_on() - await port.uat.mode.set_off() - await port.uat.mode.get() + await port.uat.mode.set(mode=enums.OnOff.ON, delay=500) + await port.uat.mode.set(mode=enums.OnOff.OFF, delay=500) + + resp = await port.uat.mode.get() + resp.mode + resp.delay Frame Loss Ratio ---------------- +This command defines the threshold for the Frame Loss Ratio, where a second is +declared as a Severely Errored Second (SES). In Valkyrie1564 UnAvailable Time +(UAT) is declared after 10 consecutive SES has been detected + +Corresponding CLI command: ``P_UAT_FLR`` .. code-block:: python - await port.uat.frame_loss_ratio.get() \ No newline at end of file + resp = await port.uat.frame_loss_ratio.get() + resp.frame_loss_ratio \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/address.rst b/docs/source/api_ref/hlapiv1/port/vulcan/address.rst index 66733c8b..b02ed0c8 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/address.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/address.rst @@ -5,6 +5,8 @@ Port Address ARP Configuration -------------------- + + .. code-block:: python await port.arp_config.set() @@ -14,6 +16,8 @@ ARP Configuration NDP Configuration ------------------ + + .. code-block:: python await port.ndp_config.set() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/capabilities.rst b/docs/source/api_ref/hlapiv1/port/vulcan/capabilities.rst index f319cd7b..d3a4a9b1 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/capabilities.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/capabilities.rst @@ -1,6 +1,8 @@ Capabilities & Aptitudes ========================= + + .. code-block:: python await port.aptitudes.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/capture.rst b/docs/source/api_ref/hlapiv1/port/vulcan/capture.rst index b2c10b98..07f2517f 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/capture.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/capture.rst @@ -4,6 +4,8 @@ Capture Start -------------- + + .. code-block:: python await port.capture.start.set_on() @@ -14,6 +16,8 @@ Start Read PCAP ---------------- + + .. code-block:: python await port.capture.get_first_frame.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/index.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/index.rst index 15bc0453..3c3de24b 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/index.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/index.rst @@ -9,6 +9,8 @@ Test Application Type -------------- + + .. code-block:: python await cg.test_application.set_none() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/raw.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/raw.rst index 75a9a0dd..90e403f3 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/raw.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/raw.rst @@ -9,6 +9,8 @@ Raw Test Scenario -------------- + + .. code-block:: python await cg.raw.test_scenario.set_echo() @@ -21,6 +23,8 @@ Test Scenario Utilization -------------- + + .. code-block:: python await cg.raw.utilization.set() @@ -30,6 +34,8 @@ Utilization Transmission Config ------------------- + + .. code-block:: python await cg.raw.tx.during_ramp.set() @@ -42,6 +48,8 @@ Transmission Config Burst Config ------------------- + + .. code-block:: python await cg.raw.bursty.transmission.set_on() @@ -55,6 +63,8 @@ Burst Config Connection Close ------------------- + + .. code-block:: python await cg.raw.connection.close_condition.set_none() @@ -66,6 +76,8 @@ Connection Close Connection Incarnation ---------------------- + + .. code-block:: python await cg.raw.connection.incarnation.set_once() @@ -77,6 +89,8 @@ Connection Incarnation Connection Lifetime ------------------- + + .. code-block:: python await cg.raw.connection.lifetime.set_msecs() @@ -89,6 +103,8 @@ Connection Lifetime Connection Repetition ---------------------- + + .. code-block:: python await cg.raw.connection.repetitions.set_finite() @@ -99,6 +115,8 @@ Connection Repetition Download Request Content ------------------------- + + .. code-block:: python await cg.raw.download_request.content.set() @@ -108,6 +126,8 @@ Download Request Content Download Request Server Wait ---------------------------- + + .. code-block:: python await cg.raw.download_request.server_must_wait.set_yes() @@ -119,6 +139,8 @@ Download Request Server Wait Download Request Transaction Limit ---------------------------------- + + .. code-block:: python await cg.raw.download_request.transactions_number.set_finite() @@ -129,6 +151,8 @@ Download Request Transaction Limit Payload Type ---------------------- + + .. code-block:: python await cg.raw.payload.type.set_fixed() @@ -141,6 +165,8 @@ Payload Type Payload Content ---------------------- + + .. code-block:: python await cg.raw.payload.content.set() @@ -150,6 +176,8 @@ Payload Content Payload Repeat Length ---------------------- + + .. code-block:: python await cg.raw.payload.repeat_length.set() @@ -159,6 +187,8 @@ Payload Repeat Length Payload Total Length ---------------------- + + .. code-block:: python await cg.raw.payload.total_length.set_finite() @@ -169,6 +199,8 @@ Payload Total Length Payload RX Length ---------------------- + + .. code-block:: python await cg.raw.payload.rx_length.set_infinite() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/replay.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/replay.rst index e2538e96..52ad3ec1 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/replay.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/application/replay.rst @@ -9,6 +9,8 @@ Replay Utilization -------------- + + .. code-block:: python await cg.replay.utilization.set() @@ -18,6 +20,8 @@ Utilization Replay File ------------------- + + .. code-block:: python await cg.replay.files.indices.get() @@ -28,6 +32,8 @@ Replay File User Incarnation ------------------- + + .. code-block:: python await cg.replay.user.incarnation.set_once() @@ -39,6 +45,8 @@ User Incarnation User Repetition ------------------- + + .. code-block:: python await cg.replay.user.repetitions.set_finite() @@ -49,6 +57,8 @@ User Repetition Connection Incarnation ---------------------- + + .. code-block:: python await cg.raw.connection.incarnation.set_once() @@ -60,6 +70,8 @@ Connection Incarnation Connection Lifetime ------------------- + + .. code-block:: python await cg.raw.connection.lifetime.set_msecs() @@ -72,6 +84,8 @@ Connection Lifetime Connection Repetition ---------------------- + + .. code-block:: python await cg.raw.connection.repetitions.set_finite() @@ -82,6 +96,8 @@ Connection Repetition Download Request Content ------------------------- + + .. code-block:: python await cg.raw.download_request.content.set() @@ -91,6 +107,8 @@ Download Request Content Download Request Server Wait ---------------------------- + + .. code-block:: python await cg.raw.download_request.server_must_wait.set_yes() @@ -102,6 +120,8 @@ Download Request Server Wait Download Request Transaction Limit ---------------------------------- + + .. code-block:: python await cg.raw.download_request.transactions_number.set_finite() @@ -112,6 +132,8 @@ Download Request Transaction Limit Payload Type ---------------------- + + .. code-block:: python await cg.raw.payload.type.set_fixed() @@ -124,6 +146,8 @@ Payload Type Payload Content ---------------------- + + .. code-block:: python await cg.raw.payload.content.set() @@ -133,6 +157,8 @@ Payload Content Payload Repeat Length ---------------------- + + .. code-block:: python await cg.raw.payload.repeat_length.set() @@ -142,6 +168,8 @@ Payload Repeat Length Payload Total Length ---------------------- + + .. code-block:: python await cg.raw.payload.total_length.set_finite() @@ -152,6 +180,8 @@ Payload Total Length Payload RX Length ---------------------- + + .. code-block:: python await cg.raw.payload.rx_length.set_infinite() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/clear.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/clear.rst index d734a5d5..e0952866 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/clear.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/clear.rst @@ -5,6 +5,8 @@ Clear Counters Applicable to Vulcan port only. + + .. code-block:: python await cg.counters.clear.set() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/create.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/create.rst index 92510ba5..3f3c21b1 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/create.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/create.rst @@ -10,6 +10,8 @@ Create and Obtain Create a connection group on the Vulcan port, and obtain the connection group object. The connection group index is automatically assigned by the port. + + .. code-block:: python cg = await port.connection_groups.create() @@ -20,6 +22,8 @@ Obtain One Obtain an existing connection group on the port with an explicit connection group index. + + .. code-block:: python cg = port.connection_groups.obtain(cg_idx) @@ -30,6 +34,8 @@ Obtain Multiple Obtain multiple existing connection groups on the port with explicit connection group indices. + + .. code-block:: python cg_list = port.connection_groups.obtain_multiple(*cg_idx_list) @@ -40,6 +46,8 @@ Remove Remove a connection group on the port with an explicit connection group index. + + .. code-block:: python await port.connection_groups.remove(cg_idx) \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/description.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/description.rst index b170f85a..7570e8ca 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/description.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/description.rst @@ -6,6 +6,8 @@ Description Applicable to Vulcan port only. + + .. code-block:: python await cg.comment.set() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/histogram.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/histogram.rst index e559538c..dc0dede0 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/histogram.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/histogram.rst @@ -9,6 +9,8 @@ Histogram Configuration -------------- + + .. code-block:: python await cg.histogram.config.transaction.set() @@ -23,6 +25,8 @@ Configuration Recalculate -------------- + + .. code-block:: python await cg.histogram.recalculates.transaction.set() @@ -35,6 +39,8 @@ Recalculate Transaction -------------- + + .. code-block:: python await cg.histogram.transaction.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l2.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l2.rst index 909485da..491ff4e0 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l2.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l2.rst @@ -9,6 +9,8 @@ L2 ARP Resolution -------------- + + .. code-block:: python await cg.l2.address_resolve.set_no() @@ -19,6 +21,8 @@ ARP Resolution Use Gateway MAC as DMAC ----------------------- + + .. code-block:: python await cg.l2.gateway.use.set_yes() @@ -29,6 +33,8 @@ Use Gateway MAC as DMAC Gateway Config ----------------------- + + .. code-block:: python await cg.l2.gateway.ipv4.set() @@ -41,6 +47,8 @@ Gateway Config MAC Address ---------------------------- + + .. code-block:: python await cg.l2.mac.client.set() @@ -53,6 +61,8 @@ MAC Address VLAN Settings -------------- + + .. code-block:: python await cg.l2.vlan.enable.set_on() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l3.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l3.rst index 9c382d6d..c7248f34 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l3.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l3.rst @@ -9,6 +9,8 @@ L3 IP Version -------------- + + .. code-block:: python await cg.l3.ip_version.set_ipv4() @@ -19,6 +21,8 @@ IP Version IPv4 Range ----------------------- + + .. code-block:: python await cg.l3.ipv4.client_range.set() @@ -32,6 +36,8 @@ IPv4 Range IPv4 DiffServ Config ----------------------- + + .. code-block:: python await cg.l3.diffserv.mask.set() @@ -53,6 +59,8 @@ IPv4 DiffServ Config IPv6 Range ----------------------- + + .. code-block:: python await cg.l3.ipv6.client_range.set() @@ -65,6 +73,8 @@ IPv6 Range IPv6 Flow Label Config ----------------------- + + .. code-block:: python await cg.l3.ipv6.flow_label.set() @@ -77,6 +87,8 @@ IPv6 Flow Label Config NAT ---- + + .. code-block:: python await cg.l3.nat.set_on() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/index.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/index.rst index cd4142ec..ebcb52b8 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/index.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/index.rst @@ -9,6 +9,8 @@ L4 L4 Protocol -------------- + + .. code-block:: python await cg.layer4_protocol.set_tcp() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/tcp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/tcp.rst index c6704791..29787573 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/tcp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/tcp.rst @@ -8,6 +8,8 @@ TCP ACK Configuration ----------------------- + + .. code-block:: python await cg.tcp.ack.duplicate_thresholds.set() @@ -23,6 +25,8 @@ ACK Configuration Congestion Control ---------------------- + + .. code-block:: python await cg.tcp.cwnd.congestion_mode.set_none() @@ -34,6 +38,8 @@ Congestion Control Initial CWND ---------------------- + + .. code-block:: python await cg.tcp.cwnd.icwnd_calc_method.set_fixed_factor() @@ -45,6 +51,8 @@ Initial CWND Initial Slow Slart ---------------------- + + .. code-block:: python await cg.tcp.iss_treshold.set_automatic() @@ -55,6 +63,8 @@ Initial Slow Slart Max Segment Size - Fixed ------------------------ + + .. code-block:: python await cg.tcp.mss.fixed_value.set() @@ -64,6 +74,8 @@ Max Segment Size - Fixed Max Segment Size - Varying -------------------------- + + .. code-block:: python await cg.tcp.mss.range_limits.set() @@ -78,6 +90,8 @@ Max Segment Size - Varying RWND Scaling ---------------------- + + .. code-block:: python await cg.tcp.rwnd.scaling.set_yes() @@ -88,6 +102,8 @@ RWND Scaling RWND Size ---------------------- + + .. code-block:: python await cg.tcp.rwnd.size.set() @@ -97,6 +113,8 @@ RWND Size Retransmission Timeout Prolonged Mode -------------------------------------- + + .. code-block:: python await cg.tcp.rto.prolonged_mode.set_disable() @@ -106,6 +124,8 @@ Retransmission Timeout Prolonged Mode Retransmission Timeout Range -------------------------------------- + + .. code-block:: python await cg.tcp.rto.range_limits.set() @@ -114,6 +134,8 @@ Retransmission Timeout Range SYN Retransmission Timeout -------------------------------------- + + .. code-block:: python await cg.tcp.rto.syn_value.set() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/udp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/udp.rst index a264ac37..bf257cfa 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/udp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/l4/udp.rst @@ -8,6 +8,8 @@ UDP Packet Size Range ----------------------- + + .. code-block:: python await cg.udp.packet_size.range_limits.set() @@ -17,6 +19,8 @@ Packet Size Range Packet Size Type ---------------------- + + .. code-block:: python await cg.udp.packet_size.type.set_fixed() @@ -28,6 +32,8 @@ Packet Size Type Packet Size Value ---------------------- + + .. code-block:: python await cg.udp.packet_size.value.set() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/load.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/load.rst index 68ba654f..8c0ef002 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/load.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/load.rst @@ -8,6 +8,8 @@ Load Profile Shape ------ + + .. code-block:: python await cg.load_profile.shape.set() @@ -17,6 +19,8 @@ Shape Time Scale ---------- + + .. code-block:: python await cg.load_profile.time_scale.set_msecs() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/role.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/role.rst index 960fcee3..8641255d 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/role.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/role.rst @@ -5,6 +5,8 @@ Role Applicable to Vulcan port only. + + .. code-block:: python await cg.role.set_client() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/status.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/status.rst index a8f8b01b..d1f2e2be 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/status.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/status.rst @@ -6,6 +6,8 @@ Status Applicable to Vulcan port only. + + .. code-block:: python await cg.status.set_on() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/cg/tls.rst b/docs/source/api_ref/hlapiv1/port/vulcan/cg/tls.rst index 5a2fd25b..bdb848a6 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/cg/tls.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/cg/tls.rst @@ -8,6 +8,8 @@ TLS Enable -------------- + + .. code-block:: python await cg.tls.enable.set_yes() @@ -18,6 +20,8 @@ Enable Cipher Suites -------------- + + .. code-block:: python await cg.tls.cipher_suites.set() @@ -27,6 +31,8 @@ Cipher Suites Close Notify -------------- + + .. code-block:: python await cg.tls.close_notify.set_yes() @@ -37,6 +43,8 @@ Close Notify Certificate and Key -------------------- + + .. code-block:: python await cg.tls.file.certificate_path.set() @@ -47,6 +55,8 @@ Certificate and Key Max Record Size ---------------- + + .. code-block:: python await cg.tls.max_record_size.set() @@ -56,6 +66,8 @@ Max Record Size Protocol Version ---------------- + + .. code-block:: python await cg.tls.protocol.version.set_sslv3() @@ -68,6 +80,8 @@ Protocol Version Minimum Required Version ------------------------ + + .. code-block:: python await cg.tls.protocol.min_required_version.get() @@ -76,6 +90,8 @@ Minimum Required Version Server Name ------------------------ + + .. code-block:: python await cg.tls.server_name.set() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/clear.rst b/docs/source/api_ref/hlapiv1/port/vulcan/clear.rst index 89ad6318..bf30fbb4 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/clear.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/clear.rst @@ -1,6 +1,8 @@ Clear All ========================= + + .. code-block:: python await port.clear.set() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/replay.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/replay.rst index 146258f4..96e9f405 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/replay.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/replay.rst @@ -5,6 +5,8 @@ Replay Applicable to Vulcan port only. + + .. code-block:: python await cg.replay.counters.replay.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tcp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tcp.rst index 2b8aad13..e7ddb87b 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tcp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tcp.rst @@ -8,6 +8,8 @@ TCP Error ----- + + .. code-block:: python await cg.tcp.counters.error.get() @@ -15,6 +17,8 @@ Error Packet ------ + + .. code-block:: python await cg.tcp.counters.packet.tx.get() @@ -23,6 +27,8 @@ Packet Payload -------- + + .. code-block:: python await cg.tcp.counters.payload.rx.get() @@ -31,6 +37,8 @@ Payload Retransmission -------------- + + .. code-block:: python await cg.tcp.counters.retransmission.get() @@ -38,6 +46,8 @@ Retransmission State ----- + + .. code-block:: python await cg.tcp.counters.state.current.get() @@ -47,6 +57,8 @@ State Histogram ---------- + + .. code-block:: python await cg.tcp.histogram.connection.close_times.get() @@ -59,6 +71,8 @@ Histogram Clear Port Test Statistics -------------------------- + + .. code-block:: python await cg.tcp.clear_post_test_statistics.set() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tls.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tls.rst index 9816d1c9..3c0a6381 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tls.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/tls.rst @@ -8,6 +8,8 @@ TLS Alerts ------ + + .. code-block:: python await cg.tls.counters.alert.fatal.get() @@ -17,6 +19,8 @@ Alerts Payload -------- + + .. code-block:: python await cg.tls.counters.payload.tx.get() @@ -25,6 +29,8 @@ Payload State ----- + + .. code-block:: python await cg.tls.counters.state.current.get() @@ -34,6 +40,8 @@ State Histogram ---------- + + .. code-block:: python await cg.tls.histogram.handshake.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/transaction.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/transaction.rst index c6b9ecab..35afc7f6 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/transaction.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/transaction.rst @@ -5,6 +5,8 @@ Transaction Applicable to Vulcan port only. + + .. code-block:: python await cg.raw.transaction_counter.transaction.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/udp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/udp.rst index 93ae8cc5..64feda63 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/udp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/udp.rst @@ -8,6 +8,8 @@ UDP Packet ------ + + .. code-block:: python await cg.udp.counters.packet.rx.get() @@ -16,6 +18,8 @@ Packet Payload -------- + + .. code-block:: python await cg.udp.counters.payload.rx.get() @@ -25,6 +29,8 @@ Payload State ----- + + .. code-block:: python await cg.udp.counters.state.current.get() @@ -34,6 +40,8 @@ State Histogram ---------- + + .. code-block:: python await cg.udp.histogram.rx_bytes.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/user.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/user.rst index f75b57e1..cc5a4bb3 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/user.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/cg/user.rst @@ -5,6 +5,8 @@ User Applicable to Vulcan port only. + + .. code-block:: python await cg.user_state.current.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/arp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/arp.rst index d78cf163..9e996872 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/arp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/arp.rst @@ -8,6 +8,8 @@ ARP Total ----------------- + + .. code-block:: python await port.counters.arp.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.arp.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.arp.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/clear.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/clear.rst index 7031f9a4..cc0f1164 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/clear.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/clear.rst @@ -5,6 +5,8 @@ Clear Counters Applicable to Vulcan port only. + + .. code-block:: python await port.counters.clear.set() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/eth.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/eth.rst index 193e4b47..af4df05a 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/eth.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/eth.rst @@ -8,6 +8,8 @@ Ethernet Total ----------------- + + .. code-block:: python await port.counters.eth.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.eth.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.eth.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/icmp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/icmp.rst index 39a6f81a..1b900c5a 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/icmp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/icmp.rst @@ -8,6 +8,8 @@ ICMP Total ----------------- + + .. code-block:: python await port.counters.icmp.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.icmp.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.icmp.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv4.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv4.rst index 7bea4311..5e412447 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv4.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv4.rst @@ -4,6 +4,8 @@ IPv4 Total ----------------- + + .. code-block:: python await port.counters.ipv4.total.get() @@ -12,6 +14,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.ipv4.tx.get() @@ -20,6 +24,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.ipv4.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv6.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv6.rst index b2f49a5a..4e25f2d4 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv6.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ipv6.rst @@ -8,6 +8,8 @@ IPv6 Total ----------------- + + .. code-block:: python await port.counters.ipv6.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.ipv6.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.ipv6.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ndp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ndp.rst index 26a0bda7..9f63e5a7 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ndp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/ndp.rst @@ -8,6 +8,8 @@ NDP Total ----------------- + + .. code-block:: python await port.counters.ndp.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.ndp.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.ndp.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/tcp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/tcp.rst index c24c77ca..9a4cf7ab 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/tcp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/tcp.rst @@ -8,6 +8,8 @@ TCP Total ----------------- + + .. code-block:: python await port.counters.tcp.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.tcp.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.tcp.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/total.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/total.rst index 07fdaa7c..b7a9e8fa 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/total.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/total.rst @@ -8,6 +8,8 @@ All Total ----------------- + + .. code-block:: python await port.counters.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.total_tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.total_rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/udp.rst b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/udp.rst index 70f53e85..f86c7242 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/udp.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/counter/port/udp.rst @@ -8,6 +8,8 @@ UDP Total ----------------- + + .. code-block:: python await port.counters.udp.total.get() @@ -16,6 +18,8 @@ Total TX ----------------- + + .. code-block:: python await port.counters.udp.tx.get() @@ -24,6 +28,8 @@ TX RX ----------------- + + .. code-block:: python await port.counters.udp.rx.get() diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/identification.rst b/docs/source/api_ref/hlapiv1/port/vulcan/identification.rst index 7e117f00..aa0547dd 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/identification.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/identification.rst @@ -4,6 +4,8 @@ Identification Firmware Version ----------------- + + .. code-block:: python await port.nic_firmware_version.get() @@ -12,6 +14,8 @@ Firmware Version NIC Name ------------ + + .. code-block:: python await port.nic_name.get() @@ -19,6 +23,8 @@ NIC Name Status ------ + + .. code-block:: python await port.last_state_status.get() @@ -27,6 +33,8 @@ Status License Info ------------- + + .. code-block:: python await port.license_info.get() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/port/vulcan/pps.rst b/docs/source/api_ref/hlapiv1/port/vulcan/pps.rst index 83e3b78b..e8061202 100644 --- a/docs/source/api_ref/hlapiv1/port/vulcan/pps.rst +++ b/docs/source/api_ref/hlapiv1/port/vulcan/pps.rst @@ -1,6 +1,8 @@ Max Packet Rate ========================= + + .. code-block:: python await port.max_packet_rate.set_automatic() diff --git a/docs/source/api_ref/hlapiv1/stream/cdf.rst b/docs/source/api_ref/hlapiv1/stream/cdf.rst index 3696cbd0..39cb3cd3 100644 --- a/docs/source/api_ref/hlapiv1/stream/cdf.rst +++ b/docs/source/api_ref/hlapiv1/stream/cdf.rst @@ -7,18 +7,47 @@ Custom Data Field Field Offset --------------------- +This command is part of the Custom Data Field (CDF) feature. The CDF offset +for the stream is the location in the stream data packets where the various CDF +data will be inserted. All fields for a given stream uses the same offset +value. The default value is zero (0) which means that the CDF data will be +inserted at the very start of the packet, thus overwriting the packet protocol +headers. If you want the CDF data to start immediately after the end of the +packet protocol headers you will have to set the CDF field offset manually. The +feature requires that the P_PAYLOADMODE command on the parent port has been +set to CDF. This enables the feature for all streams on this port. + +Corresponding CLI command: ``PS_CDFOFFSET`` .. code-block:: python - await stream.cdf.offset.set() - await stream.cdf.offset.get() + # Custom Data Field + # Use await port.payload_mode.set_cdf() to set the port's payload mode to Custom Data Field. + + # Field Offset + await stream.cdf.offset.set(offset=1) + + resp = await stream.cdf.offset.get() + resp.offset Byte Count ------------------------- +This command is part of the Custom Data Field (CDF) feature. It controls the +number of custom data fields available for each stream. You can set a different number +of fields for each stream. Changing the field count value to a larger value will +leave all existing fields intact. Changing the field count value to a smaller +value will remove all existing fields with an index larger than or equal to the +new count. The feature requires that the P_PAYLOADMODE command on the parent +port has been set to CDF. This enables the feature for all streams on this port. + +Corresponding CLI command: ``PS_CDFCOUNT`` .. code-block:: python - await stream.cdf.count.set() - await stream.cdf.count.get() + # Byte Count + await stream.cdf.count.set(cdf_count=1) + + resp = await stream.cdf.count.get() + resp.cdf_count diff --git a/docs/source/api_ref/hlapiv1/stream/connectivity.rst b/docs/source/api_ref/hlapiv1/stream/connectivity.rst index 10460e6e..ea1e6b72 100644 --- a/docs/source/api_ref/hlapiv1/stream/connectivity.rst +++ b/docs/source/api_ref/hlapiv1/stream/connectivity.rst @@ -3,42 +3,81 @@ Connectivity Check IPv4 Gateway Address -------------------- +An IPv4 gateway configuration specified for a stream. + +Corresponding CLI command: ``PS_IPV4GATEWAY`` .. code-block:: python - await stream.gateway.ipv4.set() - await stream.gateway.ipv4.get() + # IPv4 Gateway Address + await stream.gateway.ipv4.set(gateway=ipaddress.IPv4Address("10.10.10.1")) + + resp = await stream.gateway.ipv4.get() + resp.gateway IPv6 Gateway Address -------------------- +An IPv6 gateway configuration specified for a stream. + +Corresponding CLI command: ``PS_IPV6GATEWAY`` .. code-block:: python - await stream.gateway.ipv6.set() - await stream.gateway.ipv6.get() + # IPv6 Gateway Address + await stream.gateway.ipv6.set(gateway=ipaddress.IPv6Address("::0001")) + + resp = await stream.gateway.ipv6.get() + resp.gateway ARP Resolve Peer Address ------------------------ +Generates an outgoing ARP request on the test port. The packet header for the +stream must contain an IP protocol segment, and the destination IP address is +used in the ARP request. If there is a gateway IP address specified for the port +and it is on a different subnet than the destination IP address in the packet +header, then the gateway IP address is used instead. The framing of the ARP +request matches the packet header, including any VLAN protocol segments. This +command does not generate an immediate result, but waits until an ARP +reply is received on the test port. If no reply is received within 500 +milliseconds, it returns. .. note:: You need to make sure either the port has a correct gateway or the stream has a correct destination IP address to ARP resolve the MAC address. +Corresponding CLI command: ``PS_ARPREQUEST`` + .. code-block:: python - await stream.request.arp.get() + # ARP Resolve Peer Address + # You need to make sure either the port has a correct gateway or the stream has a correct destination IP address to ARP resolve the MAC address. + resp = await stream.request.arp.get() + resp.mac_address PING Check IP Peer ------------------------ +Generates an outgoing ping request using the ICMP protocol on the test port. The +packet header for the stream must contain an IP protocol segment, with valid +source and destination IP addresses. The framing of the ping request matches the +packet header, including any VLAN protocol segments, and the destination MAC +address must also be valid, possibly containing a value obtained with +PS_ARPREQUEST. This command does not generate an immediate result, but +waits until a ping reply is received on the test port. .. note:: You need to make sure either the port has a correct gateway or the stream has a correct destination IP address to ping. +Corresponding CLI command: ``PS_PINGREQUEST`` + .. code-block:: python - await stream.request.ping.get() + # PING Check IP Peer + # You need to make sure either the port has a correct gateway or the stream has a correct destination IP address to ping. + resp = await stream.request.ping.get() + resp.delay + resp.time_to_live diff --git a/docs/source/api_ref/hlapiv1/stream/content.rst b/docs/source/api_ref/hlapiv1/stream/content.rst index 27004aef..651c1399 100644 --- a/docs/source/api_ref/hlapiv1/stream/content.rst +++ b/docs/source/api_ref/hlapiv1/stream/content.rst @@ -3,53 +3,116 @@ Packet Content Packet Size --------------------- +The length distribution of the packets transmitted for a stream. The length of +the packets transmitted for a stream can be varied from packet to packet, +according to a choice of distributions within a specified min...max range. The +length of each packet is reflected in the size of the payload portion of the +packet, whereas the header has constant length. Length variation complements, +and is independent of, the content variation produced by header modifiers. + +Corresponding CLI command: ``PS_PACKETLENGTH`` .. code-block:: python - await stream.packet.length.set_fixed(min, max) - await stream.packet.length.set_butterfly(min, max) - await stream.packet.length.set_incrementing(min, max) - await stream.packet.length.set_mix(min, max) - await stream.packet.length.set_random(min, max) - await stream.packet.length.get() + # Packet Size + await stream.packet.length.set(length_type=enums.LengthType.FIXED, min_val=64, max_val=64) + await stream.packet.length.set(length_type=enums.LengthType.INCREMENTING, min_val=64, max_val=1500) + await stream.packet.length.set(length_type=enums.LengthType.BUTTERFLY, min_val=64, max_val=1500) + await stream.packet.length.set(length_type=enums.LengthType.RANDOM, min_val=64, max_val=1500) + await stream.packet.length.set(length_type=enums.LengthType.MIX, min_val=64, max_val=64) + + resp = await stream.packet.length.get() + resp.length_type + resp.min_val + resp.max_val Packet Auto Size ------------------------- +Executing PS_AUTOADJUST will adjust the packet length distribution (PS_PACKETLENGTH) of the stream: + +(1) Set the type of packet length distribution (PS_PACKETLENGTH ````) to ``FIXED``. + +(2) Set the lower limit on the packet length (PS_PACKETLENGTH ````) to exactly fit the specified protocol headers, +TPLD and FCS (but never set to less than 64). + +(3) Set the payload type of packets transmitted for the stream (PS_PAYLOAD ````) to ``PATTERN``. + +(4) If necessary, also set the maximum number of header content bytes (P_MAXHEADERLENGTH ```` ````) +that can be freely specified for each generated stream of the port to a higher value, if needed to accommodate the header size of the stream +(implicitly given by the PS_PACKETHEADER command). + +(5) If the needed maximum header length (P_MAXHEADERLENGTH ```` ````) +is not possible with the actual number of active streams for the port, the command will fail with: . + +Corresponding CLI command: ``PS_AUTOADJUST`` .. code-block:: python + # Packet Auto Size await stream.packet.auto_adjust.set() Payload Type ------------------------- +The payload content of the packets transmitted for a stream. The payload portion +of a packet starts after the header and continues up until the test payload or +the frame checksum. The payload may vary in length and is filled with either an +incrementing sequence of byte values or a repeated multi-byte pattern. Length +variation complements and is independent of the content variation produced by +header modifiers. +Corresponding CLI command: ``PS_PAYLOAD`` .. code-block:: python + # Payload Type # Pattern string in hex, min = 1 byte, max = 18 bytes - await stream.payload.content.set_pattern("AABBCCDD") + await stream.payload.content.set(payload_type=enums.PayloadType.PATTERN, hex_data=Hex("000102030405060708090A0B0C0D0E0FDEAD")) + await stream.payload.content.set(payload_type=enums.PayloadType.PATTERN, hex_data=Hex("F5")) # Patter string ignored for non-pattern types + await stream.payload.content.set(payload_type=enums.PayloadType.INC16, hex_data=Hex("F5")) await stream.payload.content.set_inc_word("00") + await stream.payload.content.set(payload_type=enums.PayloadType.INC8, hex_data=Hex("F5")) await stream.payload.content.set_inc_byte("00") + await stream.payload.content.set(payload_type=enums.PayloadType.DEC8, hex_data=Hex("F5")) await stream.payload.content.set_dec_byte("00") + await stream.payload.content.set(payload_type=enums.PayloadType.DEC16, hex_data=Hex("F5")) await stream.payload.content.set_dec_word("00") + await stream.payload.content.set(payload_type=enums.PayloadType.PRBS, hex_data=Hex("F5")) await stream.payload.content.set_prbs("00") + await stream.payload.content.set(payload_type=enums.PayloadType.RANDOM, hex_data=Hex("F5")) await stream.payload.content.set_random("00") + resp = await stream.payload.content.get() + resp.hex_data + resp.payload_type + Extended Payload ------------------------- +This command controls the extended payload feature. The PS_PAYLOAD command +described above only allow the user to specify an 18-byte pattern (when +PS_PAYLOAD is set to PATTERN). The PS_EXTPAYLOAD command allow the definition +of a much larger (up to MTU) payload buffer for each stream. The extended +payload will be inserted immediately after the end of the protocol segment area. +The feature requires the P_PAYLOADMODE command on the parent port being set to +EXTPL. This enables the feature for all streams on this port. .. note:: Use ``await port.payload_mode.set_extpl()`` to set the port's payload mode to Extended Payload. +Corresponding CLI command: ``PS_EXTPAYLOAD`` + .. code-block:: python - await stream.payload.extended.set("00110022FF...") - await stream.payload.extended.get() + # Extended Payload + # Use await port.payload_mode.set_extpl() to set the port's payload mode to Extended Payload. + await stream.payload.extended.set(hex_data=Hex("00110022FF")) + + resp = await stream.payload.extended.get() + resp.hex_data diff --git a/docs/source/api_ref/hlapiv1/stream/create.rst b/docs/source/api_ref/hlapiv1/stream/create.rst index b003cf34..1f6e1b12 100644 --- a/docs/source/api_ref/hlapiv1/stream/create.rst +++ b/docs/source/api_ref/hlapiv1/stream/create.rst @@ -6,6 +6,8 @@ Create and Obtain Create a stream on the port, and obtain the stream object. The stream index is automatically assigned by the port. +Corresponding CLI command: ``PS_CREATE`` + .. code-block:: python stream = await port.streams.create() @@ -18,7 +20,7 @@ Obtain an existing stream on the port with an explicit stream index. .. code-block:: python - stream = port.streams.obtain(stream_idx) + stream = = port.streams.obtain(0) Obtain Multiple @@ -28,14 +30,18 @@ Obtain multiple existing streams on the port with explicit stream indices. .. code-block:: python - stream_list = port.streams.obtain_multiple(*stream_idx_list) + stream_list = port.streams.obtain_multiple(*[0,1,2]) Remove --------------- -Remove a stream on the port with an explicit stream index. +Deletes the stream definition with the specified sub-index value. + +Corresponding CLI command: ``PS_DELETE`` .. code-block:: python - await port.streams.remove(stream_idx) \ No newline at end of file + # Remove + # Remove a stream on the port with an explicit stream index. + await port.streams.remove(position_idx=0) \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/stream/error_handling/error_inject.rst b/docs/source/api_ref/hlapiv1/stream/error_handling/error_inject.rst index 5575da7c..eb27222c 100644 --- a/docs/source/api_ref/hlapiv1/stream/error_handling/error_inject.rst +++ b/docs/source/api_ref/hlapiv1/stream/error_handling/error_inject.rst @@ -3,39 +3,78 @@ Error Injection Misorder Error ------------------------------ +Force a misorder error by swapping the test payload sequence numbers in two of +the packets currently being transmitted from a stream. This can aid in analyzing +the error-detection functionality of the system under test. Traffic must be on +for the port, and the stream must be enabled and include test payloads. + +Corresponding CLI command: ``PS_INJECTMISERR`` .. code-block:: python + # Misorder Error Injection await stream.inject_err.misorder.set() Payload Integrity Error ------------------------------ +Force a payload integrity error in one of the packets currently being +transmitted from a stream. Payload integrity validation is only available for +incrementing payloads, and the error is created by changing a byte from the +incrementing sequence. The packet will have a correct frame checksum, but the +receiving Xena chassis will detect the invalid payload based on information in +the test payload. Traffic must be on for the port, and the stream must be +enabled and include test payloads. + +Corresponding CLI command: ``PS_INJECTPLDERR`` .. code-block:: python + # Payload Integrity Error Injection await stream.inject_err.payload_integrity.set() Sequence Error ------------------------------ +Force a sequence error by skipping a test payload sequence number in one of the +packets currently being transmitted from a stream. This can aid in analyzing the +error-detection functionality of the system under test. Traffic must be on for +the port, and the stream must be enabled and include test payloads. + +Corresponding CLI command: ``PS_INJECTSEQERR`` .. code-block:: python + # Sequence Error Injection await stream.inject_err.sequence.set() Test Payload Error ------------------------------ +Force a test payload error in one of the packets currently being transmitted +from a stream. This means that the test payload will not be recognized at the +receiving port, so it will be counted as a no-test-payload packet, and there +will be a lost packet for the stream. Traffic must be on for the port, and the +stream must be enabled and include test payloads. + +Corresponding CLI command: ``PS_INJECTTPLDERR`` .. code-block:: python + # Test Payload Error Injection await stream.inject_err.test_payload.set() Checksum Error ------------------------------ +Force a frame checksum error in one of the packets currently being transmitted +from a stream. This can aid in analyzing the error-detection functionality of +the system under test. Traffic must be on for the port, and the stream must be +enabled. + +Corresponding CLI command: ``PS_INJECTFCSERR`` .. code-block:: python + # Checksum Error Injection await stream.inject_err.frame_checksum.set() \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/stream/error_handling/insert_fcs.rst b/docs/source/api_ref/hlapiv1/stream/error_handling/insert_fcs.rst index bd0a5eea..96c14fc1 100644 --- a/docs/source/api_ref/hlapiv1/stream/error_handling/insert_fcs.rst +++ b/docs/source/api_ref/hlapiv1/stream/error_handling/insert_fcs.rst @@ -1,8 +1,16 @@ Insert Frame Checksum ========================= +Whether a valid frame checksum is added to the packets of a stream. + +Corresponding CLI command: ``PS_INSERTFCS`` .. code-block:: python + # Insert Frame Checksum + await stream.insert_packets_checksum.set(on_off=enums.OnOff.ON) await stream.insert_packets_checksum.set_on() + await stream.insert_packets_checksum.set(on_off=enums.OnOff.OFF) await stream.insert_packets_checksum.set_off() - await stream.insert_packets_checksum.get() + + resp = await stream.insert_packets_checksum.get() + resp.on_off diff --git a/docs/source/api_ref/hlapiv1/stream/header.rst b/docs/source/api_ref/hlapiv1/stream/header.rst index 71d183cd..01b44269 100644 --- a/docs/source/api_ref/hlapiv1/stream/header.rst +++ b/docs/source/api_ref/hlapiv1/stream/header.rst @@ -3,18 +3,132 @@ Packet Header Definition Header Protocol Segment ------------------------ +This command will inform the Xena tester how to interpret the packet header +byte sequence specified with PS_PACKETHEADER. This is mainly for information +purposes, and the stream will transmit the packet header bytes even if no +protocol segments are specified. The Xena tester however support calculation of +certain field values in hardware, such as the IP, TCP and UDP length and +checksum fields. This allow the use of hardware modifiers for these protocol +segments. In order for this function to work the Xena tester needs to know the +type of each segment that precedes the segment where the hardware calculation is +to be performed. + +Corresponding CLI command: ``PS_HEADERPROTOCOL`` .. code-block:: python - await stream.packet.header.protocol.set(segments) - await stream.packet.header.protocol.get() + # Header Protocol Segment + await stream.packet.header.protocol.set(segments=[ + enums.ProtocolOption.ETHERNET, + enums.ProtocolOption.VLAN, + enums.ProtocolOption.IP, + enums.ProtocolOption.UDP, + ]) + + # ETHERNET = 1 + # """Ethernet II""" + # VLAN = 2 + # """VLAN""" + # ARP = 3 + # """Address Resolution Protocol""" + # IP = 4 + # """IPv4""" + # IPV6 = 5 + # """IPv6""" + # UDP = 6 + # """User Datagram Protocol (w/o checksum)""" + # TCP = 7 + # """Transmission Control Protocol (w/o checksum)""" + # LLC = 8 + # """Logic Link Control""" + # SNAP = 9 + # """Subnetwork Access Protocol""" + # GTP = 10 + # """GPRS Tunnelling Protocol""" + # ICMP = 11 + # """Internet Control Message Protocol""" + # RTP = 12 + # """Real-time Transport Protocol""" + # RTCP = 13 + # """RTP Control Protocol""" + # STP = 14 + # """Spanning Tree Protocol""" + # SCTP = 15 + # """Stream Control Transmission Protocol""" + # MACCTRL = 16 + # """MAC Control""" + # MPLS = 17 + # """Multiprotocol Label Switching""" + # PBBTAG = 18 + # """Provider Backbone Bridge tag""" + # FCOE = 19 + # """Fibre Channel over Ethernet""" + # FC = 20 + # """Fibre Channel""" + # FCOETAIL = 21 + # """Fibre Channel over Ethernet (tail)""" + # IGMPV3L0 = 22 + # """IGMPv3 Membership Query L=0""" + # IGMPV3L1 = 23 + # """IGMPv3 Membership Query L=1""" + # UDPCHECK = 24 + # """User Datagram Protocol (w/ checksum)""" + # IGMPV2 = 25 + # """Internet Group Management Protocol v2""" + # MPLS_TP_OAM = 26 + # """MPLS-TP, OAM Header""" + # GRE_NOCHECK = 27 + # """Generic Routing Encapsulation (w/o checksum)""" + # GRE_CHECK = 28 + # """Generic Routing Encapsulation (w/ checksum)""" + # TCPCHECK = 29 + # """Transmission Control Protocol (w/ checksum)""" + # GTPV1L0 = 30 + # """GTPv1 (no options), GPRS Tunneling Protocol v1""" + # GTPV1L1 = 31 + # """GTPv1 (w/ options), GPRS Tunneling Protocol v1""" + # GTPV2L0 = 32 + # """GTPv2 (no options), GPRS Tunneling Protocol v2""" + # GTPV2L1 = 33 + # """GTPv2 (w/ options), GPRS Tunneling Protocol v2""" + # IGMPV1 = 34 + # """Internet Group Management Protocol v1""" + # PWETHCTRL = 35 + # """PW Ethernet Control Word""" + # VXLAN = 36 + # """Virtual eXtensible LAN""" + # ETHERNET_8023 = 37 + # """Ethernet 802.3""" + # NVGRE = 38 + # """Generic Routing Encapsulation (Network Virtualization)""" + # DHCPV4 = 39 + # """Dynamic Host Configuration Protocol (IPv4)""" + # GENEVE = 40 + # """Generic Network Virtualization Encapsulation""" + + resp = await stream.packet.header.protocol.get() + resp.segments Header Value ------------------------- +The first portion of the packet bytes that are transmitted for a stream. This +starts with the 14 bytes of the Ethernet header, followed by any contained +protocol segments. All packets transmitted for the stream start with this fixed +header. Individual byte positions of the packet header may be varied on a +packet-to-packet basis using modifiers. The full packet comprises the header, +the payload, an optional test payload, and the frame checksum. The header data +is specified as raw bytes, since the script environment does not know the field- +by-field layout of the various protocol segments. + +Corresponding CLI command: ``PS_PACKETHEADER`` .. code-block:: python - await stream.packet.header.data.set("11223344FFEEBB...") - await stream.packet.header.data.get() + # Header Value + await stream.packet.header.data.set( + hex_data=Hex("00000000000004F4BC7FFE908100000008004500002A000000007F113BC400000000000000000000000000160000")) + + resp = await stream.packet.header.data.get() + resp.hex_data diff --git a/docs/source/api_ref/hlapiv1/stream/identification.rst b/docs/source/api_ref/hlapiv1/stream/identification.rst index 18863ed7..f3b01232 100644 --- a/docs/source/api_ref/hlapiv1/stream/identification.rst +++ b/docs/source/api_ref/hlapiv1/stream/identification.rst @@ -3,27 +3,60 @@ Identification Description ----------- +The description of a stream. + +Corresponding CLI command: ``PS_COMMENT`` .. code-block:: python + # Description await stream.comment.set(comment="description") - await stream.comment.get() + + resp = await stream.comment.get() + resp.comment Test Payload ID --------------- +The identifier of the test payloads inserted into packets transmitted for a +stream. A value of -1 disables test payloads for the stream. Test payloads are +inserted at the end of each packet, and contains time-stamp and sequence-number +information. This allows the receiving port to provide error-checking and +latency measurements, in addition to the basic counts and rate measurements +provided for all traffic. The test payload identifier furthermore allows the +receiving port to distinguish multiple different streams, which may originate +from multiple different chassis. Since test payloads are an inter-port and +inter-chassis mechanism, the test payload identifier assignments should be + +Corresponding CLI command: ``PS_TPLDID`` .. code-block:: python - await stream.tpld_id.set() - await stream.tpld_id.get() + # Test Payload ID + await stream.tpld_id.set(test_payload_identifier=0) + + resp = await stream.tpld_id.get() + resp.test_payload_identifier) State ------------- +This property determines if a stream contributes outgoing packets for a port. +The value can be toggled between ON and SUPPRESS while traffic is enabled at the +port level. Streams in the OFF state cannot be set to any other value while +traffic is enabled. The sum of the rates of all enabled or suppressed streams +must not exceed the effective port rate. + +Corresponding CLI command: ``PS_ENABLE`` .. code-block:: python + # State + await stream.enable.set(state=enums.OnOffWithSuppress.OFF) await stream.enable.set_off() + await stream.enable.set(state=enums.OnOffWithSuppress.ON) await stream.enable.set_on() + await stream.enable.set(state=enums.OnOffWithSuppress.SUPPRESS) await stream.enable.set_suppress() - await stream.enable.get() + + resp = await stream.enable.get() + resp.state diff --git a/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst b/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst index d6abeb37..b4207e16 100644 --- a/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst +++ b/docs/source/api_ref/hlapiv1/stream/modifier/modifier.rst @@ -7,8 +7,8 @@ Create .. code-block:: python - await stream.packet.header.modifiers.configure(modifier_count) - + # Create + await stream.packet.header.modifiers.configure(number=1) Clear @@ -16,6 +16,7 @@ Clear .. code-block:: python + # Clear await stream.packet.header.modifiers.clear() @@ -29,22 +30,56 @@ Obtain .. code-block:: python - modifier = stream.packet.header.modifiers.obtain(modifier_idx) + # Obtain + # Must create modifiers before obtain. + modifier = stream.packet.header.modifiers.obtain(idx=0) Range ------------------------- +Range specification for a packet modifier for a stream header, specifying which +values the modifier should take on. This applies only to incrementing and +decrementing modifiers; random modifiers always produce every possible bit +pattern. The range is specified as three values: mix, step, and max, where max +must be equal to min plus a multiple of step. Note that when "decrement" is +specified in PS_MODIFIER as the action, the value sequence will begin with the +max value instead of the min value and decrement from there: {max, max-1, max-2, +...., min, max, max-1...}. + +Corresponding CLI command: ``PS_MODIFIERRANGE`` .. code-block:: python - await modifier.range.set() - await modifier.range.get() + # Range + await modifier.range.set(min_val=0, step=10, max_val=9) + + resp = await modifier.range.get() + resp.min_val + resp.max_val + resp.step Position, Action, Mask ---------------------- +A packet modifier for a stream header. The headers of each packet transmitted +for the stream will be varied according to the modifier specification. This +command requires two sub-indices, one for the stream and one for the modifier. +A modifier is positioned at a fixed place in the header, selects a number of +consecutive bits starting from that position, and applies an action to those +bits in each packet. Packets can be repeated so that a certain number of +identical packets are transmitted before applying the next modification. + +Corresponding CLI command: ``PS_MODIFIER`` .. code-block:: python - await modifier.specification.set() - await modifier.specification.get() \ No newline at end of file + # Position, Action, Mask + await modifier.specification.set(position=0, mask=Hex("FFFF0000"), action=enums.ModifierAction.INC, repetition=1) + await modifier.specification.set(position=0, mask=Hex("FFFF0000"), action=enums.ModifierAction.DEC, repetition=1) + await modifier.specification.set(position=0, mask=Hex("FFFF0000"), action=enums.ModifierAction.RANDOM, repetition=1) + + resp = await modifier.specification.get() + resp.action + resp.mask + resp.position + resp.repetition \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst b/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst index 61024f3e..1db4c33f 100644 --- a/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst +++ b/docs/source/api_ref/hlapiv1/stream/modifier/modifier_ext.rst @@ -7,8 +7,8 @@ Create .. code-block:: python - await stream.packet.header.modifiers_extended.configure(modifier_count) - + # Create + await stream.packet.header.modifiers_extended.configure(number=1) Clear @@ -16,6 +16,7 @@ Clear .. code-block:: python + # Clear await stream.packet.header.modifiers_extended.clear() @@ -29,22 +30,58 @@ Obtain .. code-block:: python - modifier_ext = stream.packet.header.modifiers_extended.obtain(modifier_idx) + # Obtain + # Must create modifiers before obtain. + modifier_ext = stream.packet.header.modifiers_extended.obtain(idx=0) Range ------------------------- +Range specification for an extended packet modifier for a stream header, +specifying which values the modifier should take on. This applies only to +incrementing and decrementing modifiers; random modifiers always produce every +possible bit pattern. The range is specified as a three values: mix, step, and +max, where max must be equal to min plus a multiple of step. Note that when +"decrement" is specified in PS_MODIFIEREXT as the action, the value sequence +will begin with the max value instead of the min value and decrement from there: +{max, max-1, max-2, ...., min, max, max-1...}. + +Corresponding CLI command: ``PS_MODIFIEREXTRANGE`` .. code-block:: python - await modifier_ext.range.set() - await modifier_ext.range.get() + # Range + await modifier_ext.range.set(min_val=0, step=1, max_val=100) + + resp = await modifier_ext.range.get() + resp.max_val + resp.min_val + resp.step Position, Action, Mask ---------------------- +An extended packet modifier for a stream header. The headers of each packet +transmitted for the stream will be varied according to the modifier +specification. The modifier acts on 32 bits and takes up the space for two +16-bit modifiers to do this. This command requires two sub-indices, one for +the stream and one for the modifier. A modifier is positioned at a fixed place +in the header, selects a number of consecutive bits starting from that position, +and applies an action to those bits in each packet. Packets can be repeated so +that a certain number of identical packets are transmitted before applying the +next modification. + +Corresponding CLI command: ``PS_MODIFIEREXT`` .. code-block:: python - await modifier_ext.specification.set() - await modifier_ext.specification.get() \ No newline at end of file + # Position, Action, Mask + await modifier_ext.specification.set(position=0, mask=Hex("FFFFFFFF"), action=enums.ModifierAction.INC, repetition=1) + await modifier_ext.specification.set(position=0, mask=Hex("FFFFFFFF"), action=enums.ModifierAction.DEC, repetition=1) + await modifier_ext.specification.set(position=0, mask=Hex("FFFFFFFF"), action=enums.ModifierAction.RANDOM, repetition=1) + + resp = await modifier_ext.specification.get() + resp.action + resp.mask + resp.position + resp.repetition \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/stream/tx_profile.rst b/docs/source/api_ref/hlapiv1/stream/tx_profile.rst index 14826d18..16897092 100644 --- a/docs/source/api_ref/hlapiv1/stream/tx_profile.rst +++ b/docs/source/api_ref/hlapiv1/stream/tx_profile.rst @@ -3,63 +3,151 @@ TX Profile Rate Fraction --------------- +The rate of the traffic transmitted for a stream expressed in millionths of the +effective rate for the port. The bandwidth consumption includes the inter-frame +gap and is independent of the length of the packets generated for the stream. +The sum of the bandwidth consumption for all the enabled streams must not exceed +the effective rate for the port. Setting this command also instructs the +Manager to attempt to keep the rate-percentage unchanged in case it has to cap +stream rates. Get value is only valid if the rate was last set using this +command. + +Corresponding CLI command: ``PS_RATEFRACTION`` .. code-block:: python - await stream.rate.fraction.set() - await stream.rate.fraction.get() + # Rate Fraction + await stream.rate.fraction.set(stream_rate_ppm=1_000_000) + + resp = await stream.rate.fraction.get() + resp.stream_rate_ppm Packet Rate ------------------------- +The rate of the traffic transmitted for a stream expressed in packets per +second. The bandwidth consumption is heavily dependent on the length of the +packets generated for the stream, and also on the inter-frame gap for the port. +The sum of the bandwidth consumption for all the enabled streams must not exceed +the effective rate for the port. Setting this command also instructs the +Manager to attempt to keep the packets-per-second unchanged in case it has to +cap stream rates. Get value is only valid if the rate was the last set using +this command. + +Corresponding CLI command: ``PS_RATEPPS`` .. code-block:: python - await stream.rate.pps.set() - await stream.rate.pps.get() + a# Packet Rate + await stream.rate.pps.set(stream_rate_pps=1_000) + + resp = await stream.rate.pps.get() + resp.stream_rate_pps Bit Rate L2 -------------------------- +The rate of the traffic transmitted for a stream, expressed in units of bits- +per-second at layer-2, thus including the Ethernet header but excluding the +inter-frame gap. The bandwidth consumption is somewhat dependent on the length +of the packets generated for the stream, and also on the inter-frame gap for the +port. The sum of the bandwidth consumption for all the enabled streams must not +exceed the effective rate for the port. Setting this command also instructs +the Manager to attempt to keep the layer-2 bps rate unchanged in case it has to +cap stream rates. Get value is only valid if the rate was the last set using +this command. + +Corresponding CLI command: ``PS_RATEL2BPS`` .. code-block:: python - await stream.rate.l2bps.set() - await stream.rate.l2bps.get() - + # Bit Rate L2 + await stream.rate.l2bps.set(l2_bps=1_000_000) + + resp = await stream.rate.l2bps.get() + resp.l2_bps Packet Limit -------------------------- +The rate of the traffic transmitted for a stream expressed in packets per +second. The bandwidth consumption is heavily dependent on the length of the +packets generated for the stream, and also on the inter-frame gap for the port. +The sum of the bandwidth consumption for all the enabled streams must not exceed +the effective rate for the port. Setting this command also instructs the +Manager to attempt to keep the packets-per-second unchanged in case it has to +cap stream rates. Get value is only valid if the rate was the last set using +this command. + +Corresponding CLI command: ``PS_RATEPPS`` .. code-block:: python - await stream.packet.limit.set() - await stream.packet.limit.get() + # Packet Limit + await stream.packet.limit.set(packet_count=1_000) + + resp = await stream.packet.limit.get() + resp.packet_count Burst Size and Density -------------------------- +The burstiness of the traffic transmitted for a stream, expressed in terms of +the number of packets in each burst, and how densely they are packed together. +The burstiness does not affect the bandwidth consumed by the stream, only the +spacing between the packets. A density value of 100 means that the packets are +packed tightly together, only spaced by the minimum inter-frame gap. A value of +0 means even, non-bursty, spacing. The exact spacing achieved depends on the +other enabled streams of the port. + +Corresponding CLI command: ``PS_BURST`` .. code-block:: python - await stream.burst.burstiness.set() - await stream.burst.burstiness.get() + # Burst Size and Density + await stream.burst.burstiness.set(size=20, density=80) + + resp = await stream.burst.burstiness.get() + resp.size + resp.density Inter Burst/Packet Gap -------------------------- +When the port is in in Burst TX mode, this command defines the gap between packets in a burst +(inter-packet gap) and the gap after a burst defined in one stream stops until a +burst defined in the next stream starts (inter-burst gap). + +Corresponding CLI command: ``PS_BURSTGAP`` .. code-block:: python - await stream.burst.gap.set() - await stream.burst.gap.get() + # Inter Burst/Packet Gap + await stream.burst.gap.set(inter_packet_gap=30, inter_burst_gap=30) + + resp = await stream.burst.gap.get() + resp.inter_packet_gap + resp.inter_burst_gap Priority Flow -------------------------- +Set and get the Priority Flow Control (PFC) Cos value of a stream. + +Corresponding CLI command: ``PS_PFCPRIORITY`` .. code-block:: python - await stream.priority_flow.set() - await stream.priority_flow.get() + # Priority Flow + await stream.priority_flow.set(cos=enums.PFCMode.ZERO) + await stream.priority_flow.set(cos=enums.PFCMode.ONE) + await stream.priority_flow.set(cos=enums.PFCMode.TWO) + await stream.priority_flow.set(cos=enums.PFCMode.THREE) + await stream.priority_flow.set(cos=enums.PFCMode.FOUR) + await stream.priority_flow.set(cos=enums.PFCMode.FIVE) + await stream.priority_flow.set(cos=enums.PFCMode.SIX) + await stream.priority_flow.set(cos=enums.PFCMode.SEVEN) + await stream.priority_flow.set(cos=enums.PFCMode.VLAN_PCP) + + resp = await stream.priority_flow.get() + resp.cos diff --git a/docs/source/api_ref/hlapiv1/summary.py b/docs/source/api_ref/hlapiv1/summary.py index e545525a..3c209da0 100644 --- a/docs/source/api_ref/hlapiv1/summary.py +++ b/docs/source/api_ref/hlapiv1/summary.py @@ -505,6 +505,7 @@ async def my_awesome_func(stop_event: asyncio.Event): if isinstance(module, modules.ModuleChimera): resp = await module.tx_clock.status.get() resp.status + # endregion # region Port @@ -1187,10 +1188,13 @@ async def my_awesome_func(stop_event: asyncio.Event): resp.rx_loss_lane_3 # Transceiver Read & Write - await port.transceiver.access_rw(page_address=0, register_address=0).set(value=Hex("00")) + my_int = 1234 + await port.transceiver.access_rw(page_address=0, register_address=0).set(value=hex(my_int)[2:]) resp = await port.transceiver.access_rw(page_address=0, register_address=0).get() resp.value + my_int_resp = int(resp.value, 16) + print(f"Returned value: {my_int_resp}") # Transceiver Sequential Read & Write await port.transceiver.access_rw_seq(page_address=0, register_address=0, byte_count=4).set(value=Hex("00FF00FF")) @@ -1324,6 +1328,10 @@ async def my_awesome_func(stop_event: asyncio.Event): resp = await port.dynamic.get() resp.on_off + await port.uat.mode.set(mode=enums.OnOff.ON, delay=500) + await port.uat.mode.set(mode=enums.OnOff.OFF, delay=500) + await port.uat.frame_loss_ratio.get() + ################################################# # Port Filter # ################################################# @@ -1543,9 +1551,8 @@ async def my_awesome_func(stop_event: asyncio.Event): # RX Status - RX FEC Stats resp = await port.pcs_pma.rx.fec_status.get() resp.stats_type - resp.value_count - resp.correction_stats - resp.rx_uncorrectable_code_word_count + resp.data_count + resp.stats # RX Status - RX Total Stats resp = await port.pcs_pma.rx.total_status.get() @@ -1671,10 +1678,10 @@ async def my_awesome_func(stop_event: asyncio.Event): await port.serdes[0].phy.tx_equalizer.set(pre2=0, pre1=0, main=86, post1=0, post2=0, post3=0) resp = await port.serdes[0].phy.tx_equalizer.get() resp.pre2 - resp.pre1 + resp.pre resp.main - resp.post1 - resp.post2 + resp.post + resp.pre3_post2 resp.post3 # RX Tap Configuration @@ -1751,6 +1758,7 @@ async def my_awesome_func(stop_event: asyncio.Event): resp.invert resp.statistics_mode + # PRBS Statistics resp = await port.serdes[0].prbs.status.get() resp.byte_count @@ -2457,13 +2465,16 @@ async def my_awesome_func(stop_event: asyncio.Event): if isinstance(filter, misc.ExtendedImpairmentFlowFilter): await filter.use_segments( - enums.ProtocolOption.VLAN) + enums.ProtocolOption.VLAN + ) protocol_segments = await filter.get_protocol_segments() await protocol_segments[0].value.set(value=Hex("AAAAAAAAAAAABBBBBBBBBBBB8100")) await protocol_segments[0].mask.set(masks=Hex("0000000000000000000000000000")) await protocol_segments[1].value.set(value=Hex("0064FFFF")) await protocol_segments[1].mask.set(masks=Hex("00000000")) + await protocol_segments[1].get() + # Configure impairment - Drop # Fixed Burst distribution for impairment Drop await utils.apply( @@ -2523,7 +2534,7 @@ async def my_awesome_func(stop_event: asyncio.Event): # Poisson distribution for impairment Drop await utils.apply( - flow.impairment_distribution.drop_type_config.poison.set(mean=9), + flow.impairment_distribution.drop_type_config.poisson.set(mean=9), flow.impairment_distribution.drop_type_config.schedule.set(duration=1, period=1), # repeat pattern flow.impairment_distribution.drop_type_config.schedule.set(duration=0, period=0), #continuous ) @@ -2592,6 +2603,7 @@ async def my_awesome_func(stop_event: asyncio.Event): flow.impairment_distribution.latency_jitter_type_config.step.set(low=1300, high=77000), flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous ) + await flow.impairment_distribution.corruption_type_config.off.set() # Uniform distribution for impairment Latency & Jitter await utils.apply( @@ -2605,9 +2617,13 @@ async def my_awesome_func(stop_event: asyncio.Event): flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous ) + resp = await flow.latency_range.get() + resp. + + # Poisson distribution for impairment Latency & Jitter await utils.apply( - flow.impairment_distribution.latency_jitter_type_config.poison.set(mean=1), + flow.impairment_distribution.latency_jitter_type_config.poisson.set(mean=1), flow.impairment_distribution.latency_jitter_type_config.schedule.set(duration=0, period=0), #continuous ) @@ -2692,7 +2708,7 @@ async def my_awesome_func(stop_event: asyncio.Event): # Poisson distribution for impairment Duplication await utils.apply( - flow.impairment_distribution.duplication_type_config.poison.set(mean=9), + flow.impairment_distribution.duplication_type_config.poisson.set(mean=9), flow.impairment_distribution.duplication_type_config.schedule.set(duration=1, period=1), # repeat pattern flow.impairment_distribution.duplication_type_config.schedule.set(duration=0, period=0), #continuous ) @@ -2727,7 +2743,6 @@ async def my_awesome_func(stop_event: asyncio.Event): flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), #repeat (duration = 1, period = x) flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=0), #one shot ) - # Random Burst distribution for impairment Corruption await utils.apply( flow.impairment_distribution.corruption_type_config.random_burst.set(minimum=1, maximum=1, probability=10_0000), @@ -2779,7 +2794,7 @@ async def my_awesome_func(stop_event: asyncio.Event): # Poisson distribution for impairment Corruption await utils.apply( - flow.impairment_distribution.corruption_type_config.poison.set(mean=9), + flow.impairment_distribution.corruption_type_config.poisson.set(mean=9), flow.impairment_distribution.corruption_type_config.schedule.set(duration=1, period=1), # repeat pattern flow.impairment_distribution.corruption_type_config.schedule.set(duration=0, period=0), #continuous ) @@ -2804,6 +2819,7 @@ async def my_awesome_func(stop_event: asyncio.Event): ) # Set distribution and start impairment Corruption + await flow.corruption.set(corruption_type=enums.CorruptionType.OFF) await flow.corruption.set(corruption_type=enums.CorruptionType.ETH) await flow.corruption.set(corruption_type=enums.CorruptionType.IP) await flow.corruption.set(corruption_type=enums.CorruptionType.TCP) @@ -2812,6 +2828,10 @@ async def my_awesome_func(stop_event: asyncio.Event): await flow.impairment_distribution.corruption_type_config.enable.set_on() await flow.impairment_distribution.corruption_type_config.enable.set_off() + await flow.impairment_distribution.corruption_type_config.enable.set_on() + + resp = await flow.impairment_distribution.corruption_type_config.one_shot_status.get() + resp.one_shot_status # Configure bandwidth control - Policer diff --git a/docs/source/api_ref/hlapiv1/tester/action.rst b/docs/source/api_ref/hlapiv1/tester/action.rst index a24c6d5c..7516aa8c 100644 --- a/docs/source/api_ref/hlapiv1/tester/action.rst +++ b/docs/source/api_ref/hlapiv1/tester/action.rst @@ -3,25 +3,51 @@ Action Shutdown/Restart ---------------- +Shuts down the chassis, and either restarts it in a clean state or leaves it powered off. + +Corresponding CLI command: ``C_DOWN`` .. code-block:: python - await tester.down.set_restart() + # Shutdown/Restart + await tester.down.set(operation=enums.ChassisShutdownAction.POWER_OFF) await tester.down.set_poweroff() + await tester.down.set(operation=enums.ChassisShutdownAction.RESTART) + await tester.down.set_restart() Flash ---------- +Make all the test port LEDs flash on and off with a 1-second interval. This is +helpful if you have multiple chassis mounted side by side and you need to +identify a specific one. + +Corresponding CLI command: ``C_FLASH`` + +.. note:: + + Require Tester to be reserved before change value. .. code-block:: python + # Flash + await tester.flash.set(on_off=enums.OnOff.OFF) await tester.flash.set_off() + await tester.flash.set(on_off=enums.OnOff.ON) await tester.flash.set_on() - await tester.flash.get() + + resp = await tester.flash.get() + resp.on_off Debug Log ---------- +Allows to dump all the logs of a chassis. + +Corresponding CLI command: ``C_DEBUGLOGS`` .. code-block:: python - await tester.debug_log.get() + # Debug Log + resp = await tester.debug_log.get() + resp.data + resp.message_length diff --git a/docs/source/api_ref/hlapiv1/tester/address.rst b/docs/source/api_ref/hlapiv1/tester/address.rst index 2133eeac..747c5c99 100644 --- a/docs/source/api_ref/hlapiv1/tester/address.rst +++ b/docs/source/api_ref/hlapiv1/tester/address.rst @@ -3,37 +3,66 @@ Management Address IP Address ----------- +The network configuration parameters of the chassis management port. + +Corresponding CLI command: ``C_IPADDRESS`` .. code-block:: python + import ipaddress + + # IP Address await tester.management_interface.ip_address.set( ipv4_address=ipaddress.IPv4Address("10.10.10.10"), subnet_mask=ipaddress.IPv4Address("255.255.255.0"), gateway=ipaddress.IPv4Address("10.10.10.1")) - await tester.management_interface.ip_address.get() + + resp = await tester.management_interface.ip_address.get() + resp.ipv4_address + resp.subnet_mask + resp.gateway + MAC Address ----------- +Get the MAC address for the chassis management port. + +Corresponding CLI command: ``C_MACADDRESS`` .. code-block:: python - await tester.management_interface.macaddress.get() + # MAC Address + resp = await tester.management_interface.macaddress.get() + resp.mac_address Hostname ---------- +Get or set the chassis hostname used when DHCP is enabled. + +Corresponding CLI command: ``C_HOSTNAME`` .. code-block:: python + # Hostname await tester.management_interface.hostname.set(hostname="name") - await tester.management_interface.hostname.get() + + resp = await tester.management_interface.hostname.get() + resp.hostname DHCP ---------- +Controls whether the chassis will use DHCP to get the management IP address. +Corresponding CLI command: ``C_DHCP`` .. code-block:: python + # DHCP + await tester.management_interface.dhcp.set(on_off=enums.OnOff.ON) await tester.management_interface.dhcp.set_on() + await tester.management_interface.dhcp.set(on_off=enums.OnOff.OFF) await tester.management_interface.dhcp.set_off() - await tester.management_interface.dhcp.get() \ No newline at end of file + + resp = await tester.management_interface.dhcp.get() + resp.on_off \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/tester/capabilities.rst b/docs/source/api_ref/hlapiv1/tester/capabilities.rst index aee08bb8..14bd2577 100644 --- a/docs/source/api_ref/hlapiv1/tester/capabilities.rst +++ b/docs/source/api_ref/hlapiv1/tester/capabilities.rst @@ -1,6 +1,28 @@ Capabilities ========================= +A series of integer values specifying various internal limits (aka. capabilities) of the chassis. + +Corresponding CLI command: ``C_CAPABILITIES`` .. code-block:: python - await tester.capabilities.get() \ No newline at end of file + # Capabilities + resp = await tester.capabilities.get() + resp.version + resp.max_name_len + resp.max_comment_len + resp.max_password_len + resp.max_ext_rate + resp.max_session_count + resp.max_chain_depth + resp.max_module_count + resp.max_protocol_count + resp.can_stream_based_arp + resp.can_sync_traffic_start + resp.can_read_log_files + resp.can_par_module_upgrade + resp.can_upgrade_timekeeper + resp.can_custom_defaults + resp.max_owner_name_length + resp.can_read_temperatures + resp.can_latency_f2f \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/tester/identification.rst b/docs/source/api_ref/hlapiv1/tester/identification.rst index 3ed9aa9a..3698ed4d 100644 --- a/docs/source/api_ref/hlapiv1/tester/identification.rst +++ b/docs/source/api_ref/hlapiv1/tester/identification.rst @@ -3,53 +3,100 @@ Identification Name ---------- +The name of the chassis, as it appears at various places in the user interface. +The name is also used to distinguish the various chassis contained within a +testbed and in files containing the configuration for an entire test case. + +Corresponding CLI command: ``C_NAME`` .. code-block:: python + # Name await tester.name.set(chassis_name="name") - await tester.name.get() + + resp = await tester.name.get() + resp.chassis_name Password ---------- +The password of the chassis, which must be provided when logging on to the chassis. + +Corresponding CLI command: ``C_PASSWORD`` .. code-block:: python + # Password await tester.password.set(password="xena") - await tester.password.get() + + resp = await tester.password.get() + resp.password Description ----------- +The description of the chassis. + +Corresponding CLI command: ``C_COMMENT`` .. code-block:: python + # Description await tester.comment.set(comment="description") - await tester.comment.get() + + resp = await tester.comment.get() + resp.comment Model ----------- +Gets the specific model of this Xena chassis. + +Corresponding CLI command: ``C_MODEL`` .. code-block:: python - await tester.model.get() + # Model + resp = await tester.model.get() + resp.model Serial Number ------------- +Gets the unique serial number of this particular Xena chassis. + +Corresponding CLI command: ``C_SERIALNO`` .. code-block:: python - await tester.serial_no.get() + # Serial Number + resp = await tester.serial_no.get() + resp.serial_number -Firmeware Version +Firmware Version ----------------- +Gets the major version numbers for the chassis firmware and the Xena PCI +driver installed on the chassis. + +Corresponding CLI command: ``C_VERSIONNO`` .. code-block:: python - await tester.version_no.get() - await tester.version_no_minor.get() + # Firmware Version + resp = await tester.version_no.get() + resp.chassis_major_version + resp.pci_driver_version + + resp = await tester.version_no_minor.get() + resp.chassis_minor_version + resp.reserved_1 + resp.reserved_2 Build String ------------ +Identify the hostname of the PC that builds the xenaserver. It uniquely +identifies the build of a xenaserver. + +Corresponding CLI command: ``C_BUILDSTRING`` .. code-block:: python - await tester.build_string.get() \ No newline at end of file + # Build String + resp = await tester.build_string.get() + resp.build_string \ No newline at end of file diff --git a/docs/source/api_ref/hlapiv1/tester/reservation.rst b/docs/source/api_ref/hlapiv1/tester/reservation.rst index bb5ed6e5..12d782eb 100644 --- a/docs/source/api_ref/hlapiv1/tester/reservation.rst +++ b/docs/source/api_ref/hlapiv1/tester/reservation.rst @@ -1,21 +1,41 @@ Reservation ========================= -Action ------------ +Reservation Action +------------------- +You set this command to reserve, release, or relinquish the chassis itself. +The chassis must be reserved before any of the chassis-level parameters can be +changed. The owner of the session must already have been specified. +Reservation will fail if any modules or ports are reserved for other users. + +.. note:: + + Before reserve Tester need to reserve all the ports on it, otherwise ```` + +Corresponding CLI command: ``C_RESERVATION`` .. code-block:: python + # Reservation + await tester.reservation.set(operation=enums.ReservedAction.RELEASE) await tester.reservation.set_release() + await tester.reservation.set(operation=enums.ReservedAction.RELINQUISH) await tester.reservation.set_relinquish() + await tester.reservation.set(operation=enums.ReservedAction.RESERVE) await tester.reservation.set_reserve() - await tester.reservation.get() - tester.on_reservation_change(_callback_func()) + + resp = await tester.reservation.get() + resp.operation Reserved By ----------- +Identify the user who has the chassis reserved. The empty string if the chassis +is not currently reserved. + +Corresponding CLI command: ``C_RESERVEDBY`` .. code-block:: python - await tester.reserved_by.get() - tester.on_reserved_by_change(_callback_func()) + # Reserved By + resp = await tester.reserved_by.get() + resp.username diff --git a/docs/source/api_ref/hlapiv1/tester/session.rst b/docs/source/api_ref/hlapiv1/tester/session.rst index 2382f3a8..c38a3f58 100644 --- a/docs/source/api_ref/hlapiv1/tester/session.rst +++ b/docs/source/api_ref/hlapiv1/tester/session.rst @@ -4,6 +4,8 @@ Session Information ----------- +The following are pre-fetched in cache when connection is established, thus no need to use ``await``. + .. code-block:: python tester.session.owner_name @@ -17,6 +19,10 @@ Information Logoff ---------- +Terminates the current session. Courtesy only, the chassis will also +handle disconnection at the TCP/IP level. + +Corresponding CLI command: ``C_LOGOFF`` .. code-block:: python diff --git a/docs/source/api_ref/hlapiv1/tester/time.rst b/docs/source/api_ref/hlapiv1/tester/time.rst index ae4a41e1..0c621c47 100644 --- a/docs/source/api_ref/hlapiv1/tester/time.rst +++ b/docs/source/api_ref/hlapiv1/tester/time.rst @@ -3,49 +3,85 @@ Time and Timekeeper Time ---------------- +Get local chassis time in seconds. + +Corresponding CLI command: ``C_TIME`` .. code-block:: python - await tester.time.get() + # Time + resp = await tester.time.get() + resp.local_time TimeKeeper Configuration ---------------------------- +TimeKeeper config file content. + +Corresponding CLI command: ``C_TKCONFIG`` .. code-block:: python + # TimeKeeper Configuration await tester.time_keeper.config_file.set(config_file="filename") - await tester.time_keeper.config_file.get() + + resp = await tester.time_keeper.config_file.get() + resp.config_file TimeKeeper GPS State ---------------------------- +Get TimeKeeper GPS status. + +Corresponding CLI command: ``C_TKGPSSTATE`` .. code-block:: python - await tester.time_keeper.gps_state.get() + # TimeKeeper GPS State + resp = await tester.time_keeper.gps_state.get() + resp.status TimeKeeper License File ---------------------------- +TimeKeeper license file content. + +Corresponding CLI command: ``C_TKLICFILE`` .. code-block:: python + # TimeKeeper License File await tester.time_keeper.license_file.set(license_content="") - await tester.time_keeper.license_file.get() + + resp = await tester.time_keeper.license_file.get() + resp.license_content TimeKeeper License State ---------------------------- +State of TimeKeeper license file content. + +Corresponding CLI command: ``C_TKLICSTATE`` .. code-block:: python - await tester.time_keeper.license_state.get() + # TimeKeeper License State + resp = await tester.time_keeper.license_state.get() + resp.license_errors + resp.license_file_state + resp.license_type TimeKeeper Status ---------------------------- +Version and status of TimeKeeper. + +Corresponding CLI command: ``C_TKSTATUS`` .. code-block:: python - await tester.time_keeper.status.get() - await tester.time_keeper.status_extended.get() + # TimeKeeper Status + resp = await tester.time_keeper.status.get() + resp.status_string + + resp = await tester.time_keeper.status_extended.get() + resp.status_string diff --git a/docs/source/api_ref/hlapiv1/tester/traffic.rst b/docs/source/api_ref/hlapiv1/tester/traffic.rst index 9c122b87..ce6c493a 100644 --- a/docs/source/api_ref/hlapiv1/tester/traffic.rst +++ b/docs/source/api_ref/hlapiv1/tester/traffic.rst @@ -3,9 +3,14 @@ Traffic Control Chassis Traffic ---------------- +Starts or stops the traffic on a number of ports on the chassis simultaneously. +The ports are identified by pairs of integers (module port). + +Corresponding CLI command: ``C_TRAFFIC`` .. code-block:: python + # Chassis Traffic await tester.traffic.set(on_off=enums.OnOff.ON, module_ports=[0,0,0,1]) await tester.traffic.set(on_off=enums.OnOff.OFF, module_ports=[0,0,0,1]) await tester.traffic.set_on(module_ports=[0,0,0,1]) @@ -13,9 +18,20 @@ Chassis Traffic Synchronized Chassis Traffic ---------------------------- +Works just as the ``C_TRAFFIC`` command described above with an additional option to +specify a point in time where traffic should be started. This can be used to +start traffic simultaneously on multiple chassis. The ports are identified by +pairs of integers (module port). + +.. note:: + + This requires that the chassis in question all use the TimeKeeper option to keep their CPU clocks synchronized. + +Corresponding CLI command: ``C_TRAFFICSYNC`` .. code-block:: python + # Synchronized Chassis Traffic await tester.traffic_sync.set(on_off=enums.OnOff.ON, timestamp=1234567, module_ports=[0,0,0,1]) await tester.traffic_sync.set(on_off=enums.OnOff.OFF, timestamp=1234567, module_ports=[0,0,0,1]) await tester.traffic_sync.set_on(timestamp=1234567, module_ports=[0,0,0,1]) From b3bf5e0946b49dd218f1057c150cf08426f74c86 Mon Sep 17 00:00:00 2001 From: Leonard Yu Date: Sat, 11 Nov 2023 22:38:52 +0700 Subject: [PATCH 15/15] Fix doc build issue --- .../api_ref/hlapiv1/port/tx_profile.rst | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/docs/source/api_ref/hlapiv1/port/tx_profile.rst b/docs/source/api_ref/hlapiv1/port/tx_profile.rst index a774185d..73c6a94b 100644 --- a/docs/source/api_ref/hlapiv1/port/tx_profile.rst +++ b/docs/source/api_ref/hlapiv1/port/tx_profile.rst @@ -37,24 +37,15 @@ TX Mode The scheduling mode for outgoing traffic from the port, specifying how multiple logical streams are merged onto one physical port. There are four primary modes: -* Normal Interleaved: The streams are treated independently, and are merged into a -combined traffic pattern for the port, which honors each stream's ideal packet -placements as well as possible. This is the default mode. -* Strict Uniform: This is a slight variation of normal interleaved scheduling, which emphasizes strict -uniformity of the inter-packet-gaps as more important than hitting the stream -rates absolutely precisely. -* Sequential: Each stream in turn contribute one or -more packets, before continuing to the next stream, in a cyclical pattern. The -count of packets for each stream is obtained from the PS_PACKETLIMIT command -value for the stream. The individual rates for each stream are ignored, and -instead the overall rate is determined at the port-level. This in turn determines -the rates for each stream, taking into account their packet lengths and counts. -The maximum number of packets in a cycle (i.e. the sum of PS_PACKETLIMIT for all -enabled streams) is 500. If the packet number is larger than 500, will be returned -when attempting to start the traffic (P_TRAFFIC ON). +* Normal Interleaved: The streams are treated independently, and are merged into a combined traffic pattern for the port, which honors each stream's ideal packet placements as well as possible. This is the default mode. + +* Strict Uniform: This is a slight variation of normal interleaved scheduling, which emphasizes strict uniformity of the inter-packet-gaps as more important than hitting the stream rates absolutely precisely. + +* Sequential: Each stream in turn contribute one or more packets, before continuing to the next stream, in a cyclical pattern. The count of packets for each stream is obtained from the PS_PACKETLIMIT command value for the stream. The individual rates for each stream are ignored, and instead the overall rate is determined at the port-level. This in turn determines the rates for each stream, taking into account their packet lengths and counts. The maximum number of packets in a cycle (i.e. the sum of PS_PACKETLIMIT for all enabled streams) is 500. If the packet number is larger than 500, will be returned when attempting to start the traffic (P_TRAFFIC ON). + * Burst: When this mode is selected, frames from the streams on a port are sent as bursts as depicted below: - * The Burst Period is defined in the P_TXBURSTPERIOD command. - * For the individual streams the number of packets in a burst is defined by the PS_BURST command, while the Inter Packet Gap and the Inter Burst Gap are defined by the PS_BURSTGAP command. + * The Burst Period is defined in the P_TXBURSTPERIOD command. + * For the individual streams the number of packets in a burst is defined by the PS_BURST command, while the Inter Packet Gap and the Inter Burst Gap are defined by the PS_BURSTGAP command. Corresponding CLI command: ``P_TXMODE``