-
Notifications
You must be signed in to change notification settings - Fork 212
Expand file tree
/
Copy pathy_cable_base.py
More file actions
1299 lines (1043 loc) · 50.7 KB
/
y_cable_base.py
File metadata and controls
1299 lines (1043 loc) · 50.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
"""
y_cable_base.py
Base class for implementing Y-Cable specific functionality in SONiC.
This is the base class of sonic_y_cable implentation. A vendor-specific
implementation of a 'YCable' class needs to inherit from this class.
Classes derived from this class provide the ability to interact
with a vendor-specific Y-Cable
"""
#
# YCableBase ===================================================================
#
class YCableBase():
# definitions of targets for getting the various fields/cursor
# equalization parameters from the register spec.
# the name of the target denotes which side MCU
# values will be retrieved from or written to
# on the Y-Cable
TARGET_UNKNOWN = -1
TARGET_NIC = 0
TARGET_TOR_A = 1
TARGET_TOR_B = 2
# definitions of targets for getting the EYE/BER
# and initiating PRBS/Loopback on the Y cable
# the name of the target denotes which side values
# will be retreived/initiated
EYE_PRBS_LOOPBACK_TARGET_NIC = 0
EYE_PRBS_LOOPBACK_TARGET_TOR_A = 1
EYE_PRBS_LOOPBACK_TARGET_TOR_B = 2
EYE_PRBS_LOOPBACK_TARGET_LOCAL = 3
# definitions of switch counter types
# to be entered by the user in get_switch_count api
# for retreiving the counter values
SWITCH_COUNT_MANUAL = "manual"
SWITCH_COUNT_AUTO = "auto"
# switching modes inside Y-Cable
SWITCHING_MODE_MANUAL = 0
SWITCHING_MODE_AUTO = 1
# definitions of the FEC mode to be configured
# on a port/cable
FEC_MODE_NONE = 0
FEC_MODE_RS = 1
FEC_MODE_FC = 2
# definitions of the modes to be run for loopback mode
# on the port/cable
LOOPBACK_MODE_NONE = 0
LOOPBACK_MODE_NEAR_END = 1
LOOPBACK_MODE_FAR_END = 2
# Valid return codes for upgrade firmware routine steps
FIRMWARE_DOWNLOAD_SUCCESS = 0
FIRMWARE_DOWNLOAD_FAILURE = 1
FIRMWARE_ACTIVATE_SUCCESS = 0
FIRMWARE_ACTIVATE_FAILURE = 1
FIRMWARE_ROLLBACK_SUCCESS = 0
FIRMWARE_ROLLBACK_FAILURE = 1
# Valid status values for download_firmware
# The download_firmware_status variable should be assigned
# one of these predefined values inside download_firmware routine
# as to signify what is the current status of the firmware
# download is
FIRMWARE_DOWNLOAD_STATUS_NOT_INITIATED_OR_FINISHED = 0
FIRMWARE_DOWNLOAD_STATUS_INPROGRESS = 1
FIRMWARE_DOWNLOAD_STATUS_FAILED = 2
# Valid status values for mux togge
# The mux_toggle_status variable should be assigned/used
# one of these predefined values inside toggle/telemetry routine
# as to signify what is the current status of toggle in progress
MUX_TOGGLE_STATUS_NOT_INITIATED_OR_FINISHED = 0
MUX_TOGGLE_STATUS_INPROGRESS = 1
# definitions of PRBS run modes
PRBS_DIRECTION_BOTH = 0
PRBS_DIRECTION_GENERATOR = 1
PRBS_DIRECTION_CHECKER = 2
def __init__(self, port, logger):
"""
Args:
port:
an Integer, the actual physical port connected to a Y cable
logger:
a logging instance object, must be an instance of the Logger class from sonic_py_common instantiated
by the program which is instantiating this class.
"""
self.port = port
self._logger = logger
self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_NOT_INITIATED_OR_FINISHED
self.mux_toggle_status = self.MUX_TOGGLE_STATUS_NOT_INITIATED_OR_FINISHED
def log_warning(self, msg):
self._logger.log_warning("y_cable_port {}: {}".format(self.port, msg))
def log_error(self, msg):
self._logger.log_error("y_cable_port {}: {}".format(self.port, msg))
def log_info(self, msg):
self._logger.log_info("y_cable_port {}: {}".format(self.port, msg))
def log_notice(self, msg):
self._logger.log_notice("y_cable_port {}: {}".format(self.port, msg))
def log_debug(self, msg):
self._logger.log_debug("y_cable_port {}: {}".format(self.port, msg))
def toggle_mux_to_tor_a(self):
"""
This API does a hard switch toggle of the Y cable's MUX regardless of link state to
TOR A on the port this is called for. This means if the Y cable is actively sending traffic,
the "get_active_linked_tor_side" API will now return Tor A.
It also implies that if the link is actively sending traffic on this port,
Y cable MUX will start forwarding packets from TOR A to NIC, and drop packets from TOR B to NIC
regardless of previous forwarding state.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a Boolean, True if the toggle succeeded and False if it did not succeed.
"""
raise NotImplementedError
def toggle_mux_to_tor_b(self):
"""
This API does a hard switch toggle of the Y cable's MUX regardless of link state to
TOR B. This means if the Y cable is actively sending traffic, the "get_active_linked_tor_side"
API will now return Tor B. It also implies that if the link is actively sending traffic on this port,
Y cable. MUX will start forwarding packets from TOR B to NIC, and drop packets from TOR A to NIC
regardless of previous forwarding state.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a Boolean, True if the toggle succeeded and False if it did not succeed.
"""
raise NotImplementedError
def get_read_side(self):
"""
This API checks which side of the Y cable the reads are actually getting performed
from, either TOR A or TOR B or NIC and returns the value.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
One of the following predefined constants:
TARGET_TOR_A, if reading the Y cable from TOR A side.
TARGET_TOR_B, if reading the Y cable from TOR B side.
TARGET_NIC, if reading the Y cable from NIC side.
TARGET_UNKNOWN, if reading the Y cable API fails.
"""
raise NotImplementedError
def get_mux_direction(self):
"""
This API checks which side of the Y cable mux is currently point to
and returns either TOR A or TOR B. Note that this API should return mux-direction
regardless of whether the link is active and sending traffic or not.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
One of the following predefined constants:
TARGET_TOR_A, if mux is pointing to TOR A side.
TARGET_TOR_B, if mux is pointing to TOR B side.
TARGET_UNKNOWN, if mux direction API fails.
"""
raise NotImplementedError
def get_active_linked_tor_side(self):
"""
This API checks which side of the Y cable is actively linked and sending traffic
and returns either TOR A or TOR B.
The port on which this API is called for can be referred using self.port.
This is different from get_mux_direction in a sense it also implies the link on the side
where mux is pointing to must be active and sending traffic, whereas get_mux_direction
just tells where the mux is pointing to.
Args:
Returns:
One of the following predefined constants:
TARGET_TOR_A, if TOR A is actively linked and sending traffic.
TARGET_TOR_B, if TOR B is actively linked and sending traffic.
TARGET_UNKNOWN, if checking which side is linked and sending traffic API fails.
"""
raise NotImplementedError
def is_link_active(self, target):
"""
This API checks if NIC, TOR_A and TOR_B of the Y cable's link is active.
The target specifies which link is supposed to be checked
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to check the link on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if the link is active
, False if the link is not active
"""
raise NotImplementedError
def get_eye_heights(self, target):
"""
This API returns the EYE height value for a specfic port.
The target could be local side, TOR_A, TOR_B, NIC etc.
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the target on which to get the eye:
EYE_PRBS_LOOPBACK_TARGET_LOCAL -> local side,
EYE_PRBS_LOOPBACK_TARGET_TOR_A -> TOR A
EYE_PRBS_LOOPBACK_TARGET_TOR_B -> TOR B
EYE_PRBS_LOOPBACK_TARGET_NIC -> NIC
Returns:
a list, with EYE values of lane 0 lane 1 lane 2 lane 3 with corresponding index
"""
raise NotImplementedError
def get_vendor(self):
"""
This API returns the vendor name of the Y cable for a specfic port.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a string, with vendor name
"""
raise NotImplementedError
def get_part_number(self):
"""
This API returns the part number of the Y cable for a specfic port.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a string, with part number
"""
raise NotImplementedError
def get_switch_count_total(self, switch_count_type, clear_on_read=False):
"""
This API returns the total switch count to change the Active TOR which has
been done manually/automatic by the user.
The port on which this API is called for can be referred using self.port.
Args:
switch_count_type:
One of the following predefined constants, for getting the count type:
SWITCH_COUNT_MANUAL -> manual switch count
SWITCH_COUNT_AUTO -> automatic switch count
clear_on_read:
a boolean, True if the count has to be reset after read to zero
, False if the count is not to be reset after read
Returns:
an integer, the number of times the Y-cable has been switched
"""
raise NotImplementedError
def get_switch_count_tor_a(self, clear_on_read=False):
"""
This API returns the switch count to change the Active TOR which has
been done manually by the user initiated from ToR A
This is essentially all the successful switches initiated from ToR A. Toggles which were
initiated to toggle from ToR A and did not succeed do not count.
The port on which this API is called for can be referred using self.port.
Args:
clear_on_read:
a boolean, True if the count has to be reset after read to zero
, False if the count is not to be reset after read
Returns:
an integer, the number of times the Y-cable has been switched from ToR A
"""
raise NotImplementedError
def get_switch_count_tor_b(self, clear_on_read=False):
"""
This API returns the switch count to change the Active TOR which has
been done manually by the user initiated from ToR B
This is essentially all the successful switches initiated from ToR B. Toggles which were
initiated to toggle from ToR B and did not succeed do not count.
The port on which this API is called for can be referred using self.port.
Args:
clear_on_read:
a boolean, True if the count has to be reset after read to zero
, False if the count is not to be reset after read
Returns:
an integer, the number of times the Y-cable has been switched from ToR B
"""
raise NotImplementedError
def get_switch_count_target(self, switch_count_type, target, clear_on_read=False):
"""
This API returns the total number of times the Active TOR has
been done manually/automaticlly toggled towards a target.
For example, TARGET_TOR_A as target would imply
how many times the mux has been toggled towards TOR A.
The port on which this API is called for can be referred using self.port.
Args:
switch_count_type:
One of the following predefined constants, for getting the count type:
SWITCH_COUNT_MANUAL -> manual switch count
SWITCH_COUNT_AUTO -> automatic switch count
target:
One of the following predefined constants, the actual target to check the link on:
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
clear_on_read:
a boolean, True if the count has to be reset after read to zero
, False if the count is not to be reset after read
Returns:
an integer, the number of times manually the Y-cable has been switched
"""
raise NotImplementedError
def get_target_cursor_values(self, lane, target):
"""
This API returns the cursor equalization parameters for a target(NIC, TOR_A, TOR_B).
This includes pre one, pre two, main, post one, post two, post three cursor values
If any of the value is not available please return None for that filter
The port on which this API is called for can be referred using self.port.
Args:
lane:
an Integer, the lane on which to collect the cursor values
1 -> lane 1,
2 -> lane 2
3 -> lane 3
4 -> lane 4
target:
One of the following predefined constants, the actual target to get the cursor values on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a list, with pre one, pre two, main, post one, post two, post three cursor values in the order
"""
raise NotImplementedError
def set_target_cursor_values(self, lane, cursor_values, target):
"""
This API sets the cursor equalization parameters for a target(NIC, TOR_A, TOR_B).
This includes pre one, pre two, main, post one, post two etc. cursor values
The port on which this API is called for can be referred using self.port.
Args:
lane:
an Integer, the lane on which to collect the cursor values
1 -> lane 1,
2 -> lane 2
3 -> lane 3
4 -> lane 4
cursor_values:
a list, with pre one, pre two, main, post one, post two cursor, post three etc. values in the order
target:
One of the following predefined constants, the actual target to get the cursor values on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if cursor values setting is successful
, False if cursor values setting is not successful
"""
raise NotImplementedError
def get_firmware_version(self, target):
"""
This routine should return the active, inactive and next (committed)
firmware running on the target. Each of the version values in this context
could be a string with a major and minor number and a build value.
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to get the firmware version on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a Dictionary:
with version_active, version_inactive and version_next keys
and their corresponding values
"""
raise NotImplementedError
def download_firmware(self, fwfile):
"""
This routine should download and store the firmware on all the
components of the Y cable of the port for which this API is called..
This should include any internal transfers, checksum validation etc.
from TOR to TOR or TOR to NIC side of the firmware specified by the fwfile.
This basically means that the firmware which is being downloaded should be
available to be activated (start being utilized by the cable) once this API is
successfully executed.
Note that this API should ideally not require any rollback even if it fails
as this should not interfere with the existing cable functionality because
this has not been activated yet.
The port on which this API is called for can be referred using self.port.
Args:
fwfile:
a string, a path to the file which contains the firmware image.
Note that the firmware file can be in the format of the vendor's
choosing (binary, archive, etc.). But note that it should be one file
which contains firmware for all components of the Y-cable
Returns:
One of the following predefined constants:
FIRMWARE_DOWNLOAD_SUCCESS
FIRMWARE_DOWNLOAD_FAILURE
a predefined code stating whether the firmware download was successful
or an error code as to what was the cause of firmware download failure
"""
raise NotImplementedError
def activate_firmware(self, fwfile=None, hitless=False):
"""
This routine should activate the downloaded firmware on all the
components of the Y cable of the port for which this API is called..
This API is meant to be used in conjunction with download_firmware API, and
should be called once download_firmware API is succesful.
This means that the firmware which has been downloaded should be
activated (start being utilized by the cable) once this API is
successfully executed.
The port on which this API is called for can be referred using self.port.
Args:
fwfile (optional):
a string, a path to the file which contains the firmware image.
Note that the firmware file can be in the format of the vendor's
choosing (binary, archive, etc.). But note that it should be one file
which contains firmware for all components of the Y-cable. In case the
vendor chooses to pass this file in activate_firmware, the API should
have the logic to retreive the firmware version from this file
which has to be activated on the components of the Y-Cable
this API has been called for.
If None is passed for fwfile, the cable should activate whatever
firmware is marked to be activated next.
If provided, it should retreive the firmware version(s) from this file, ensure
they are downloaded on the cable, then activate them.
hitless (optional):
a boolean, True, Hitless upgrade: it will backup/restore the current state
(ex. variables of link status, API attributes...etc.) before
and after firmware upgrade.
a boolean, False, Non-hitless upgrade: it will update the firmware regardless
the current status, a link flip can be observed during the upgrade.
Returns:
One of the following predefined constants:
FIRMWARE_ACTIVATE_SUCCESS
FIRMWARE_ACTIVATE_FAILURE
"""
raise NotImplementedError
def rollback_firmware(self, fwfile=None):
"""
This routine should rollback the firmware to the previous version
which was being used by the cable. This API is intended to be called when the
user either witnesses an activate_firmware API failure or sees issues with
newer firmware in regards to stable cable functioning.
The port on which this API is called for can be referred using self.port.
Args:
fwfile (optional):
a string, a path to the file which contains the firmware image.
Note that the firmware file can be in the format of the vendor's
choosing (binary, archive, etc.). But note that it should be one file
which contains firmware for all components of the Y-cable. In case the
vendor chooses to pass this file in rollback_firmware, the API should
have the logic to retreive the firmware version from this file
which should not be activated on the components of the Y-Cable
this API has been called for.
If None is passed for fwfile, the cable should rollback whatever
firmware is marked to be rollback next.
If provided, it should retreive the firmware version(s) from this file, ensure
that the firmware is rollbacked to a version which does not match to retreived version(s).
This is exactly the opposite behavior of this param to activate_firmware
Returns:
One of the following predefined constants:
FIRMWARE_ROLLBACK_SUCCESS
FIRMWARE_ROLLBACK_FAILURE
"""
raise NotImplementedError
def set_switching_mode(self, mode):
"""
This API enables the auto switching or manual switching feature on the Y-Cable,
depending upon the mode entered by the user.
Autoswitch feature if enabled actually does an automatic toggle of the mux in case the active
side link goes down and basically points the mux to the other side.
The port on which this API is called for can be referred using self.port.
Args:
mode:
One of the following predefined constants:
SWITCHING_MODE_AUTO
SWITCHING_MODE_MANUAL
specifies which type of switching mode we set the Y-Cable to
either SWITCHING_MODE_AUTO or SWITCHING_MODE_MANUAL
Returns:
a Boolean, True if the switch succeeded and False if it did not succeed.
"""
raise NotImplementedError
def get_switching_mode(self):
"""
This API returns which type of switching mode the cable is set to auto/manual
The port on which this API is called for can be referred using self.port.
Args:
Returns:
One of the following predefined constants:
SWITCHING_MODE_AUTO if auto switch is enabled.
SWITCHING_MODE_MANUAL if manual switch is enabled.
"""
raise NotImplementedError
def get_nic_temperature(self):
"""
This API returns nic temperature of the physical port for which this API is called.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
an Integer, the temperature of the NIC MCU
"""
raise NotImplementedError
def get_local_temperature(self):
"""
This API returns local ToR temperature of the physical port for which this API is called.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
an Integer, the temperature of the local MCU
"""
raise NotImplementedError
def get_nic_voltage(self):
"""
This API returns nic voltage of the physical port for which this API is called.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a float, the voltage of the NIC MCU
"""
raise NotImplementedError
def get_local_voltage(self):
"""
This API returns local ToR voltage of the physical port for which this API is called.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a float, the voltage of the local MCU
"""
raise NotImplementedError
def get_alive_status(self):
"""
This API checks if cable is connected to all the ports and is healthy.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a boolean, True if the cable is alive
, False if the cable is not alive
"""
raise NotImplementedError
def reset(self, target):
"""
This API resets the MCU to which this API is called for.
The target specifies which MCU is supposed to be reset
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to check the link on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if the cable is target reset
, False if the cable target is not reset
"""
raise NotImplementedError
def create_port(self, speed, fec_mode_tor=FEC_MODE_NONE, fec_mode_nic= FEC_MODE_NONE, anlt_tor=False, anlt_nic=False):
"""
This API sets the mode of the cable/port for corresponding lane/FEC etc. configuration as specified.
The speed specifies which mode is supposed to be set 50G, 100G etc
the AN/LT specifies if auto-negotiation + link training (AN/LT) has to be enabled
Note that in case create_port is called multiple times, the most recent api call will take the precedence
on either of TOR side.
The port on which this API is called for can be referred using self.port.
Args:
speed:
an Integer, the value for the link speed to be configured (in megabytes).
examples:
50000 -> 50G
100000 -> 100G
fec_mode_tor:
One of the following predefined constants, the actual FEC mode for the ToR to be configured:
FEC_MODE_NONE,
FEC_MODE_RS,
FEC_MODE_FC
fec_mode_nic:
One of the following predefined constants, the actual FEC mode for the nic to be configured:
FEC_MODE_NONE,
FEC_MODE_RS,
FEC_MODE_FC
anlt_tor:
a boolean, True if auto-negotiation + link training (AN/LT) is to be enabled on ToR's
, False if auto-negotiation + link training (AN/LT) is not to be enabled on ToR's
anlt_nic:
a boolean, True if auto-negotiation + link training (AN/LT) is to be enabled on nic
, False if auto-negotiation + link training (AN/LT) is not to be enabled on nic
Returns:
a boolean, True if the port is configured
, False if the port is not configured
"""
raise NotImplementedError
def get_speed(self):
"""
This API gets the mode of the cable for corresponding lane configuration.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
speed:
an Integer, the value for the link speed is configured (in megabytes).
examples:
50000 -> 50G
100000 -> 100G
"""
raise NotImplementedError
def set_fec_mode(self, fec_mode, target):
"""
This API gets the FEC mode of the cable for which it is set to.
The port on which this API is called for can be referred using self.port.
Args:
fec_mode:
One of the following predefined constants, the actual FEC mode for the port to be configured:
FEC_MODE_NONE,
FEC_MODE_RS,
FEC_MODE_FC
target:
One of the following predefined constants, the actual target to set the FEC mode on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if the FEC mode is configured
, False if the FEC mode is not configured
"""
raise NotImplementedError
def get_fec_mode(self, target):
"""
This API gets the FEC mode of the cable which it is set to.
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to FEC mode on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
fec_mode:
One of the following predefined constants, the actual FEC mode for the port to be configured:
FEC_MODE_NONE,
FEC_MODE_RS,
FEC_MODE_FC
"""
raise NotImplementedError
def set_anlt(self, enable, target):
"""
This API enables/disables the cable auto-negotiation + link training (AN/LT).
The port on which this API is called for can be referred using self.port.
Args:
enable:
a boolean, True if auto-negotiation + link training (AN/LT) is to be enabled
, False if auto-negotiation + link training (AN/LT) is not to be enabled
target:
One of the following predefined constants, the actual target to get the stats on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if the auto-negotiation + link training (AN/LT) enable/disable specified is configured
, False if the auto-negotiation + link training (AN/LT) enable/disable specified is not configured
"""
raise NotImplementedError
def get_anlt(self, target):
"""
This API gets the auto-negotiation + link training (AN/LT) mode of the cable for corresponding port.
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to get the AN/LT on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if auto-negotiation + link training (AN/LT) is enabled
, False if auto-negotiation + link training (AN/LT) is not enabled
"""
raise NotImplementedError
def get_event_log(self, clear_on_read=False):
"""
This API returns the event log of the cable
The port on which this API is called for can be referred using self.port.
Args:
clear_on_read:
a boolean, True if the log has to be cleared after read
, False if the log is not to be cleared after read
Returns:
list:
a list of strings which correspond to the event logs of the cable
"""
raise NotImplementedError
def get_pcs_stats(self, target):
"""
This API returns the pcs statistics of the cable
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to get the stats on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a dictionary:
a detailed format agreed upon by vendors
"""
raise NotImplementedError
def get_fec_stats(self, target):
"""
This API returns the FEC statistics of the cable
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to get the stats on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a dictionary:
a detailed format agreed upon by vendors
"""
raise NotImplementedError
def set_autoswitch_hysteresis_timer(self, time):
"""
This API sets the hysteresis timer of the cable. This is basically the time in auto-switch mode
which the mux has to wait after toggling it once, before again toggling the mux to a different ToR
The port on which this API is called for can be referred using self.port.
Args:
time:
an Integer, the time value for hysteresis to be set in milliseconds
Returns:
a boolean, True if the time is configured
, False if the time is not configured
"""
raise NotImplementedError
def get_autoswitch_hysteresis_timer(self):
"""
This API gets the hysteresis timer of the cable. This is basically the time in auto-switch mode
which the mux has to wait after toggling it once, before again toggling the mux to a different ToR
The port on which this API is called for can be referred using self.port.
Args:
Returns:
time:
an Integer, the time value for hysteresis is configured in milliseconds
"""
raise NotImplementedError
def restart_anlt(self, target):
"""
This API restarts auto-negotiation + link training (AN/LT) mode
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to restart AN/LT on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a boolean, True if restart is successful
, False if the restart is not successful
"""
raise NotImplementedError
def get_anlt_stats(self, target):
"""
This API returns auto-negotiation + link training (AN/LT) mode statistics
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the actual target to get AN/LT stats on:
TARGET_NIC -> NIC,
TARGET_TOR_A -> TORA,
TARGET_TOR_B -> TORB
Returns:
a dictionary:
a detailed format agreed upon by vendors
"""
raise NotImplementedError
#############################################################################################
### Debug Functionality ###
#############################################################################################
def set_debug_mode(self, enable):
"""
This API enables/disables a debug mode that the port is now
going to be run on. If enabled, this means that PRBS/Loopback etc. type diagnostic mode
is now going to be run on the port and hence normal traffic will be disabled
on it if enabled and vice-versa if disabled.
enable is typically to be used at the software level to inform the software
that debug APIs will be called afterwords.
disable will disable any previously enabled debug functionality inside the cable
so that traffic can pass through. Also it'll inform the software to come out of the debug mode.
The port on which this API is called for can be referred using self.port.
Args:
enable:
a boolean, True if the debug mode needs to be enabled
, False if the debug mode needs to be disabled
Returns:
a boolean, True if the enable is successful
, False if the enable failed
"""
raise NotImplementedError
def get_debug_mode(self):
"""
This API checks if a debug mode is currently being run on the port
for which this API is called for.
This means that PRBS/Loopback etc. type diagnostic mode
if any are being run on the port this should return True else False.
The port on which this API is called for can be referred using self.port.
Args:
Returns:
a boolean, True if debug mode enabled
, False if debug mode not enabled
"""
raise NotImplementedError
def enable_prbs_mode(self, target, mode_value, lane_mask, direction=PRBS_DIRECTION_BOTH):
"""
This API configures and enables the PRBS mode/type depending upon the mode_value the user provides.
The mode_value configures the PRBS Type for generation and BER sensing on a per side basis.
Target is an integer for selecting which end of the Y cable we want to run PRBS on.
LaneMap specifies the lane configuration to run the PRBS on.
Note that this is a diagnostic mode command and must not run during normal traffic/switch operation
The port on which this API is called for can be referred using self.port.
Args:
target:
One of the following predefined constants, the target on which to enable the PRBS:
EYE_PRBS_LOOPBACK_TARGET_LOCAL -> local side,
EYE_PRBS_LOOPBACK_TARGET_TOR_A -> TOR A