tdl-xoa-driver 1.5.1__py3-none-any.whl → 1.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tdl_xoa_driver-1.5.1.dist-info → tdl_xoa_driver-1.6.0.dist-info}/METADATA +1 -1
- {tdl_xoa_driver-1.5.1.dist-info → tdl_xoa_driver-1.6.0.dist-info}/RECORD +89 -88
- xoa_driver/__init__.py +2 -2
- xoa_driver/enums.py +10 -10
- xoa_driver/functions/anlt.py +60 -78
- xoa_driver/functions/cli/testbed_config.py +1 -1
- xoa_driver/functions/cmis/_replies.py +4 -4
- xoa_driver/functions/mgmt.py +206 -250
- xoa_driver/functions/tools.py +11 -6
- xoa_driver/internals/commands/c_commands.py +59 -0
- xoa_driver/internals/commands/enums.py +101 -90
- xoa_driver/internals/commands/m4_commands.py +25 -0
- xoa_driver/internals/commands/m4e_commands.py +6 -0
- xoa_driver/internals/commands/m_commands.py +51 -1
- xoa_driver/internals/commands/p4_commands.py +63 -1
- xoa_driver/internals/commands/p4e_commands.py +9 -0
- xoa_driver/internals/commands/p4g_commands.py +139 -0
- xoa_driver/internals/commands/p_commands.py +455 -61
- xoa_driver/internals/commands/pc_commands.py +9 -0
- xoa_driver/internals/commands/pd_commands.py +11 -0
- xoa_driver/internals/commands/pe_commands.py +27 -0
- xoa_driver/internals/commands/pec_commands.py +9 -0
- xoa_driver/internals/commands/ped_commands.py +23 -0
- xoa_driver/internals/commands/pef_commands.py +43 -0
- xoa_driver/internals/commands/pf_commands.py +11 -0
- xoa_driver/internals/commands/pl1_commands.py +315 -48
- xoa_driver/internals/commands/pl_commands.py +8 -0
- xoa_driver/internals/commands/pm_commands.py +11 -0
- xoa_driver/internals/commands/pp_commands.py +84 -27
- xoa_driver/internals/commands/pr_commands.py +25 -0
- xoa_driver/internals/commands/ps_commands.py +47 -1
- xoa_driver/internals/commands/pt_commands.py +15 -0
- xoa_driver/internals/commands/px_commands.py +180 -136
- xoa_driver/internals/commands/subtypes.py +4 -3
- xoa_driver/internals/core/transporter/protocol/payload/base_struct.py +1 -1
- xoa_driver/internals/hli/indices/macsecscs/base_macsecsc.py +41 -3
- xoa_driver/internals/hli/modules/modules_l23/family_combi.py +0 -64
- xoa_driver/internals/hli/modules/modules_l23/family_edun.py +0 -2
- xoa_driver/internals/hli/modules/modules_l23/{family_g.py → family_loki.py} +29 -1
- xoa_driver/internals/hli/modules/modules_l23/family_odin.py +412 -0
- xoa_driver/internals/hli/modules/modules_l23/{family_l.py → family_thor.py} +44 -0
- xoa_driver/internals/hli/ports/port_l23/chimera/port_chimera.py +3 -3
- xoa_driver/internals/hli/ports/port_l23/family_edun.py +9 -44
- xoa_driver/internals/hli/ports/port_l23/{family_l1.py → family_freya.py} +10 -45
- xoa_driver/internals/hli/ports/port_l23/{family_g.py → family_loki.py} +33 -32
- xoa_driver/internals/hli/ports/port_l23/family_odin.py +225 -0
- xoa_driver/internals/hli/ports/port_l23/family_thor.py +67 -0
- xoa_driver/internals/hli/ports/port_l23/layer1/anlt.py +512 -0
- xoa_driver/internals/hli/ports/port_l23/layer1/brr.py +26 -0
- xoa_driver/internals/hli/ports/port_l23/layer1/eye_diagram.py +71 -0
- xoa_driver/internals/hli/ports/port_l23/{pcs_pma_ijkl_chimera.py → layer1/impair.py} +7 -7
- xoa_driver/internals/hli/ports/port_l23/layer1/laser_power.py +28 -0
- xoa_driver/internals/hli/ports/port_l23/{family_e.py → layer1/lower_power.py} +1 -51
- xoa_driver/internals/hli/ports/port_l23/{freya_l1.py → layer1/medium.py} +38 -358
- xoa_driver/internals/hli/ports/port_l23/layer1/pcs_fec.py +219 -0
- xoa_driver/internals/hli/ports/port_l23/layer1/pma.py +43 -0
- xoa_driver/internals/hli/ports/port_l23/layer1/prbs.py +39 -0
- xoa_driver/internals/hli/ports/port_l23/layer1/preamble.py +25 -0
- xoa_driver/internals/hli/ports/port_l23/{fault_jkl.py → layer1/rs_fault.py} +2 -2
- xoa_driver/internals/hli/ports/port_l23/layer1/siv.py +69 -0
- xoa_driver/internals/hli/ports/port_l23/layer1_edun.py +103 -0
- xoa_driver/internals/hli/ports/port_l23/layer1_freya.py +103 -0
- xoa_driver/internals/hli/ports/port_l23/layer1_loki.py +74 -0
- xoa_driver/internals/hli/ports/port_l23/layer1_thor.py +70 -0
- xoa_driver/internals/hli/ports/port_l23/port_l23ve.py +4 -4
- xoa_driver/internals/hli/ports/port_l23/sec/__init__.py +0 -0
- xoa_driver/internals/hli/ports/port_l23/sec/macsec.py +108 -0
- xoa_driver/internals/hli/ports/port_l23/tcvr/__init__.py +0 -0
- xoa_driver/internals/hli/ports/port_l23/{bases/port_transceiver.py → tcvr/cmis.py} +4 -118
- xoa_driver/internals/hli/ports/port_l23/tcvr/transceiver.py +124 -0
- xoa_driver/internals/hli/ports/port_l23/trafficgen/__init__.py +0 -0
- xoa_driver/internals/hli/ports/port_l23/{bases → trafficgen}/port_l23.py +1 -1
- xoa_driver/internals/hli/ports/port_l23/{bases → trafficgen}/port_l23_genuine.py +5 -45
- xoa_driver/internals/hli/ports/port_l23/{bases/port_reception_statistics.py → trafficgen/port_rx_stats.py} +0 -21
- xoa_driver/internals/hli/ports/port_l23/{bases/port_transmission_statistics.py → trafficgen/port_tx_stats.py} +2 -22
- xoa_driver/internals/hli/ports/port_l23/trafficgen/runt.py +32 -0
- xoa_driver/internals/hli/testers/l23_tester.py +1 -3
- xoa_driver/internals/utils/indices/_interfaces.py +18 -6
- xoa_driver/internals/utils/indices/index_manager.py +8 -2
- xoa_driver/internals/utils/managers/ports_manager.py +5 -2
- xoa_driver/misc.py +6 -6
- xoa_driver/modules.py +31 -47
- xoa_driver/ports.py +10 -29
- xoa_driver/internals/hli/modules/modules_l23/family_d.py +0 -75
- xoa_driver/internals/hli/modules/modules_l23/family_e.py +0 -85
- xoa_driver/internals/hli/modules/modules_l23/family_f.py +0 -145
- xoa_driver/internals/hli/modules/modules_l23/family_h.py +0 -40
- xoa_driver/internals/hli/modules/modules_l23/family_i.py +0 -25
- xoa_driver/internals/hli/modules/modules_l23/family_j.py +0 -25
- xoa_driver/internals/hli/modules/modules_l23/family_k.py +0 -39
- xoa_driver/internals/hli/modules/modules_l23/family_m.py +0 -25
- xoa_driver/internals/hli/modules/modules_l23/family_n.py +0 -40
- xoa_driver/internals/hli/ports/port_l23/edun_l1.py +0 -181
- xoa_driver/internals/hli/ports/port_l23/family_combi.py +0 -37
- xoa_driver/internals/hli/ports/port_l23/family_d.py +0 -51
- xoa_driver/internals/hli/ports/port_l23/family_f.py +0 -151
- xoa_driver/internals/hli/ports/port_l23/family_h.py +0 -67
- xoa_driver/internals/hli/ports/port_l23/family_i.py +0 -84
- xoa_driver/internals/hli/ports/port_l23/family_j.py +0 -68
- xoa_driver/internals/hli/ports/port_l23/family_k.py +0 -73
- xoa_driver/internals/hli/ports/port_l23/family_l.py +0 -82
- xoa_driver/internals/hli/ports/port_l23/family_m.py +0 -29
- xoa_driver/internals/hli/ports/port_l23/pcs_pma_ghijkl.py +0 -369
- xoa_driver/internals/hli/ports/port_l23/pcs_pma_l.py +0 -78
- {tdl_xoa_driver-1.5.1.dist-info → tdl_xoa_driver-1.6.0.dist-info}/WHEEL +0 -0
- {tdl_xoa_driver-1.5.1.dist-info → tdl_xoa_driver-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {tdl_xoa_driver-1.5.1.dist-info → tdl_xoa_driver-1.6.0.dist-info}/top_level.txt +0 -0
- /xoa_driver/internals/hli/modules/modules_l23/{family_l1.py → family_freya.py} +0 -0
- /xoa_driver/internals/hli/ports/port_l23/{bases → layer1}/__init__.py +0 -0
- /xoa_driver/internals/hli/ports/port_l23/{bases → trafficgen}/port_capture.py +0 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
TYPE_CHECKING,
|
|
3
|
+
Tuple,
|
|
4
|
+
)
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from xoa_driver.internals.core import interfaces as itf
|
|
7
|
+
from xoa_driver.internals.commands import (
|
|
8
|
+
PP_AUTONEG,
|
|
9
|
+
PP_AUTONEGSTATUS,
|
|
10
|
+
PP_LINKTRAIN,
|
|
11
|
+
PL1_AUTONEGINFO,
|
|
12
|
+
PL1_LINKTRAININFO,
|
|
13
|
+
PL1_LOG,
|
|
14
|
+
PL1_CFG_TMP,
|
|
15
|
+
PL1_LINKTRAIN_CMD,
|
|
16
|
+
PL1_AUTONEG_STATUS,
|
|
17
|
+
PL1_AUTONEG_ABILITIES,
|
|
18
|
+
PL1_AUTONEG_CONFIG,
|
|
19
|
+
PL1_ANLT,
|
|
20
|
+
PL1_LINKTRAIN_CONFIG,
|
|
21
|
+
PL1_LINKTRAIN_STATUS,
|
|
22
|
+
PL1_LT_PHYTXEQ_RANGE,
|
|
23
|
+
PL1_LT_PHYTXEQ_RANGE_COEFF,
|
|
24
|
+
PL1_PRESET_CONFIG,
|
|
25
|
+
PL1_PRESET_CONFIG_COEFF,
|
|
26
|
+
PL1_PRESET_CONFIG_LEVEL,
|
|
27
|
+
PL1_PRESET_RESET,
|
|
28
|
+
)
|
|
29
|
+
from xoa_driver import enums
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AutonegBasic:
|
|
33
|
+
"""Basic auto-negotiation"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
36
|
+
self.settings = PP_AUTONEG(conn, module_id, port_id)
|
|
37
|
+
"""Auto-negotiation settings of the PHY.
|
|
38
|
+
|
|
39
|
+
:type: PP_AUTONEG
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
self.status = PP_AUTONEGSTATUS(conn, module_id, port_id)
|
|
43
|
+
"""Status of auto-negotiation settings of the PHY.
|
|
44
|
+
|
|
45
|
+
:type: PP_AUTONEGSTATUS
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LinkTrainBasic:
|
|
50
|
+
"""Basic link training"""
|
|
51
|
+
|
|
52
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
53
|
+
self.settings = PP_LINKTRAIN(conn, module_id, port_id)
|
|
54
|
+
"""Link training settings.
|
|
55
|
+
|
|
56
|
+
:type: PP_LINKTRAIN
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class AnltBasic:
|
|
61
|
+
"""Basic ANLT settings"""
|
|
62
|
+
|
|
63
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
64
|
+
self.an = AutonegBasic(conn, module_id, port_id)
|
|
65
|
+
"""PCS/PMA auto-negotiation settings.
|
|
66
|
+
|
|
67
|
+
:type: AutonegBasic
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
self.lt = LinkTrainBasic(conn, module_id, port_id)
|
|
71
|
+
"""PCS/PMA link training settings.
|
|
72
|
+
|
|
73
|
+
:type: LinkTrainBasic
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class AutoNegAdvanced:
|
|
78
|
+
"""Advanced auto-negotiation configuration and status."""
|
|
79
|
+
|
|
80
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
81
|
+
self.statistics = PL1_AUTONEGINFO(conn, module_id, port_id, 0)
|
|
82
|
+
"""Statistics of auto-negotiation.
|
|
83
|
+
|
|
84
|
+
:type: PL1_AUTONEGINFO
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
self.results = PL1_AUTONEG_STATUS(conn, module_id, port_id)
|
|
88
|
+
"""Received autoneg advertisement and negotiation results
|
|
89
|
+
|
|
90
|
+
:type: PL1_AUTONEG_STATUS
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
self.abilities = PL1_AUTONEG_ABILITIES(conn, module_id, port_id)
|
|
94
|
+
"""Supported autoneg technical abilities, fec modes, and pause modes
|
|
95
|
+
|
|
96
|
+
:type: PL1_AUTONEG_ABILITIES
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
self.advertise = PL1_AUTONEG_CONFIG(conn, module_id, port_id)
|
|
100
|
+
"""Autoneg advertisement configuration
|
|
101
|
+
|
|
102
|
+
:type: PL1_AUTONEG_CONFIG
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
self._allow_loopback = PL1_CFG_TMP(conn, module_id, port_id, 0, enums.Layer1ConfigType.AN_LOOPBACK)
|
|
106
|
+
"""Whether the port should permit loopback during AN operations.
|
|
107
|
+
|
|
108
|
+
:type: PL1_CFG_TMP
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
self._empty_np = PL1_CFG_TMP(conn, module_id, port_id, 0, enums.Layer1ConfigType.AN_EMPTY_NP)
|
|
112
|
+
"""If the port should send Next Pages even if they are empty.
|
|
113
|
+
|
|
114
|
+
:type: PL1_CFG_TMP
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
async def set_allow_loopback(self, allow: bool) -> None:
|
|
118
|
+
"""Set whether ANLT allows loopback during auto-negotiation.
|
|
119
|
+
|
|
120
|
+
:param allow: Whether to allow loopback.
|
|
121
|
+
:type allow: bool
|
|
122
|
+
"""
|
|
123
|
+
value = 1 if allow else 0
|
|
124
|
+
await self._allow_loopback.set(values=[value])
|
|
125
|
+
|
|
126
|
+
async def get_allow_loopback(self) -> bool:
|
|
127
|
+
"""Get whether ANLT allows loopback during auto-negotiation.
|
|
128
|
+
|
|
129
|
+
:return: True if loopback is allowed, False otherwise.
|
|
130
|
+
"""
|
|
131
|
+
result = await self._allow_loopback.get()
|
|
132
|
+
return bool(result.values[0])
|
|
133
|
+
|
|
134
|
+
async def set_empty_np(self, enable: bool) -> None:
|
|
135
|
+
"""Set if the port should send Next Pages even if they are empty.
|
|
136
|
+
|
|
137
|
+
:param enable: Whether to enable sending empty Next Pages.
|
|
138
|
+
:type enable: bool
|
|
139
|
+
"""
|
|
140
|
+
value = 1 if enable else 0
|
|
141
|
+
await self._empty_np.set(values=[value])
|
|
142
|
+
|
|
143
|
+
async def get_empty_np(self) -> bool:
|
|
144
|
+
"""Get if the port sends Next Pages even if they are empty.
|
|
145
|
+
|
|
146
|
+
:return: True if sending empty Next Pages is enabled, False otherwise.
|
|
147
|
+
"""
|
|
148
|
+
result = await self._empty_np.get()
|
|
149
|
+
return bool(result.values[0])
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class LinkTrainingAdvanced:
|
|
153
|
+
"""Advanced Link Training on serdes level"""
|
|
154
|
+
|
|
155
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int, serdes_xindex: int) -> None:
|
|
156
|
+
self._cmd = PL1_LINKTRAIN_CMD(conn, module_id, port_id, serdes_xindex)
|
|
157
|
+
"""Link training command.
|
|
158
|
+
|
|
159
|
+
:type: PP_LINKTRAIN
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
self.statistics = PL1_LINKTRAININFO(conn, module_id, port_id, serdes_xindex, 0)
|
|
163
|
+
"""Link training statistics.
|
|
164
|
+
|
|
165
|
+
:type: PL1_LINKTRAININFO
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
self.results = PL1_LINKTRAIN_STATUS(conn, module_id, port_id, serdes_xindex)
|
|
169
|
+
"""Link training results.
|
|
170
|
+
|
|
171
|
+
:type: PL1_LINKTRAIN_STATUS
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
self.preset1 = LinkTrainingAdvancedPreset(conn, module_id, port_id, serdes_xindex, enums.FreyaPresetIndex.PRESET1)
|
|
175
|
+
"""Configure preset 1
|
|
176
|
+
|
|
177
|
+
:type: LinkTrainingAdvancedPreset
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
self.preset2 = LinkTrainingAdvancedPreset(conn, module_id, port_id, serdes_xindex, enums.FreyaPresetIndex.PRESET2)
|
|
181
|
+
"""Configure preset 2
|
|
182
|
+
|
|
183
|
+
:type: LinkTrainingAdvancedPreset
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
self.preset3 = LinkTrainingAdvancedPreset(conn, module_id, port_id, serdes_xindex, enums.FreyaPresetIndex.PRESET3)
|
|
187
|
+
"""Configure preset 3
|
|
188
|
+
|
|
189
|
+
:type: LinkTrainingAdvancedPreset
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
self.preset4 = LinkTrainingAdvancedPreset(conn, module_id, port_id, serdes_xindex, enums.FreyaPresetIndex.PRESET4)
|
|
193
|
+
"""Configure preset 4
|
|
194
|
+
|
|
195
|
+
:type: LinkTrainingAdvancedPreset
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
self.preset5 = LinkTrainingAdvancedPreset(conn, module_id, port_id, serdes_xindex, enums.FreyaPresetIndex.PRESET5)
|
|
199
|
+
"""Configure preset 5
|
|
200
|
+
|
|
201
|
+
:type: LinkTrainingAdvancedPreset
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
self.preset_los = LinkTrainingAdvancedPreset(conn, module_id, port_id, serdes_xindex, enums.FreyaPresetIndex.LOS)
|
|
205
|
+
"""Configure preset LOS
|
|
206
|
+
|
|
207
|
+
:type: LinkTrainingAdvancedPreset
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
self.range = LinkTrainingAdvancedRange(conn, module_id, port_id, serdes_xindex)
|
|
211
|
+
"""Configure Link training tap range
|
|
212
|
+
|
|
213
|
+
:type: LinkTrainingAdvancedRange
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
self._initial_modulation = PL1_CFG_TMP(conn, module_id, port_id, 0, enums.Layer1ConfigType.LT_INITIAL_MODULATION)
|
|
217
|
+
"""Link training initial modulation
|
|
218
|
+
|
|
219
|
+
:type: PL1_CFG_TMP
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
self._algorithm = PL1_CFG_TMP(conn, module_id, port_id, 0, enums.Layer1ConfigType.LT_TRAINING_ALGORITHM)
|
|
223
|
+
"""Link training algorithm
|
|
224
|
+
|
|
225
|
+
:type: PL1_CFG_TMP
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
async def set_initial_modulation_nrz(self) -> None:
|
|
229
|
+
"""Set link training initial modulation to NRZ (PAM2).
|
|
230
|
+
"""
|
|
231
|
+
await self._initial_modulation.set(values=[enums.LinkTrainEncoding.NRZ.value])
|
|
232
|
+
|
|
233
|
+
async def set_initial_modulation_pam4(self) -> None:
|
|
234
|
+
"""Set link training initial modulation to PAM4.
|
|
235
|
+
"""
|
|
236
|
+
await self._initial_modulation.set(values=[enums.LinkTrainEncoding.PAM4.value])
|
|
237
|
+
|
|
238
|
+
async def set_initial_modulation_pam4precoding(self) -> None:
|
|
239
|
+
"""Set link training initial modulation to PAM4 with precoding.
|
|
240
|
+
"""
|
|
241
|
+
await self._initial_modulation.set(values=[enums.LinkTrainEncoding.PAM4_WITH_PRECODING.value])
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
async def get_initial_modulation(self) -> enums.LinkTrainEncoding:
|
|
245
|
+
"""Get link training initial modulation.
|
|
246
|
+
|
|
247
|
+
:return: The current modulation.
|
|
248
|
+
"""
|
|
249
|
+
result = await self._initial_modulation.get()
|
|
250
|
+
return enums.LinkTrainEncoding(result.values[0])
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
async def set_algorithm_default(self) -> None:
|
|
254
|
+
"""Set link training algorithm to default.
|
|
255
|
+
|
|
256
|
+
The default algorithm is called Algorithm 0.
|
|
257
|
+
|
|
258
|
+
Algorithm 0 sets a target BER to 1e-8. First, it picks the preset that provides the lowest BER. Then from the selected preset, it adjusts the coefficients to lower the BER further. During the training process, if the target BER is reached, the training will stop.
|
|
259
|
+
|
|
260
|
+
"""
|
|
261
|
+
await self._algorithm.set(values=[enums.LinkTrainAlgorithm.ALG0.value])
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
async def set_algorithm_lite(self) -> None:
|
|
265
|
+
"""Set link training algorithm to simple.
|
|
266
|
+
|
|
267
|
+
The default algorithm is called Algorithm -1.
|
|
268
|
+
|
|
269
|
+
Algorithm -1 request Preset 2, then requests an increment to c(1) and a decrement to c(0). Then the training stops regardless of the achieved BER.
|
|
270
|
+
|
|
271
|
+
"""
|
|
272
|
+
await self._algorithm.set(values=[enums.LinkTrainAlgorithm.ALGN1.value])
|
|
273
|
+
|
|
274
|
+
async def get_algorithm(self) -> enums.LinkTrainAlgorithm:
|
|
275
|
+
"""Get link training algorithm.
|
|
276
|
+
|
|
277
|
+
:return: The current algorithm.
|
|
278
|
+
"""
|
|
279
|
+
result = await self._algorithm.get()
|
|
280
|
+
return enums.LinkTrainAlgorithm(result.values[0])
|
|
281
|
+
|
|
282
|
+
async def send_cmd_nop(self) -> None:
|
|
283
|
+
"""Send NOP command.
|
|
284
|
+
"""
|
|
285
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_NOP, arg=0)
|
|
286
|
+
|
|
287
|
+
async def send_cmd_inc(self, coeff: enums.LinkTrainCoeffs) -> None:
|
|
288
|
+
"""Send Inc Coeffcient request command.
|
|
289
|
+
|
|
290
|
+
:param coeff: The coefficient to increment.
|
|
291
|
+
:type coeff: enums.LinkTrainCoeffs
|
|
292
|
+
"""
|
|
293
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_INC, arg=coeff.value)
|
|
294
|
+
|
|
295
|
+
async def send_cmd_dec(self, coeff: enums.LinkTrainCoeffs) -> None:
|
|
296
|
+
"""Send Dec Coeffcient request command.
|
|
297
|
+
|
|
298
|
+
:param coeff: The coefficient to decrement.
|
|
299
|
+
:type coeff: enums.LinkTrainCoeffs
|
|
300
|
+
"""
|
|
301
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_DEC, arg=coeff.value)
|
|
302
|
+
|
|
303
|
+
async def send_cmd_preset(self, preset: enums.LinkTrainPresets) -> None:
|
|
304
|
+
"""Send Preset request command.
|
|
305
|
+
|
|
306
|
+
:param preset: The preset to request.
|
|
307
|
+
:type preset: enums.LinkTrainPresets
|
|
308
|
+
"""
|
|
309
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_INC, arg=preset.value)
|
|
310
|
+
|
|
311
|
+
async def send_cmd_modulation(self, modulation: enums.LinkTrainEncoding) -> None:
|
|
312
|
+
"""Send Modulation request command.
|
|
313
|
+
|
|
314
|
+
:param modulation: The modulation to request.
|
|
315
|
+
:type modulation: enums.LinkTrainEncoding
|
|
316
|
+
"""
|
|
317
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_ENCODING, arg=modulation.value)
|
|
318
|
+
|
|
319
|
+
async def send_cmd_trained(self) -> None:
|
|
320
|
+
"""Send Trained command.
|
|
321
|
+
"""
|
|
322
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_LOCAL_TRAINED, arg=0)
|
|
323
|
+
|
|
324
|
+
async def send_cmd_no_equalization(self) -> None:
|
|
325
|
+
"""Send No Equalization command.
|
|
326
|
+
|
|
327
|
+
Ask the remote port to set the coeff to NO_EQ.
|
|
328
|
+
"""
|
|
329
|
+
await self._cmd.set(cmd=enums.LinkTrainCmd.CMD_NO_EQ, arg=0)
|
|
330
|
+
|
|
331
|
+
async def get_cmd_result_flag(self) -> Tuple[enums.LinkTrainCmd, enums.LinkTrainCmdResults, enums.LinkTrainCmdFlags]:
|
|
332
|
+
"""Get the last sent link training command and its results and flags.
|
|
333
|
+
|
|
334
|
+
:return: A tuple containing the last command and its argument.
|
|
335
|
+
|
|
336
|
+
- The first element is the LinkTrainCmd enum representing the last command sent.
|
|
337
|
+
- The second element is the LinkTrainCmdResults enum representing the result of the command.
|
|
338
|
+
- The third element is the LinkTrainCmdFlags enum representing any flags associated with the command.
|
|
339
|
+
|
|
340
|
+
:rtype: Tuple[enums.LinkTrainCmd, enums.LinkTrainCmdResults, enums.LinkTrainCmdFlags]
|
|
341
|
+
"""
|
|
342
|
+
resp = await self._cmd.get()
|
|
343
|
+
cmd = enums.LinkTrainCmd(resp.cmd)
|
|
344
|
+
result = enums.LinkTrainCmdResults(resp.result)
|
|
345
|
+
flag = enums.LinkTrainCmdFlags(resp.flags)
|
|
346
|
+
|
|
347
|
+
return cmd, result, flag
|
|
348
|
+
|
|
349
|
+
class AnltAdvanced:
|
|
350
|
+
"""Advanced port-level anlt. For per-serdes configuration and status, use serdes[x]
|
|
351
|
+
"""
|
|
352
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
353
|
+
self.an = AutoNegAdvanced(conn, module_id, port_id)
|
|
354
|
+
"""Autoneg config and status
|
|
355
|
+
|
|
356
|
+
:type: AutoNegAdvanced
|
|
357
|
+
"""
|
|
358
|
+
|
|
359
|
+
self.ctrl = PL1_ANLT(conn, module_id, port_id)
|
|
360
|
+
"""ANLT control
|
|
361
|
+
|
|
362
|
+
:type: PL1_ANLT
|
|
363
|
+
"""
|
|
364
|
+
|
|
365
|
+
self.lt_config = PL1_LINKTRAIN_CONFIG(conn, module_id, port_id)
|
|
366
|
+
"""Port-level Link Training config
|
|
367
|
+
|
|
368
|
+
:type: PL1_LINKTRAIN_CONFIG
|
|
369
|
+
"""
|
|
370
|
+
|
|
371
|
+
self.log = PL1_LOG(conn, module_id, port_id)
|
|
372
|
+
"""Advanced ANLT protocol trace log
|
|
373
|
+
|
|
374
|
+
:type: PL1_LOG
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
self._autorestart = PL1_CFG_TMP(conn, module_id, port_id, 0, enums.Layer1ConfigType.AUTO_LINK_RECOVERY)
|
|
378
|
+
"""ANLT Autorestart
|
|
379
|
+
|
|
380
|
+
:type: PL1_CFG_TMP
|
|
381
|
+
"""
|
|
382
|
+
|
|
383
|
+
self._strict_mode = PL1_CFG_TMP(conn, module_id, port_id, 0, enums.Layer1ConfigType.ANLT_STRICT_MODE)
|
|
384
|
+
"""ANLT strict mode. In strict mode, errored framed will be ignored.
|
|
385
|
+
|
|
386
|
+
:type: PL1_CFG_TMP
|
|
387
|
+
"""
|
|
388
|
+
|
|
389
|
+
async def set_autorestart(self, restart_link_down: bool, restart_lt_failure: bool) -> None:
|
|
390
|
+
"""Set ANLT autorestart configuration.
|
|
391
|
+
|
|
392
|
+
:param restart_link_down: Whether to restart ANLT when link goes down.
|
|
393
|
+
:param restart_lt_failure: Whether to restart ANLT when link training fails.
|
|
394
|
+
"""
|
|
395
|
+
value = 0
|
|
396
|
+
if restart_link_down:
|
|
397
|
+
value |= 0x01
|
|
398
|
+
if restart_lt_failure:
|
|
399
|
+
value |= 0x02
|
|
400
|
+
await self._autorestart.set(values=[value])
|
|
401
|
+
|
|
402
|
+
async def get_autorestart(self) -> Tuple[bool, bool]:
|
|
403
|
+
"""Get ANLT autorestart configuration.
|
|
404
|
+
|
|
405
|
+
:return: A tuple containing two booleans:
|
|
406
|
+
- The first boolean indicates whether ANLT restarts when link goes down.
|
|
407
|
+
- The second boolean indicates whether ANLT restarts when link training fails.
|
|
408
|
+
"""
|
|
409
|
+
result = await self._autorestart.get()
|
|
410
|
+
value = result.values[0]
|
|
411
|
+
restart_link_down = bool(value & 0x01)
|
|
412
|
+
restart_lt_failure = bool(value & 0x02)
|
|
413
|
+
return restart_link_down, restart_lt_failure
|
|
414
|
+
|
|
415
|
+
async def set_strict_mode(self, enable: bool) -> None:
|
|
416
|
+
"""Set ANLT strict mode. In strict mode, errored framed will be ignored.
|
|
417
|
+
|
|
418
|
+
:param enable: Whether to enable strict mode.
|
|
419
|
+
"""
|
|
420
|
+
value = 1 if enable else 0
|
|
421
|
+
await self._strict_mode.set(values=[value])
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
async def get_strict_mode(self) -> bool:
|
|
425
|
+
"""Get ANLT strict mode status.
|
|
426
|
+
|
|
427
|
+
:return: True if strict mode is enabled, False otherwise.
|
|
428
|
+
"""
|
|
429
|
+
result = await self._strict_mode.get()
|
|
430
|
+
return bool(result.values[0])
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class LinkTrainingAdvancedPreset:
|
|
434
|
+
"""Advanced Link Training Preset"""
|
|
435
|
+
|
|
436
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int, serdes_xindex: int, preset_index: enums.FreyaPresetIndex) -> None:
|
|
437
|
+
|
|
438
|
+
self.native = PL1_PRESET_CONFIG(conn, module_id, port_id, serdes_xindex, preset_index)
|
|
439
|
+
"""Preset native values. (only for Freya)
|
|
440
|
+
|
|
441
|
+
:type: PL1_PRESET_CONFIG
|
|
442
|
+
"""
|
|
443
|
+
|
|
444
|
+
self.ieee = PL1_PRESET_CONFIG_COEFF(conn, module_id, port_id, serdes_xindex, preset_index)
|
|
445
|
+
"""Preset IEEE coefficient values. (only for Freya)
|
|
446
|
+
|
|
447
|
+
:type: PL1_PRESET_CONFIG_COEFF
|
|
448
|
+
"""
|
|
449
|
+
|
|
450
|
+
self.level = PL1_PRESET_CONFIG_LEVEL(conn, module_id, port_id, serdes_xindex, preset_index)
|
|
451
|
+
"""Preset mV/dB values. (only for Freya)
|
|
452
|
+
|
|
453
|
+
:type: PL1_PRESET_CONFIG_LEVEL
|
|
454
|
+
"""
|
|
455
|
+
|
|
456
|
+
self.reset = PL1_PRESET_RESET(conn, module_id, port_id, serdes_xindex, preset_index)
|
|
457
|
+
"""Reset preset to default. (only for Freya)
|
|
458
|
+
|
|
459
|
+
:type: PL1_PRESET_RESET
|
|
460
|
+
"""
|
|
461
|
+
|
|
462
|
+
class LinkTrainingAdvancedRangeTap:
|
|
463
|
+
"""Advanced Link Training Range Tap"""
|
|
464
|
+
|
|
465
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int, serdes_xindex: int, tap_index: enums.FreyaTapIndex) -> None:
|
|
466
|
+
|
|
467
|
+
self.native = PL1_LT_PHYTXEQ_RANGE(conn, module_id, port_id, serdes_xindex, tap_index)
|
|
468
|
+
"""Tap range native values. (only for Freya)
|
|
469
|
+
|
|
470
|
+
:type: PL1_LT_PHYTXEQ_RANGE
|
|
471
|
+
"""
|
|
472
|
+
|
|
473
|
+
self.ieee = PL1_LT_PHYTXEQ_RANGE_COEFF(conn, module_id, port_id, serdes_xindex, tap_index)
|
|
474
|
+
"""Tap range IEEE coefficient values. (only for Freya)
|
|
475
|
+
|
|
476
|
+
:type: PL1_LT_PHYTXEQ_RANGE_COEFF
|
|
477
|
+
"""
|
|
478
|
+
|
|
479
|
+
class LinkTrainingAdvancedRange:
|
|
480
|
+
"""Advanced Link Training Range"""
|
|
481
|
+
|
|
482
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int, serdes_xindex: int) -> None:
|
|
483
|
+
|
|
484
|
+
self.pre = LinkTrainingAdvancedRangeTap(conn, module_id, port_id, serdes_xindex, enums.FreyaTapIndex.TAP0)
|
|
485
|
+
"""Pre tap range and response. (only for Freya)
|
|
486
|
+
|
|
487
|
+
:type: LinkTrainingAdvancedRangeTap
|
|
488
|
+
"""
|
|
489
|
+
|
|
490
|
+
self.main = LinkTrainingAdvancedRangeTap(conn, module_id, port_id, serdes_xindex, enums.FreyaTapIndex.TAP1)
|
|
491
|
+
"""Main tap range and response. (only for Freya)
|
|
492
|
+
|
|
493
|
+
:type: LinkTrainingAdvancedRangeTap
|
|
494
|
+
"""
|
|
495
|
+
|
|
496
|
+
self.post = LinkTrainingAdvancedRangeTap(conn, module_id, port_id, serdes_xindex, enums.FreyaTapIndex.TAP2)
|
|
497
|
+
"""Post tap range and response. (only for Freya)
|
|
498
|
+
|
|
499
|
+
:type: LinkTrainingAdvancedRangeTap
|
|
500
|
+
"""
|
|
501
|
+
|
|
502
|
+
self.pre2 = LinkTrainingAdvancedRangeTap(conn, module_id, port_id, serdes_xindex, enums.FreyaTapIndex.TAP3)
|
|
503
|
+
"""Pre2 tap range and response. (only for Freya)
|
|
504
|
+
|
|
505
|
+
:type: LinkTrainingAdvancedRangeTap
|
|
506
|
+
"""
|
|
507
|
+
|
|
508
|
+
self.pre3 = LinkTrainingAdvancedRangeTap(conn, module_id, port_id, serdes_xindex, enums.FreyaTapIndex.TAP4)
|
|
509
|
+
"""Pre3 tap range and response. (only for Freya)
|
|
510
|
+
|
|
511
|
+
:type: LinkTrainingAdvancedRangeTap
|
|
512
|
+
"""
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
TYPE_CHECKING,
|
|
3
|
+
Tuple,
|
|
4
|
+
)
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from xoa_driver.internals.core import interfaces as itf
|
|
7
|
+
from xoa_driver.internals.commands import (
|
|
8
|
+
P_BRRMODE,
|
|
9
|
+
P_BRRSTATUS,
|
|
10
|
+
)
|
|
11
|
+
from xoa_driver import enums
|
|
12
|
+
|
|
13
|
+
class BroadrReach:
|
|
14
|
+
"""BroadR Reach configuration and status."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
17
|
+
self.mode = P_BRRMODE(conn, module_id, port_id)
|
|
18
|
+
"""BRR mode.
|
|
19
|
+
|
|
20
|
+
:type: P_BRRMODE
|
|
21
|
+
"""
|
|
22
|
+
self.status = P_BRRSTATUS(conn, module_id, port_id)
|
|
23
|
+
"""Actual BRR status.
|
|
24
|
+
|
|
25
|
+
:type: P_BRRSTATUS
|
|
26
|
+
"""
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
TYPE_CHECKING,
|
|
3
|
+
Tuple,
|
|
4
|
+
)
|
|
5
|
+
from typing import Self
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from xoa_driver.internals.core import interfaces as itf
|
|
8
|
+
from xoa_driver.internals.commands import (
|
|
9
|
+
PP_EYEMEASURE,
|
|
10
|
+
PP_EYERESOLUTION,
|
|
11
|
+
PP_EYEREAD,
|
|
12
|
+
PP_EYEINFO,
|
|
13
|
+
PP_EYEBER,
|
|
14
|
+
PP_EYEDWELLBITS,
|
|
15
|
+
)
|
|
16
|
+
from xoa_driver import enums
|
|
17
|
+
|
|
18
|
+
class EyeDiagram:
|
|
19
|
+
"""L23 high-speed port SerDes eye diagram."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int, serdes_xindex: int) -> None:
|
|
22
|
+
self.__conn = conn
|
|
23
|
+
self.__module_id = module_id
|
|
24
|
+
self.__port_id = port_id
|
|
25
|
+
self.__serdes_index = serdes_xindex
|
|
26
|
+
self.measure = PP_EYEMEASURE(conn, module_id, port_id, serdes_xindex)
|
|
27
|
+
"""BER eye measurement.
|
|
28
|
+
|
|
29
|
+
:type: PP_EYEMEASURE
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
self.resolution = PP_EYERESOLUTION(conn, module_id, port_id, serdes_xindex)
|
|
33
|
+
"""Resolution for BER eye measurement.
|
|
34
|
+
|
|
35
|
+
:type: PP_EYERESOLUTION
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
self.info = PP_EYEINFO(conn, module_id, port_id, serdes_xindex)
|
|
39
|
+
"""Information of BER eye measurement.
|
|
40
|
+
|
|
41
|
+
:type: PP_EYEINFO
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
self.ber = PP_EYEBER(conn, module_id, port_id, serdes_xindex)
|
|
45
|
+
"""BER estimation of an eye diagram.
|
|
46
|
+
|
|
47
|
+
:type: PP_EYEBER
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
self.dwell_bits = PP_EYEDWELLBITS(conn, module_id, port_id, serdes_xindex)
|
|
51
|
+
"""Dwell bits for an eye capture.
|
|
52
|
+
|
|
53
|
+
:type: PP_EYEDWELLBITS
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __await__(self):
|
|
57
|
+
return self._setup().__await__()
|
|
58
|
+
|
|
59
|
+
async def _setup(self) -> Self:
|
|
60
|
+
resolution = await self.resolution.get()
|
|
61
|
+
self.read_column = tuple(
|
|
62
|
+
PP_EYEREAD(
|
|
63
|
+
self.__conn,
|
|
64
|
+
self.__module_id,
|
|
65
|
+
self.__port_id,
|
|
66
|
+
self.__serdes_index,
|
|
67
|
+
_colum_xindex=x
|
|
68
|
+
)
|
|
69
|
+
for x in range(resolution.x_resolution)
|
|
70
|
+
)
|
|
71
|
+
return self
|
|
@@ -26,7 +26,7 @@ class LinkFlap:
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class
|
|
29
|
+
class PmaErrorInject:
|
|
30
30
|
"""L23 high-speed port PMA pulse error injection."""
|
|
31
31
|
|
|
32
32
|
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
@@ -43,18 +43,18 @@ class PmaPulseErrInj:
|
|
|
43
43
|
"""
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
class
|
|
47
|
-
"""
|
|
46
|
+
class Impair:
|
|
47
|
+
"""Impairment functions"""
|
|
48
48
|
|
|
49
|
-
def __init__(self, conn: "itf.IConnection",
|
|
50
|
-
self.link_flap = LinkFlap(conn,
|
|
49
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
50
|
+
self.link_flap = LinkFlap(conn, module_id, port_id)
|
|
51
51
|
"""Link flap settings.
|
|
52
52
|
|
|
53
53
|
:type: LinkFlap
|
|
54
54
|
"""
|
|
55
55
|
|
|
56
|
-
self.
|
|
56
|
+
self.pma_error_inject = PmaErrorInject(conn, module_id, port_id)
|
|
57
57
|
"""PMA pulse error injection settings.
|
|
58
58
|
|
|
59
|
-
:type:
|
|
59
|
+
:type: PmaErrorInject
|
|
60
60
|
"""
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
TYPE_CHECKING,
|
|
3
|
+
Tuple,
|
|
4
|
+
)
|
|
5
|
+
from typing import Self
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from xoa_driver.internals.core import interfaces as itf
|
|
8
|
+
from xoa_driver.internals.commands import (
|
|
9
|
+
PP_RXLASERPOWER,
|
|
10
|
+
PP_TXLASERPOWER,
|
|
11
|
+
)
|
|
12
|
+
from xoa_driver import enums
|
|
13
|
+
|
|
14
|
+
class LaserPower:
|
|
15
|
+
"""Laser power status."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, conn: "itf.IConnection", module_id: int, port_id: int) -> None:
|
|
18
|
+
self.tx_laser_power = PP_TXLASERPOWER(conn, module_id, port_id)
|
|
19
|
+
"""Power of TX laser.
|
|
20
|
+
|
|
21
|
+
:type: PP_TXLASERPOWER
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
self.rx_laser_power = PP_RXLASERPOWER(conn, module_id, port_id)
|
|
25
|
+
"""Power of RX laser.
|
|
26
|
+
|
|
27
|
+
:type: PP_RXLASERPOWER
|
|
28
|
+
"""
|