6
6
7
7
try :
8
8
import math
9
+ import time
9
10
import struct
10
11
from ctypes import c_int8
11
12
48
49
OFFSET_TOR1_CURSOR_VALUES = 681
49
50
OFFSET_TOR2_CURSOR_VALUES = 701
50
51
OFFSET_NIC_LANE_ACTIVE = 721
52
+ OFFSET_INTERNAL_TEMPERATURE = 22
53
+ OFFSET_INTERNAL_VOLTAGE = 26
54
+ OFFSET_NIC_TEMPERATURE = 727
55
+ OFFSET_NIC_VOLTAGE = 729
51
56
52
57
# definitions of targets for getting the cursor
53
58
# equalization parameters from the register spec
75
80
SWITCH_COUNT_MANUAL = "manual"
76
81
SWITCH_COUNT_AUTO = "auto"
77
82
83
+ FIRMWARE_INFO_PAYLOAD_SIZE = 48
84
+ NUM_MCU_SIDE = 3
85
+
86
+ EEPROM_READ_DATA_INVALID = - 1
87
+ EEPROM_ERROR = - 1
88
+ EEPROM_TIMEOUT_ERROR = - 1
89
+
90
+ BER_TIMEOUT_SECS = 1
91
+ EYE_TIMEOUT_SECS = 1
92
+
93
+ MAX_NUM_LANES = 4
94
+
78
95
SYSLOG_IDENTIFIER = "sonic_y_cable"
79
96
80
97
# Global logger instance for helper functions and classes to log
@@ -97,15 +114,15 @@ def y_cable_validate_read_data(result, size, physical_port, message):
97
114
if len (result ) != size :
98
115
LOG_MESSAGE_TEMPLATE = "Error: for checking mux_cable {}, eeprom read returned a size {} not equal to 1 for port {}"
99
116
helper_logger .log_error (LOG_MESSAGE_TEMPLATE .format (message , len (result ), physical_port ))
100
- return - 1
117
+ return EEPROM_READ_DATA_INVALID
101
118
else :
102
119
LOG_MESSAGE_TEMPLATE = "Error: for checking mux_cable {}, eeprom read returned an instance value of type {} which is not a bytearray for port {}"
103
120
helper_logger .log_error (LOG_MESSAGE_TEMPLATE .format (message , type (result ), physical_port ))
104
- return - 1
121
+ return EEPROM_READ_DATA_INVALID
105
122
else :
106
123
LOG_MESSAGE_TEMPLATE = "Error: for checking mux_cable {}, eeprom read returned a None value for port {} which is not expected"
107
124
helper_logger .log_error (LOG_MESSAGE_TEMPLATE .format (message , physical_port ))
108
- return - 1
125
+ return EEPROM_READ_DATA_INVALID
109
126
110
127
111
128
def hook_y_cable_simulator (target ):
@@ -573,7 +590,6 @@ def check_if_link_is_active_for_torB(physical_port):
573
590
return False
574
591
575
592
576
- @hook_y_cable_simulator
577
593
def enable_prbs_mode (physical_port , target , mode_value , lane_map ):
578
594
"""
579
595
This API specifically configures and enables the PRBS mode/type depending upon the mode_value the user provides.
@@ -646,7 +662,6 @@ def enable_prbs_mode(physical_port, target, mode_value, lane_map):
646
662
return result
647
663
648
664
649
- @hook_y_cable_simulator
650
665
def disable_prbs_mode (physical_port , target ):
651
666
"""
652
667
This API specifically disables the PRBS mode on the physcial port.
@@ -697,7 +712,6 @@ def disable_prbs_mode(physical_port, target):
697
712
return result
698
713
699
714
700
- @hook_y_cable_simulator
701
715
def enable_loopback_mode (physical_port , target , lane_map ):
702
716
"""
703
717
This API specifically configures and enables the Loopback mode on the port user provides.
@@ -755,7 +769,6 @@ def enable_loopback_mode(physical_port, target, lane_map):
755
769
return result
756
770
757
771
758
- @hook_y_cable_simulator
759
772
def disable_loopback_mode (physical_port , target ):
760
773
"""
761
774
This API specifically disables the Loopback mode on the port user provides.
@@ -809,7 +822,6 @@ def disable_loopback_mode(physical_port, target):
809
822
return result
810
823
811
824
812
- @hook_y_cable_simulator
813
825
def get_ber_info (physical_port , target ):
814
826
"""
815
827
This API specifically returns the BER (Bit error rate) value for a specfic port.
@@ -856,20 +868,27 @@ def get_ber_info(physical_port, target):
856
868
physical_port ).write_eeprom (curr_offset , 1 , buffer )
857
869
if result is False :
858
870
return result
871
+ time_start = time .time ()
859
872
while (True ):
860
873
done = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
861
- y_cable_validate_read_data (done , 1 , physical_port , "BER data ready to read" )
874
+ if y_cable_validate_read_data (done , 1 , physical_port , "BER data ready to read" ) == EEPROM_READ_DATA_INVALID :
875
+ return EEPROM_ERROR
876
+ time_now = time .time ()
877
+ time_diff = time_now - time_start
862
878
if done [0 ] == 1 :
863
879
break
880
+ elif time_diff >= BER_TIMEOUT_SECS :
881
+ return EEPROM_TIMEOUT_ERROR
864
882
865
883
idx = 0
866
- maxLane = 2
867
884
curr_offset = OFFSET_LANE_1_BER_RESULT
868
- for lane in range (maxLane ):
885
+ for lane in range (MAX_NUM_LANES ):
869
886
msb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + idx , 1 )
870
- y_cable_validate_read_data (msb_result , 1 , physical_port , "BER data msb result" )
887
+ if y_cable_validate_read_data (msb_result , 1 , physical_port , "BER data msb result" ) == EEPROM_READ_DATA_INVALID :
888
+ return EEPROM_ERROR
871
889
lsb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 1 + idx , 1 )
872
- y_cable_validate_read_data (lsb_result , 1 , physical_port , "BER data lsb result" )
890
+ if y_cable_validate_read_data (lsb_result , 1 , physical_port , "BER data lsb result" ) == EEPROM_READ_DATA_INVALID :
891
+ return EEPROM_ERROR
873
892
lane_result = msb_result [0 ] * math .pow (10 , (lsb_result [0 ]- 24 ))
874
893
ber_result .append (lane_result )
875
894
idx += 2
@@ -881,7 +900,6 @@ def get_ber_info(physical_port, target):
881
900
return ber_result
882
901
883
902
884
- @hook_y_cable_simulator
885
903
def get_eye_info (physical_port , target ):
886
904
"""
887
905
This API specifically returns the EYE height value for a specfic port.
@@ -927,20 +945,27 @@ def get_eye_info(physical_port, target):
927
945
if result is False :
928
946
return result
929
947
948
+ time_start = time .time ()
930
949
while (True ):
931
950
done = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
932
- y_cable_validate_read_data (done , 1 , physical_port , "EYE data ready to read" )
951
+ if y_cable_validate_read_data (done , 1 , physical_port , "EYE data ready to read" ) == EEPROM_READ_DATA_INVALID :
952
+ return EEPROM_ERROR
953
+ time_now = time .time ()
954
+ time_diff = time_now - time_start
933
955
if done [0 ] == 1 :
934
956
break
957
+ elif time_diff >= EYE_TIMEOUT_SECS :
958
+ return EEPROM_TIMEOUT_ERROR
935
959
936
960
idx = 0
937
- maxLane = 2
938
- for lane in range (maxLane ):
961
+ for lane in range (MAX_NUM_LANES ):
939
962
curr_offset = OFFSET_LANE_1_EYE_RESULT
940
963
msb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + idx , 1 )
941
- y_cable_validate_read_data (msb_result , 1 , physical_port , "EYE data msb result" )
964
+ if y_cable_validate_read_data (msb_result , 1 , physical_port , "EYE data msb result" ) == EEPROM_READ_DATA_INVALID :
965
+ return EEPROM_ERROR
942
966
lsb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 1 + idx , 1 )
943
- y_cable_validate_read_data (lsb_result , 1 , physical_port , "EYE data lsb result" )
967
+ if y_cable_validate_read_data (lsb_result , 1 , physical_port , "EYE data lsb result" ) == EEPROM_READ_DATA_INVALID :
968
+ return EEPROM_ERROR
944
969
lane_result = (msb_result [0 ] << 8 | lsb_result [0 ])
945
970
eye_result .append (lane_result )
946
971
idx += 2
@@ -952,7 +977,6 @@ def get_eye_info(physical_port, target):
952
977
return eye_result
953
978
954
979
955
- @hook_y_cable_simulator
956
980
def get_pn_number_and_vendor_name (physical_port ):
957
981
"""
958
982
This API specifically returns the pn number and vendor name for a specfic port.
@@ -968,10 +992,12 @@ def get_pn_number_and_vendor_name(physical_port):
968
992
969
993
if platform_chassis is not None :
970
994
pn_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 15 )
971
- y_cable_validate_read_data (pn_result , 1 , physical_port , "PN number" )
995
+ if y_cable_validate_read_data (pn_result , 15 , physical_port , "PN number" ) == EEPROM_READ_DATA_INVALID :
996
+ return EEPROM_ERROR
972
997
curr_offset = OFFSET_VENDOR_NAME
973
998
vendor_name = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 15 )
974
- y_cable_validate_read_data (vendor_name , 15 , physical_port , "vendor name" )
999
+ if y_cable_validate_read_data (vendor_name , 15 , physical_port , "vendor name" ) == EEPROM_READ_DATA_INVALID :
1000
+ return EEPROM_ERROR
975
1001
976
1002
else :
977
1003
helper_logger .log_error ("platform_chassis is not loaded, failed to get pin results" )
@@ -980,7 +1006,6 @@ def get_pn_number_and_vendor_name(physical_port):
980
1006
return pn_result , vendor_name
981
1007
982
1008
983
- @hook_y_cable_simulator
984
1009
def get_switch_count (physical_port , count_type ):
985
1010
"""
986
1011
This API specifically returns the switch count to change the Active TOR which has
@@ -1009,13 +1034,17 @@ def get_switch_count(physical_port, count_type):
1009
1034
1010
1035
if platform_chassis is not None :
1011
1036
msb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1012
- y_cable_validate_read_data (msb_result , 1 , physical_port , "{} switch count msb result" .format (count_type ))
1037
+ if y_cable_validate_read_data (msb_result , 1 , physical_port , "{} switch count msb result" .format (count_type )) == EEPROM_READ_DATA_INVALID :
1038
+ return EEPROM_ERROR
1013
1039
msb_result_1 = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 1 , 1 )
1014
- y_cable_validate_read_data (msb_result_1 , 1 , physical_port , "{} switch count msb result 1" .format (count_type ))
1040
+ if y_cable_validate_read_data (msb_result_1 , 1 , physical_port , "{} switch count msb result 1" .format (count_type )) == EEPROM_READ_DATA_INVALID :
1041
+ return EEPROM_ERROR
1015
1042
msb_result_2 = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 2 , 1 )
1016
- y_cable_validate_read_data (msb_result_2 , 1 , physical_port , "{} switch count msb result 2" .format (count_type ))
1043
+ if y_cable_validate_read_data (msb_result_2 , 1 , physical_port , "{} switch count msb result 2" .format (count_type )) == EEPROM_READ_DATA_INVALID :
1044
+ return EEPROM_ERROR
1017
1045
lsb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 3 , 1 )
1018
- y_cable_validate_read_data (lsb_result , 1 , physical_port , "{} switch count lsb result" .format (count_type ))
1046
+ if y_cable_validate_read_data (lsb_result , 1 , physical_port , "{} switch count lsb result" .format (count_type )) == EEPROM_READ_DATA_INVALID :
1047
+ return EEPROM_ERROR
1019
1048
count = (msb_result [0 ] << 24 | msb_result_1 [0 ] << 16 | msb_result_2 [0 ] << 8 | lsb_result [0 ])
1020
1049
1021
1050
else :
@@ -1025,7 +1054,6 @@ def get_switch_count(physical_port, count_type):
1025
1054
return count
1026
1055
1027
1056
1028
- @hook_y_cable_simulator
1029
1057
def get_target_cursor_values (physical_port , lane , target ):
1030
1058
"""
1031
1059
This API specifically returns the cursor equalization parameters for a target(NIC, TOR1, TOR2).
@@ -1055,19 +1083,24 @@ def get_target_cursor_values(physical_port, lane, target):
1055
1083
1056
1084
if platform_chassis is not None :
1057
1085
pre1 = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + (target )* 20 + (lane - 1 )* 5 , 1 )
1058
- y_cable_validate_read_data (pre1 , 1 , physical_port , "target cursor result" )
1086
+ if y_cable_validate_read_data (pre1 , 1 , physical_port , "target cursor result" ) == EEPROM_READ_DATA_INVALID :
1087
+ return EEPROM_ERROR
1059
1088
result .append (c_int8 (pre1 [0 ]).value )
1060
1089
pre2 = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + (target )* 20 + (lane - 1 )* 5 + 1 , 1 )
1061
- y_cable_validate_read_data (pre2 , 1 , physical_port , "target cursor result" )
1090
+ if y_cable_validate_read_data (pre2 , 1 , physical_port , "target cursor result" ) == EEPROM_READ_DATA_INVALID :
1091
+ return EEPROM_ERROR
1062
1092
result .append (c_int8 (pre2 [0 ]).value )
1063
1093
main = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + (target )* 20 + (lane - 1 )* 5 + 2 , 1 )
1064
- y_cable_validate_read_data (main , 1 , physical_port , "target cursor result" )
1094
+ if y_cable_validate_read_data (main , 1 , physical_port , "target cursor result" ) == EEPROM_READ_DATA_INVALID :
1095
+ return EEPROM_ERROR
1065
1096
result .append (c_int8 (main [0 ]).value )
1066
1097
post1 = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + (target )* 20 + (lane - 1 )* 5 + 3 , 1 )
1067
- y_cable_validate_read_data (post1 , 1 , physical_port , "target cursor result" )
1098
+ if y_cable_validate_read_data (post1 , 1 , physical_port , "target cursor result" ) == EEPROM_READ_DATA_INVALID :
1099
+ return EEPROM_ERROR
1068
1100
result .append (c_int8 (post1 [0 ]).value )
1069
1101
post2 = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + (target )* 20 + (lane - 1 )* 5 + 4 , 1 )
1070
- y_cable_validate_read_data (post2 , 1 , physical_port , "target cursor result" )
1102
+ if y_cable_validate_read_data (post2 , 1 , physical_port , "target cursor result" ) == EEPROM_READ_DATA_INVALID :
1103
+ return EEPROM_ERROR
1071
1104
result .append (c_int8 (post2 [0 ]).value )
1072
1105
1073
1106
else :
@@ -1077,7 +1110,6 @@ def get_target_cursor_values(physical_port, lane, target):
1077
1110
return result
1078
1111
1079
1112
1080
- @hook_y_cable_simulator
1081
1113
def check_if_nic_lanes_active (physical_port ):
1082
1114
"""
1083
1115
This API specifically returns the byte value which denotes which nic lanes
@@ -1097,11 +1129,111 @@ def check_if_nic_lanes_active(physical_port):
1097
1129
1098
1130
if platform_chassis is not None :
1099
1131
res = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1100
- y_cable_validate_read_data (res , 1 , physical_port , "nic lanes active" )
1132
+ if y_cable_validate_read_data (res , 1 , physical_port , "nic lanes active" ) == EEPROM_READ_DATA_INVALID :
1133
+ return EEPROM_ERROR
1101
1134
result = res [0 ]
1102
1135
1103
1136
else :
1104
1137
helper_logger .log_error ("platform_chassis is not loaded, failed to get NIC lanes active" )
1105
1138
return - 1
1106
1139
1107
1140
return result
1141
+
1142
+
1143
+ def get_firmware_version (physical_port , target ):
1144
+
1145
+ data = bytearray (FIRMWARE_INFO_PAYLOAD_SIZE )
1146
+
1147
+ if platform_chassis is not None :
1148
+ for byte_idx in range (0 , FIRMWARE_INFO_PAYLOAD_SIZE ):
1149
+ curr_offset = 0xfc * 128 + 128 + byte_idx
1150
+ read_out = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1151
+ if y_cable_validate_read_data (read_out , 1 , physical_port , "firmware info" ) == EEPROM_READ_DATA_INVALID :
1152
+ return EEPROM_ERROR
1153
+ data [byte_idx ] = read_out [0 ]
1154
+ else :
1155
+ helper_logger .log_error ("platform_chassis is not loaded, failed to get NIC lanes active" )
1156
+ return - 1
1157
+
1158
+ result = {}
1159
+ NUM_MCU_SIDE = 3
1160
+
1161
+ base_addr = int (target * (FIRMWARE_INFO_PAYLOAD_SIZE / NUM_MCU_SIDE ))
1162
+ rev_major_slot1 = struct .unpack_from ('<B' , data [(0 + base_addr ):(1 + base_addr )])[0 ]
1163
+ rev_minor_slot1 = struct .unpack_from ('<B' , data [(2 + base_addr ):(3 + base_addr )])[0 ]
1164
+ rev_build_lsb_slot1 = struct .unpack_from ('<B' , data [(4 + base_addr ):(5 + base_addr )])[0 ]
1165
+ rev_build_msb_slot1 = struct .unpack_from ('<B' , data [(5 + base_addr ):(6 + base_addr )])[0 ]
1166
+ rev_major_slot2 = struct .unpack_from ('<B' , data [(1 + base_addr ):(2 + base_addr )])[0 ]
1167
+ rev_minor_slot2 = struct .unpack_from ('<B' , data [(3 + base_addr ):(4 + base_addr )])[0 ]
1168
+ rev_build_lsb_slot2 = struct .unpack_from ('<B' , data [(6 + base_addr ):(7 + base_addr )])[0 ]
1169
+ rev_build_msb_slot2 = struct .unpack_from ('<B' , data [(7 + base_addr ):(8 + base_addr )])[0 ]
1170
+ slot_status = struct .unpack_from ('<B' , data [(8 + base_addr ):(9 + base_addr )])[0 ]
1171
+
1172
+ if (rev_major_slot1 == 0 and rev_minor_slot1 == 0 and rev_build_lsb_slot1 == 0 and rev_build_msb_slot1 == 0 and rev_major_slot2 == 0 and rev_minor_slot2 == 0 and rev_build_lsb_slot2 == 0 and rev_build_msb_slot2 == 0 ):
1173
+ return None
1174
+ else :
1175
+ build_slot1 = chr (rev_build_lsb_slot1 ) + chr (rev_build_msb_slot1 )
1176
+ version_slot1 = str (rev_major_slot1 ) + "." + str (rev_minor_slot1 )
1177
+ build_slot2 = chr (rev_build_lsb_slot2 ) + chr (rev_build_msb_slot2 )
1178
+ version_slot2 = str (rev_major_slot2 ) + "." + str (rev_minor_slot2 )
1179
+
1180
+ result ["build_slot1" ] = build_slot1
1181
+ result ["version_slot1" ] = version_slot1
1182
+ result ["build_slot2" ] = build_slot2
1183
+ result ["version_slot2" ] = version_slot2
1184
+ result ["run_slot1" ] = True if slot_status & 0x01 else False
1185
+ result ["run_slot2" ] = True if slot_status & 0x10 else False
1186
+ result ["commit_slot1" ] = True if slot_status & 0x02 else False
1187
+ result ["commit_slot2" ] = True if slot_status & 0x20 else False
1188
+ result ["empty_slot1" ] = True if slot_status & 0x04 else False
1189
+ result ["empty_slot2" ] = True if slot_status & 0x40 else False
1190
+
1191
+ return result
1192
+
1193
+
1194
+ def get_internal_voltage_temp (physical_port ):
1195
+
1196
+ curr_offset = OFFSET_INTERNAL_TEMPERATURE
1197
+ if platform_chassis is not None :
1198
+ result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1199
+ if y_cable_validate_read_data (result , 1 , physical_port , "internal voltage" ) == EEPROM_READ_DATA_INVALID :
1200
+ return EEPROM_ERROR
1201
+ curr_offset = OFFSET_INTERNAL_VOLTAGE
1202
+ msb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1203
+ if y_cable_validate_read_data (msb_result , 1 , physical_port , "internal temperature msb" ) == EEPROM_READ_DATA_INVALID :
1204
+ return EEPROM_ERROR
1205
+ lsb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 1 , 1 )
1206
+ if y_cable_validate_read_data (lsb_result , 1 , physical_port , "internal temperature lsb" ) == EEPROM_READ_DATA_INVALID :
1207
+ return EEPROM_ERROR
1208
+
1209
+ temp = result [0 ]
1210
+ voltage = (((msb_result [0 ] << 8 ) | lsb_result [0 ]) * 0.0001 )
1211
+ else :
1212
+ helper_logger .log_error ("platform_chassis is not loaded, failed to get internal voltage and temp" )
1213
+ return - 1
1214
+
1215
+ return temp , voltage
1216
+
1217
+
1218
+ def get_nic_voltage_temp (physical_port ):
1219
+
1220
+ curr_offset = OFFSET_NIC_TEMPERATURE
1221
+ if platform_chassis is not None :
1222
+ result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1223
+ if y_cable_validate_read_data (result , 1 , physical_port , "internal voltage" ) == EEPROM_READ_DATA_INVALID :
1224
+ return EEPROM_ERROR
1225
+ curr_offset = OFFSET_NIC_VOLTAGE
1226
+ msb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset , 1 )
1227
+ if y_cable_validate_read_data (msb_result , 1 , physical_port , "internal temperature msb" ) == EEPROM_READ_DATA_INVALID :
1228
+ return EEPROM_ERROR
1229
+ lsb_result = platform_chassis .get_sfp (physical_port ).read_eeprom (curr_offset + 1 , 1 )
1230
+ if y_cable_validate_read_data (lsb_result , 1 , physical_port , "internal temperature lsb" ) == EEPROM_READ_DATA_INVALID :
1231
+ return EEPROM_ERROR
1232
+
1233
+ temp = result [0 ]
1234
+ voltage = (((msb_result [0 ] << 8 ) | lsb_result [0 ]) * 0.0001 )
1235
+ else :
1236
+ helper_logger .log_error ("platform_chassis is not loaded, failed to get NIC voltage and temp" )
1237
+ return - 1
1238
+
1239
+ return temp , voltage
0 commit comments