diff --git a/sonic_y_cable/credo/y_cable_credo.py b/sonic_y_cable/credo/y_cable_credo.py index 3a888f727665..81a1a54174f6 100644 --- a/sonic_y_cable/credo/y_cable_credo.py +++ b/sonic_y_cable/credo/y_cable_credo.py @@ -7,6 +7,9 @@ import math import time import struct +import threading +from contextlib import contextmanager + from ctypes import c_int8 from sonic_y_cable.y_cable_base import YCableBase @@ -15,6 +18,18 @@ except ImportError as e: pass +class RLocker(): + ACQUIRE_LOCK_TIMEOUT = 15 + + def __init__(self): + self.rlock = threading.RLock() + + @contextmanager + def acquire_timeout(self, timeout): + result = self.rlock.acquire(timeout=timeout) + yield result + if result: + self.rlock.release() class YCable(YCableBase): # definitions of the offset with width accommodated for values @@ -120,6 +135,7 @@ class YCable(YCableBase): EYE_TIMEOUT_SECS = 1 GET_DEBUG_MODE_TIMEOUT_SECS = 1 EXTEND_SWITCH_CNT_TIMEOUT_SECS = 1 + FWUPD_UART_XFER_TIMEOUT_SECS = 120 # error code of EEPROM EEPROM_READ_DATA_INVALID = -1 @@ -179,6 +195,7 @@ def __init__(self, port, main_logger): YCableBase.__init__(self, port, main_logger) self.platform_chassis = None + self.rlock = RLocker() try: self.platform_chassis = sonic_platform.platform.Platform().get_chassis() @@ -502,7 +519,12 @@ def toggle_mux_to_tor_a(self): curr_offset = YCable.OFFSET_SWITCH_MUX_DIRECTION if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to toggle mux to TOR A') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to toggle mux to TOR A") return YCable.EEPROM_ERROR @@ -527,7 +549,12 @@ def toggle_mux_to_tor_b(self): curr_offset = YCable.OFFSET_SWITCH_MUX_DIRECTION if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to toggle mux to TOR B') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to toggle mux to TOR B") return YCable.EEPROM_ERROR @@ -553,7 +580,12 @@ def get_read_side(self): curr_offset = YCable.OFFSET_DETERMINE_CABLE_READ_SIDE if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + else: + self.log_error('acquire lock timeout, failed to check read side') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to check read side") return YCable.EEPROM_ERROR @@ -608,10 +640,15 @@ def get_mux_direction(self): curr_offset = YCable.OFFSET_MUX_DIRECTION if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + else: + self.log_error('acquire lock timeout, failed to get mux direction') + return YCableBase.EEPROM_ERROR else: self.log_error( - "platform_chassis is not loaded, failed to check Active Linked and routing TOR side") + "platform_chassis is not loaded, failed to get mux direction") return YCable.EEPROM_ERROR if result is not None: @@ -661,7 +698,12 @@ def get_active_linked_tor_side(self): curr_offset = YCable.OFFSET_ACTIVE_TOR_INDICATOR if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + else: + self.log_error('acquire lock timeout, failed to check Active Linked and routing TOR side') + return YCableBase.EEPROM_ERROR else: self.log_error( "platform_chassis is not loaded, failed to check Active Linked and routing TOR side") @@ -717,7 +759,12 @@ def is_link_active(self, target): curr_offset = YCable.OFFSET_CHECK_LINK_ACTIVE if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + else: + self.log_error('acquire lock timeout, failed to check if link is Active on target side') + return YCableBase.EEPROM_ERROR else: self.log_error( "platform_chassis is not loaded, failed to check if link is Active on target side") @@ -772,39 +819,44 @@ def get_eye_heights(self, target): eye_result = [] if self.platform_chassis is not None: - buffer = bytearray([target]) - curr_offset = YCable.OFFSET_TARGET - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - - buffer = bytearray([0]) - curr_offset = YCable.OFFSET_INITIATE_EYE_MEASUREMENT - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - - time_start = time.time() - while(True): - done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - time_now = time.time() - time_diff = time_now - time_start - if done[0] == 1: - break - elif time_diff >= YCable.EYE_TIMEOUT_SECS: - return YCable.EEPROM_TIMEOUT_ERROR - - idx = 0 - for lane in range(YCable.MAX_NUM_LANES): - curr_offset = YCable.OFFSET_LANE_1_EYE_RESULT - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + idx, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + idx + 1, 1) - - lane_result = (msb_result[0] << 8 | lsb_result[0]) - eye_result.append(lane_result) - idx += 2 + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + buffer = bytearray([target]) + curr_offset = YCable.OFFSET_TARGET + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + + buffer = bytearray([0]) + curr_offset = YCable.OFFSET_INITIATE_EYE_MEASUREMENT + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + + time_start = time.time() + while(True): + done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + time_now = time.time() + time_diff = time_now - time_start + if done[0] == 1: + break + elif time_diff >= YCable.EYE_TIMEOUT_SECS: + return YCable.EEPROM_TIMEOUT_ERROR + + idx = 0 + for lane in range(YCable.MAX_NUM_LANES): + curr_offset = YCable.OFFSET_LANE_1_EYE_RESULT + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + idx, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + idx + 1, 1) + + lane_result = (msb_result[0] << 8 | lsb_result[0]) + eye_result.append(lane_result) + idx += 2 + else: + self.log_error('acquire lock timeout, failed to get eye height') + return YCableBase.EEPROM_ERROR else: - self.log_error("platform_chassis is not loaded, failed to configure the PRBS type") + self.log_error("platform_chassis is not loaded, failed to get eye height") return YCable.EEPROM_ERROR return eye_result @@ -823,7 +875,12 @@ def get_vendor(self): curr_offset = YCable.OFFSET_VENDOR_NAME if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 16) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 16) + else: + self.log_error('acquire lock timeout, failed to get vendor name') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get Vendor name") return YCable.EEPROM_ERROR @@ -845,7 +902,12 @@ def get_part_number(self): curr_offset = YCable.OFFSET_PART_NUMBER if self.platform_chassis is not None: - part_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 16) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + part_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 16) + else: + self.log_error('acquire lock timeout, failed to get part number') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get part number") return YCable.EEPROM_ERROR @@ -867,9 +929,14 @@ def get_serial_number(self): curr_offset = YCable.OFFSET_SERIAL_NUMBER if self.platform_chassis is not None: - part_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 16) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + part_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 16) + else: + self.log_error('acquire lock timeout, failed to get serial number') + return YCableBase.EEPROM_ERROR else: - self.log_error("platform_chassis is not loaded, failed to get part number") + self.log_error("platform_chassis is not loaded, failed to get serial number") return YCable.EEPROM_ERROR part_number = str(part_result.decode()) @@ -896,32 +963,40 @@ def get_switch_count_total(self, switch_count_type, clear_on_read=False): count = 0 - if switch_count_type == YCableBase.SWITCH_COUNT_MANUAL: - count = self.get_switch_count_tor_a(clear_on_read) + self.get_switch_count_tor_b(clear_on_read) - elif switch_count_type == YCableBase.SWITCH_COUNT_AUTO: - curr_offset = YCable.OFFSET_AUTO_SWITCH_COUNT - - if self.platform_chassis is not None: - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) - msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+3, 1) - count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + if self.platform_chassis is not None: + if switch_count_type == YCableBase.SWITCH_COUNT_MANUAL: + count = self.get_switch_count_tor_a(clear_on_read) + self.get_switch_count_tor_b(clear_on_read) + elif switch_count_type == YCableBase.SWITCH_COUNT_AUTO: + curr_offset = YCable.OFFSET_AUTO_SWITCH_COUNT + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) + msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 3, 1) + count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + else: + self.log_error('acquire lock timeout, failed to get switch count') + return YCableBase.EEPROM_ERROR else: - self.log_error("platform_chassis is not loaded, failed to get manual switch count") + self.log_error("not a valid switch_count_type, failed to get switch count") return YCable.EEPROM_ERROR - else: - self.log_error("not a valid switch_count_type, failed to get switch count") - return YCable.EEPROM_ERROR - if clear_on_read: - if switch_count_type == YCableBase.SWITCH_COUNT_AUTO: - curr_offset = YCable.OFFSET_AUTO_SWITCH_COUNT - buffer = bytearray([6]) - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return YCable.EEPROM_ERROR + if clear_on_read: + if switch_count_type == YCableBase.SWITCH_COUNT_AUTO: + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_AUTO_SWITCH_COUNT + buffer = bytearray([6]) + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return YCable.EEPROM_ERROR + else: + self.log_error('acquire lock timeout, failed to clear switch count') + return YCableBase.EEPROM_ERROR + else: + self.log_error("platform_chassis is not loaded, failed to get switch count") + return YCable.EEPROM_ERROR return count @@ -946,23 +1021,26 @@ def get_switch_count_tor_a(self, clear_on_read=False): count = 0 if self.platform_chassis is not None: - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) - msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+3, 1) - count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) + msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+3, 1) + count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + + buffer = bytearray([4]) + curr_offset = YCable.OFFSET_CLEAR_SWITCH_COUNT + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return YCable.EEPROM_ERROR + else: + self.log_error('acquire lock timeout, failed to get switch count (tor A)') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get manual switch count") return YCable.EEPROM_ERROR - if clear_on_read: - buffer = bytearray([4]) - curr_offset = YCable.OFFSET_CLEAR_SWITCH_COUNT - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return YCable.EEPROM_ERROR - return count def get_switch_count_tor_b(self, clear_on_read=False): @@ -986,23 +1064,27 @@ def get_switch_count_tor_b(self, clear_on_read=False): count = 0 if self.platform_chassis is not None: - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) - msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+3, 1) - count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) + msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+3, 1) + count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + + if clear_on_read: + buffer = bytearray([5]) + curr_offset = YCable.OFFSET_CLEAR_SWITCH_COUNT + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return YCable.EEPROM_ERROR + else: + self.log_error('acquire lock timeout, failed to get switch count (tor B)') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get manual switch count") return YCable.EEPROM_ERROR - if clear_on_read: - buffer = bytearray([5]) - curr_offset = YCable.OFFSET_CLEAR_SWITCH_COUNT - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return YCable.EEPROM_ERROR - return count def get_switch_count_target(self, switch_count_type, target, clear_on_read=False): @@ -1052,33 +1134,36 @@ def get_switch_count_target(self, switch_count_type, target, clear_on_read=False return YCable.EEPROM_ERROR if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return YCable.EEPROM_ERROR - time_start = time.time() - while(True): - done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - time_now = time.time() - time_diff = time_now - time_start - if done[0] & 0x80: - break - elif time_diff >= YCable.EXTEND_SWITCH_CNT_TIMEOUT_SECS: - return YCable.EEPROM_TIMEOUT_ERROR - - curr_offset = YCable.OFFSET_EXTEND_SWITCH_COUNT - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 3, 1) - msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) - msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) - - if clear_on_read: - curr_offset = YCable.OFFSET_CLEAR_SWITCH_COUNT - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return YCable.EEPROM_ERROR + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return YCable.EEPROM_ERROR + time_start = time.time() + while(True): + done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + time_now = time.time() + time_diff = time_now - time_start + if done[0] & 0x80: + break + elif time_diff >= YCable.EXTEND_SWITCH_CNT_TIMEOUT_SECS: + return YCable.EEPROM_TIMEOUT_ERROR + + curr_offset = YCable.OFFSET_EXTEND_SWITCH_COUNT + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 3, 1) + msb_result_1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 2, 1) + msb_result_2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + 1, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + count = (msb_result[0] << 24 | msb_result_1[0] << 16 | msb_result_2[0] << 8 | lsb_result[0]) + + if clear_on_read: + curr_offset = YCable.OFFSET_CLEAR_SWITCH_COUNT + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return YCable.EEPROM_ERROR + else: + self.log_error('acquire lock timeout, failed to get switch count target') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get switch count target") return YCable.EEPROM_ERROR @@ -1112,16 +1197,21 @@ def get_target_cursor_values(self, lane, target): result = [] if self.platform_chassis is not None: - pre1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5, 1) - result.append(c_int8(pre1[0]).value) - pre2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 1, 1) - result.append(c_int8(pre2[0]).value) - main = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 2, 1) - result.append(c_int8(main[0]).value) - post1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 3, 1) - result.append(c_int8(post1[0]).value) - post2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 4, 1) - result.append(c_int8(post2[0]).value) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + pre1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5, 1) + result.append(c_int8(pre1[0]).value) + pre2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 1, 1) + result.append(c_int8(pre2[0]).value) + main = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 2, 1) + result.append(c_int8(main[0]).value) + post1 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 3, 1) + result.append(c_int8(post1[0]).value) + post2 = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset + (target)*20 + (lane-1)*5 + 4, 1) + result.append(c_int8(post2[0]).value) + else: + self.log_error('acquire lock timeout, failed to get target cursor values') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get target cursor values") return YCable.EEPROM_ERROR @@ -1155,12 +1245,17 @@ def set_target_cursor_values(self, lane, cursor_values, target): curr_offset = YCable.OFFSET_NIC_CURSOR_VALUES idx = 0 if self.platform_chassis is not None: - for data in cursor_values: - data = data & 0xFF - buffer = bytearray([data]) - self.platform_chassis.get_sfp(self.port).write_eeprom( - curr_offset + (target)*20 + (lane-1)*5 + idx, 1, buffer) - idx += 1 + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + for data in cursor_values: + data = data & 0xFF + buffer = bytearray([data]) + self.platform_chassis.get_sfp(self.port).write_eeprom( + curr_offset + (target)*20 + (lane-1)*5 + idx, 1, buffer) + idx += 1 + else: + self.log_error('acquire lock timeout, failed to set target cursor values') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get target cursor values") return YCable.EEPROM_ERROR @@ -1186,20 +1281,28 @@ def get_firmware_version(self, target): and their corresponding values """ - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_GET_INFO - self.send_vsc(vsc_req_form) - - data = bytearray(YCable.FIRMWARE_INFO_PAYLOAD_SIZE) - if self.platform_chassis is not None: - for byte_idx in range(0, YCable.FIRMWARE_INFO_PAYLOAD_SIZE): - curr_offset = 0xfc * 128 + 128 + byte_idx - read_out = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - data[byte_idx] = read_out[0] + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_GET_INFO + status = self.send_vsc(vsc_req_form) + + if status != YCable.MCU_EC_NO_ERROR: + self.log_error('Get firmware version error (error code:0x%04X)' % (status)) + return None + + data = bytearray(YCable.FIRMWARE_INFO_PAYLOAD_SIZE) + for byte_idx in range(0, YCable.FIRMWARE_INFO_PAYLOAD_SIZE): + curr_offset = 0xfc * 128 + 128 + byte_idx + read_out = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + data[byte_idx] = read_out[0] + else: + self.log_error('acquire lock timeout, failed to get firmware version') + return None else: - self.log_error("platform_chassis is not loaded, failed to get NIC lanes active") + self.log_error("platform_chassis is not loaded, failed to get firmware version") return YCable.EEPROM_ERROR result = {} @@ -1274,24 +1377,37 @@ def download_firmware(self, fwfile): """ if self.platform_chassis is not None: - inFile = open(fwfile, 'rb') fwImage = bytearray(inFile.read()) inFile.close() + bin_pid = struct.unpack_from('>B', fwImage[5 : 6])[0] + mcu_pid = self.read_mmap(0xFB, 187) + + if bin_pid != mcu_pid: + self.log_error('Firmware binary ID Mismatched Bin[%d] MCU[%d]' % (bin_pid, mcu_pid)) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_INPROGRESS ''' Firmware update start ''' - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_START - status = self.send_vsc(vsc_req_form) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error(YCable.MCU_ERROR_CODE_STRING[status]) - self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED - return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_START + status = self.send_vsc(vsc_req_form) + if status != YCable.MCU_EC_NO_ERROR: + self.log_error(YCable.MCU_ERROR_CODE_STRING[status]) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + else: + self.log_error('acquire lock timeout, failed to start firmware update') + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE ''' Transfer firmwre image to local side MCU @@ -1300,99 +1416,111 @@ def download_firmware(self, fwfile): chunk_idx = 0 retry_count = 0 while chunk_idx < total_chunk: - checksum = 0 - fw_img_offset = chunk_idx * YCable.VSC_BUFF_SIZE - for byte_offset in range(YCable.VSC_BUFF_SIZE): - checksum += fwImage[fw_img_offset] - fw_img_offset += 1 - if (((byte_offset + 1) % YCable.VSC_BLOCK_WRITE_LENGTH) == 0): - page = YCable.MIS_PAGE_FC + byte_offset // 128 - byte = 128 + ((byte_offset + 1) - YCable.VSC_BLOCK_WRITE_LENGTH) % 128 - self.write_mmap(page, byte, bytearray( - fwImage[fw_img_offset - YCable.VSC_BLOCK_WRITE_LENGTH: fw_img_offset]), YCable.VSC_BLOCK_WRITE_LENGTH) - - fw_img_offset = chunk_idx * YCable.VSC_BUFF_SIZE - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_LOCAL_XFER - vsc_req_form[YCable.VSC_BYTE_ADDR0] = (fw_img_offset >> 0) & 0xFF - vsc_req_form[YCable.VSC_BYTE_ADDR1] = (fw_img_offset >> 8) & 0xFF - vsc_req_form[YCable.VSC_BYTE_ADDR2] = (fw_img_offset >> 16) & 0xFF - vsc_req_form[YCable.VSC_BYTE_ADDR3] = (fw_img_offset >> 24) & 0xFF - vsc_req_form[YCable.VSC_BYTE_CHKSUM_MSB] = (checksum >> 8) & 0xFF - vsc_req_form[YCable.VSC_BYTE_CHKSUM_LSB] = (checksum >> 0) & 0xFF - status = self.send_vsc(vsc_req_form) - - if status == YCable.MCU_EC_NO_ERROR: - chunk_idx += 1 - retry_count = 0 - else: - self.log_error('Firmware binary transfer error (error code:%04X)' % (status)) - - if retry_count == 3: - self.log_error('Retry Xfer Fw Bin Error, abort firmware update') + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + checksum = 0 + fw_img_offset = chunk_idx * YCable.VSC_BUFF_SIZE + for byte_offset in range(YCable.VSC_BUFF_SIZE): + checksum += fwImage[fw_img_offset] + fw_img_offset += 1 + if (((byte_offset + 1) % YCable.VSC_BLOCK_WRITE_LENGTH) == 0): + page = YCable.MIS_PAGE_FC + byte_offset // 128 + byte = 128 + ((byte_offset + 1) - YCable.VSC_BLOCK_WRITE_LENGTH) % 128 + self.write_mmap(page, byte, bytearray( + fwImage[fw_img_offset - YCable.VSC_BLOCK_WRITE_LENGTH: fw_img_offset]), YCable.VSC_BLOCK_WRITE_LENGTH) + + fw_img_offset = chunk_idx * YCable.VSC_BUFF_SIZE + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_LOCAL_XFER + vsc_req_form[YCable.VSC_BYTE_ADDR0] = (fw_img_offset >> 0) & 0xFF + vsc_req_form[YCable.VSC_BYTE_ADDR1] = (fw_img_offset >> 8) & 0xFF + vsc_req_form[YCable.VSC_BYTE_ADDR2] = (fw_img_offset >> 16) & 0xFF + vsc_req_form[YCable.VSC_BYTE_ADDR3] = (fw_img_offset >> 24) & 0xFF + vsc_req_form[YCable.VSC_BYTE_CHKSUM_MSB] = (checksum >> 8) & 0xFF + vsc_req_form[YCable.VSC_BYTE_CHKSUM_LSB] = (checksum >> 0) & 0xFF + status = self.send_vsc(vsc_req_form) + + if status == YCable.MCU_EC_NO_ERROR: + chunk_idx += 1 + retry_count = 0 + else: + self.log_error('Firmware binary transfer error (error code:%04X)' % (status)) + + if retry_count == 3: + self.log_error('Retry Xfer Fw Bin Error, abort firmware update') + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + retry_count += 1 + else: + self.log_error('acquire lock timeout, failed to xfer firmware') self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED return YCableBase.FIRMWARE_DOWNLOAD_FAILURE - retry_count += 1 ''' Complete the local side firmware transferring ''' - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_LOCAL_XFER_COMPLETE - status = self.send_vsc(vsc_req_form) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error('Veriyf firmware binary error (error code:0x%04X)' % (status)) - self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED - return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_LOCAL_XFER_COMPLETE + status = self.send_vsc(vsc_req_form) + if status != YCable.MCU_EC_NO_ERROR: + self.log_error('Veriyf firmware binary error (error code:0x%04X)' % (status)) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + else: + self.log_error('acquire lock timeout, failed to complete firmware xfer') + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE ''' transfer firmware image from local side MCU to the other two via UART ''' - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_UART_XFER - status = self.send_vsc(vsc_req_form) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error('Firmware binary UART transfer error (error code:0x%04X)' % (status)) - self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED - return YCableBase.FIRMWARE_DOWNLOAD_FAILURE - - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_UART_XFER_STATUS - status = self.send_vsc(vsc_req_form) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error( - 'Get firmware binary UART transfer status error (error code:0x%04X)' % (status)) - self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED - return YCableBase.FIRMWARE_DOWNLOAD_FAILURE - - busy = self.read_mmap(YCable.MIS_PAGE_FC, 128) - self.read_mmap(YCable.MIS_PAGE_FC, 129) - self.read_mmap(YCable.MIS_PAGE_FC, 130) - self.read_mmap(YCable.MIS_PAGE_FC, 131) - - while busy != 0: - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_UART_XFER_STATUS - status = self.send_vsc(vsc_req_form) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error( - 'Get firmware binary UART transfer status error (error code:0x%04X)' % (status)) - + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_UART_XFER + status = self.send_vsc(vsc_req_form) + if status != YCable.MCU_EC_NO_ERROR: + self.log_error('Firmware binary UART transfer error (error code:0x%04X)' % (status)) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + else: + self.log_error('acquire lock timeout, failed to uart xfer') self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED return YCableBase.FIRMWARE_DOWNLOAD_FAILURE - time.sleep(0.2) - busy = self.read_mmap(YCable.MIS_PAGE_FC, 128) - self.read_mmap(YCable.MIS_PAGE_FC, 129) - self.read_mmap(YCable.MIS_PAGE_FC, 130) - self.read_mmap(YCable.MIS_PAGE_FC, 131) - - self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_NOT_INITIATED_OR_FINISHED + uartXferStartTime = time.time() + while True: + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_UART_XFER_STATUS + status = self.send_vsc(vsc_req_form) + + busy = self.read_mmap(YCable.MIS_PAGE_FC, 128) + self.read_mmap(YCable.MIS_PAGE_FC, 129) + self.read_mmap(YCable.MIS_PAGE_FC, 130) + self.read_mmap(YCable.MIS_PAGE_FC, 131) + + if busy == 0: + break + + if (time.time() - uartXferStartTime) > YCable.FWUPD_UART_XFER_TIMEOUT_SECS: + self.log_error( + 'Get firmware binary UART transfer status error (error code:0x%04X)' % (status)) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE + + time.sleep(1) + else: + self.log_error('acquire lock timeout, failed to get uart xfer status') + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_DOWNLOAD_FAILURE else: self.log_error("platform_chassis is not loaded, failed to download firmware") return YCable.EEPROM_ERROR @@ -1438,27 +1566,38 @@ def activate_firmware(self, fwfile=None, hitless=False): """ if self.platform_chassis is not None: if fwfile is None: - side = 0x7 - - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_COMMIT - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_ADDR0] = side - status = self.send_vsc(vsc_req_form) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error(YCable.MCU_ERROR_CODE_STRING[status]) - return YCableBase.FIRMWARE_ACTIVATE_FAILURE - - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_RUN - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_ADDR0] = side - vsc_req_form[YCable.VSC_BYTE_ADDR1] = hitless - status = self.send_vsc(vsc_req_form) - time.sleep(5) - if status != YCable.MCU_EC_NO_ERROR: - self.log_error(YCable.MCU_ERROR_CODE_STRING[status]) - return YCableBase.FIRMWARE_ACTIVATE_FAILURE + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_INPROGRESS + side = 0x7 + + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_COMMIT + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_ADDR0] = side + status = self.send_vsc(vsc_req_form) + if status != YCable.MCU_EC_NO_ERROR: + self.log_error(YCable.MCU_ERROR_CODE_STRING[status]) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_ACTIVATE_FAILURE + + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_RUN + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_ADDR0] = side + vsc_req_form[YCable.VSC_BYTE_ADDR1] = hitless + status = self.send_vsc(vsc_req_form) + time.sleep(5) + if status != YCable.MCU_EC_NO_ERROR: + self.log_error(YCable.MCU_ERROR_CODE_STRING[status]) + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_ACTIVATE_FAILURE + + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_NOT_INITIATED_OR_FINISHED + else: + self.log_error('acquire lock timeout, failed to activate firmware') + self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_FAILED + return YCableBase.FIRMWARE_ACTIVATE_FAILURE else: inFile = open(fwfile, 'rb') fwImage = bytearray(inFile.read()) @@ -1477,10 +1616,6 @@ def activate_firmware(self, fwfile=None, hitless=False): return YCableBase.FIRMWARE_ACTIVATE_SUCCESS elif fwVer['version_inactive'] == version_build_file: return self.activate_firmware(hitless=hitless) - else: - if self.download_firmware(fwfile) != YCableBase.FIRMWARE_DOWNLOAD_SUCCESS: - return YCableBase.FIRMWARE_ACTIVATE_FAILURE - return self.activate_firmware(fwfile, hitless) else: self.log_error("platform_chassis is not loaded, failed to activate firmware") return YCable.EEPROM_ERROR @@ -1558,10 +1693,14 @@ def set_switching_mode(self, mode): curr_offset = YCable.OFFSET_ENABLE_AUTO_SWITCH if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to set switching mode') + return YCableBase.EEPROM_ERROR else: - self.log_error("platform_chassis is not loaded, failed to do a switch target") + self.log_error("platform_chassis is not loaded, failed to set switching mode") return YCable.EEPROM_ERROR return result @@ -1581,16 +1720,22 @@ def get_switching_mode(self): curr_offset = YCable.OFFSET_ENABLE_AUTO_SWITCH if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).read_eeprom(curr_offset, 1) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if result[0] == 1: + return YCableBase.SWITCHING_MODE_AUTO + else: + return YCableBase.SWITCHING_MODE_MANUAL + else: + self.log_error('acquire lock timeout, failed to get the switch mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get the switch mode") return YCable.EEPROM_ERROR - if result[0] == 1: - return YCableBase.SWITCHING_MODE_AUTO - else: - return YCableBase.SWITCHING_MODE_MANUAL + def get_nic_temperature(self): """ @@ -1605,8 +1750,13 @@ def get_nic_temperature(self): curr_offset = YCable.OFFSET_NIC_TEMPERATURE if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - temp = result[0] + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + temp = result[0] + else: + self.log_error('acquire lock timeout, failed to get NIC temp') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get NIC temp") return -1 @@ -1626,8 +1776,13 @@ def get_local_temperature(self): curr_offset = YCable.OFFSET_INTERNAL_TEMPERATURE if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - temp = result[0] + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + temp = result[0] + else: + self.log_error('acquire lock timeout, failed to get local temp') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get local temp") return YCable.EEPROM_ERROR @@ -1646,10 +1801,15 @@ def get_nic_voltage(self): """ if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_VOLTAGE - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+1, 1) - voltage = (((msb_result[0] << 8) | lsb_result[0]) * 0.0001) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_VOLTAGE + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+1, 1) + voltage = (((msb_result[0] << 8) | lsb_result[0]) * 0.0001) + else: + self.log_error('acquire lock timeout, failed to get NIC voltage') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get NIC voltage") return -1 @@ -1668,10 +1828,15 @@ def get_local_voltage(self): """ if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_INTERNAL_VOLTAGE - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+1, 1) - voltage = (((msb_result[0] << 8) | lsb_result[0]) * 0.0001) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_INTERNAL_VOLTAGE + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+1, 1) + voltage = (((msb_result[0] << 8) | lsb_result[0]) * 0.0001) + else: + self.log_error('acquire lock timeout, failed to get local voltage') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get local voltage") return YCable.EEPROM_ERROR @@ -1691,16 +1856,21 @@ def get_alive_status(self): """ if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_SIGNAL_DETECTION - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 6) - if result is False: - return result - - for idx in range(6): - if result[idx] == 0: - return False + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_SIGNAL_DETECTION + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 6) + if result is False: + return result + + for idx in range(6): + if result[idx] == 0: + return False + else: + self.log_error('acquire lock timeout, failed to get active status') + return YCableBase.EEPROM_ERROR else: - self.log_error("platform_chassis is not loaded, failed to get anlt") + self.log_error("platform_chassis is not loaded, failed to get active status") return YCable.EEPROM_ERROR return True @@ -1731,21 +1901,26 @@ def reset(self, target): self.log_error("reset: unsupported target") return False - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_RUN - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD - vsc_req_form[YCable.VSC_BYTE_ADDR0] = (1 << target) - vsc_req_form[YCable.VSC_BYTE_ADDR1] = 0 - status = self.send_vsc(vsc_req_form) - - if target == YCableBase.TARGET_NIC: - time.sleep(4) - else: - time.sleep(2) - - if status != YCable.MCU_EC_NO_ERROR: - self.log_error("unable to reset the module") - return False + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.FWUPD_OPTION_RUN + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_FWUPD + vsc_req_form[YCable.VSC_BYTE_ADDR0] = (1 << target) + vsc_req_form[YCable.VSC_BYTE_ADDR1] = 0 + status = self.send_vsc(vsc_req_form) + + if status != YCable.MCU_EC_NO_ERROR: + self.log_error("unable to reset the module") + return False + + if target == YCableBase.TARGET_NIC: + time.sleep(4) + else: + time.sleep(2) + else: + self.log_error('acquire lock timeout, failed to reset') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to reset") return YCable.EEPROM_ERROR @@ -1795,25 +1970,30 @@ def create_port(self, speed, fec_mode_tor = YCableBase.FEC_MODE_NONE, fec_mode_n """ if self.platform_chassis is not None: - mode = 0 - if speed == 50000: - mode |= (0 << 6) - elif speed == 100000: - mode |= (1 << 6) - else: - self.log_error("create port: unsupported speed:%d" % (speed)) - return False - - mode |= (1 << 0) if anlt_nic else (0 << 0) - mode |= (1 << 1) if anlt_tor else (0 << 1) - mode |= (1 << 3) if fec_mode_nic == YCableBase.FEC_MODE_RS else (0 << 3) - mode |= (1 << 4) if fec_mode_tor == YCableBase.FEC_MODE_RS else (0 << 4) - - curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION - buffer = bytearray([mode]) - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + mode = 0 + if speed == 50000: + mode |= (0 << 6) + elif speed == 100000: + mode |= (1 << 6) + else: + self.log_error("create port: unsupported speed:%d" % (speed)) + return False + + mode |= (1 << 0) if anlt_nic else (0 << 0) + mode |= (1 << 1) if anlt_tor else (0 << 1) + mode |= (1 << 3) if fec_mode_nic == YCableBase.FEC_MODE_RS else (0 << 3) + mode |= (1 << 4) if fec_mode_tor == YCableBase.FEC_MODE_RS else (0 << 4) + + curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION + buffer = bytearray([mode]) + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + else: + self.log_error('acquire lock timeout, failed to create port') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to create port") return YCable.EEPROM_ERROR @@ -1837,16 +2017,21 @@ def get_speed(self): speed = 0 if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION - mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - - if (mode[0] >> 6) == 0: - speed = 50000 - elif (mode[0] >> 6) == 1: - speed = 100000 - else: - self.log_error("unsupported speed") - return -1 + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION + mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if (mode[0] >> 6) == 0: + speed = 50000 + elif (mode[0] >> 6) == 1: + speed = 100000 + else: + self.log_error("unsupported speed") + return -1 + else: + self.log_error('acquire lock timeout, failed to get speed') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get speed") return YCable.EEPROM_ERROR @@ -1877,22 +2062,27 @@ def set_fec_mode(self, fec_mode, target): """ if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION - mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - - if target == YCableBase.TARGET_NIC: - mode[0] &= ~(1 << 3) - mode[0] |= (1 << 3) if fec_mode == YCableBase.FEC_MODE_RS else (0 << 3) - elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: - mode[0] &= ~(1 << 4) - mode[0] |= (1 << 4) if fec_mode == YCableBase.FEC_MODE_RS else (0 << 4) - else: - self.log_error("set fec mode: unsupported target") - return False - - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, mode) - if result is False: - return result + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION + mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if target == YCableBase.TARGET_NIC: + mode[0] &= ~(1 << 3) + mode[0] |= (1 << 3) if fec_mode == YCableBase.FEC_MODE_RS else (0 << 3) + elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: + mode[0] &= ~(1 << 4) + mode[0] |= (1 << 4) if fec_mode == YCableBase.FEC_MODE_RS else (0 << 4) + else: + self.log_error("set fec mode: unsupported target") + return False + + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, mode) + if result is False: + return result + else: + self.log_error('acquire lock timeout, failed to set fec mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to set fec mode") return YCable.EEPROM_ERROR @@ -1921,17 +2111,22 @@ def get_fec_mode(self, target): fec_mode = YCableBase.FEC_MODE_NONE if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION - mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - - if target == YCableBase.TARGET_NIC: - if mode[0] & (1 << 3): - fec_mode = YCableBase.FEC_MODE_RS - elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: - if mode[0] & (1 << 4): - fec_mode = YCableBase.FEC_MODE_RS - else: - self.log_error("get fec mode: unsupported target") + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION + mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if target == YCableBase.TARGET_NIC: + if mode[0] & (1 << 3): + fec_mode = YCableBase.FEC_MODE_RS + elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: + if mode[0] & (1 << 4): + fec_mode = YCableBase.FEC_MODE_RS + else: + self.log_error("get fec mode: unsupported target") + else: + self.log_error('acquire lock timeout, failed to get fec mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get fec mode") return YCable.EEPROM_ERROR @@ -1960,22 +2155,27 @@ def set_anlt(self, enable, target): """ if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION - mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - - if target == YCableBase.TARGET_NIC: - mode[0] &= ~(1 << 0) - mode[0] |= (1 << 0) if enable else (0 << 0) - elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: - mode[0] &= ~(1 << 1) - mode[0] |= (1 << 1) if enable else (0 << 1) - else: - self.log_error("set anlt: unsupported target") - return False - - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, mode) - if result is False: - return result + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION + mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if target == YCableBase.TARGET_NIC: + mode[0] &= ~(1 << 0) + mode[0] |= (1 << 0) if enable else (0 << 0) + elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: + mode[0] &= ~(1 << 1) + mode[0] |= (1 << 1) if enable else (0 << 1) + else: + self.log_error("set anlt: unsupported target") + return False + + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, mode) + if result is False: + return result + else: + self.log_error('acquire lock timeout, failed to set anlt') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to set anlt") return YCable.EEPROM_ERROR @@ -2001,18 +2201,23 @@ def get_anlt(self, target): anlt_mode = False if self.platform_chassis is not None: - curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION - mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - - if target == YCableBase.TARGET_NIC: - if mode[0] & (1 << 0): - anlt_mode = True - - elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: - if mode[0] & (1 << 1): - anlt_mode = True - else: - self.log_error("get anlt: unsupported target") + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + curr_offset = YCable.OFFSET_NIC_MODE_CONFIGURATION + mode = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if target == YCableBase.TARGET_NIC: + if mode[0] & (1 << 0): + anlt_mode = True + + elif target == YCableBase.TARGET_TOR_A or target == YCableBase.TARGET_TOR_B: + if mode[0] & (1 << 1): + anlt_mode = True + else: + self.log_error("get anlt: unsupported target") + else: + self.log_error('acquire lock timeout, failed to get anlt') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get anlt") return YCable.EEPROM_ERROR @@ -2038,10 +2243,19 @@ def get_event_log(self, clear_on_read=False): if self.platform_chassis is not None: if (clear_on_read): - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_EVENTLOG - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.EVENTLOG_OPTION_CLEAR - self.send_vsc(vsc_req_form) + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) + vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_EVENTLOG + vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.EVENTLOG_OPTION_CLEAR + status = self.send_vsc(vsc_req_form) + + if status != YCable.MCU_EC_NO_ERROR: + self.log_error("clear event log error(error code:%04X)" % (status)) + return YCable.EEPROM_ERROR + else: + self.log_error("acquire lock timeout, failed to clear event log") + return YCable.EEPROM_ERROR last_read_id = -1 @@ -2061,52 +2275,57 @@ def get_event_log(self, clear_on_read=False): } while (True): - vsc_req_form = [None] * (YCable.VSC_CMD_ATTRIBUTE_LENGTH) - vsc_req_form[YCable.VSC_BYTE_OPCODE] = YCable.VSC_OPCODE_EVENTLOG - vsc_req_form[YCable.VSC_BYTE_OPTION] = YCable.EVENTLOG_OPTION_DUMP - vsc_req_form[YCable.VSC_BYTE_ADDR0] = (last_read_id >> 0) & 0xFF - vsc_req_form[YCable.VSC_BYTE_ADDR1] = (last_read_id >> 8) & 0xFF - vsc_req_form[YCable.VSC_BYTE_ADDR2] = (last_read_id >> 16) & 0xFF - vsc_req_form[YCable.VSC_BYTE_ADDR3] = (last_read_id >> 24) & 0xFF - status = self.send_vsc(vsc_req_form) - - if status == YCable.MCU_EC_NO_ERROR: - fetch_cnt = self.read_mmap(YCable.MIS_PAGE_VSC, 134) - if (fetch_cnt == 0): - break - else: - self.log_error("download event log error(error code:%04X)" % (status)) - return None - - event_data = bytearray(YCable.EVENTLOG_PAYLOAD_SIZE * fetch_cnt) - - for byte_offset in range(0, YCable.EVENTLOG_PAYLOAD_SIZE * fetch_cnt): - byte_data = self.read_mmap(YCable.MIS_PAGE_FC, 128 + byte_offset) - event_data[byte_offset] = byte_data - - for curr_idx in range(0, fetch_cnt): - byte_offset = curr_idx * YCable.EVENTLOG_PAYLOAD_SIZE - event_id = struct.unpack_from('> 0) & 0xFF + vsc_req_form[YCable.VSC_BYTE_ADDR1] = (last_read_id >> 8) & 0xFF + vsc_req_form[YCable.VSC_BYTE_ADDR2] = (last_read_id >> 16) & 0xFF + vsc_req_form[YCable.VSC_BYTE_ADDR3] = (last_read_id >> 24) & 0xFF + status = self.send_vsc(vsc_req_form) + + if status == YCable.MCU_EC_NO_ERROR: + fetch_cnt = self.read_mmap(YCable.MIS_PAGE_VSC, 134) + if (fetch_cnt == 0): + break + else: + self.log_error("download event log error(error code:%04X)" % (status)) + return YCable.EEPROM_ERROR + + event_data = bytearray(YCable.EVENTLOG_PAYLOAD_SIZE * fetch_cnt) + + for byte_offset in range(0, YCable.EVENTLOG_PAYLOAD_SIZE * fetch_cnt): + byte_data = self.read_mmap(YCable.MIS_PAGE_FC, 128 + byte_offset) + event_data[byte_offset] = byte_data + + for curr_idx in range(0, fetch_cnt): + byte_offset = curr_idx * YCable.EVENTLOG_PAYLOAD_SIZE + event_id = struct.unpack_from('> 8) & 0xFF, lt_tx1 & 0xFF, (lt_tx2 >> 8) & 0xFF, lt_tx2 & 0xFF] + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + an_sm = 0 + if target == YCableBase.TARGET_NIC: + an_sm = self.reg_read(0x0048) + lanes=[0,4] + elif target == YCableBase.TARGET_TOR_A: + an_sm = self.reg_read(0x5448) + lanes=[12,16] + elif target == YCableBase.TARGET_TOR_B: + an_sm = self.reg_read(0x5C48) + lanes=[20,24] + else: + self.log_error("get anlt stats: unsupported target") + + anlt_stat['AN_StateMachine'] = an_sm + + for idx, ln in enumerate(range(lanes[0], lanes[1])): + lt_tx1 = self.reg_read(0xB3 | 0x200 * ln) + lt_tx2 = self.reg_read(0xB4 | 0x200 * ln) + anlt_stat['LT_TX_lane%d' % idx] = [(lt_tx1 >> 8) & 0xFF, lt_tx1 & 0xFF, (lt_tx2 >> 8) & 0xFF, lt_tx2 & 0xFF] + else: + self.log_error('acquire lock timeout, failed to get anlt stat') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get anlt stats") return YCable.EEPROM_ERROR @@ -2450,26 +2698,30 @@ def enable_prbs_mode(self, target, mode_value, lane_mask, direction=YCableBase.P curr_offset = YCable.OFFSET_TARGET if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - - buffer = bytearray([0]) - curr_offset = YCable.OFFSET_ENABLE_PRBS - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - - buffer = bytearray([mode_value]) - curr_offset = YCable.OFFSET_CONFIGURE_PRBS_TYPE - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - - buffer = bytearray([lane_mask]) - curr_offset = YCable.OFFSET_ENABLE_PRBS - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + + buffer = bytearray([0]) + curr_offset = YCable.OFFSET_ENABLE_PRBS + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + + buffer = bytearray([mode_value]) + curr_offset = YCable.OFFSET_CONFIGURE_PRBS_TYPE + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + + buffer = bytearray([lane_mask]) + curr_offset = YCable.OFFSET_ENABLE_PRBS + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to enable the PRBS mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to enable the PRBS mode") return YCable.EEPROM_ERROR @@ -2503,15 +2755,17 @@ def disable_prbs_mode(self, target, direction): curr_offset = YCable.OFFSET_TARGET if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - buffer = bytearray([0]) - curr_offset = YCable.OFFSET_ENABLE_PRBS - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + buffer = bytearray([0]) + curr_offset = YCable.OFFSET_ENABLE_PRBS + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to disable the PRBS mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to disable the PRBS mode") return YCable.EEPROM_ERROR @@ -2551,15 +2805,17 @@ def enable_loopback_mode(self, target, lane_mask, mode=YCableBase.LOOPBACK_MODE_ curr_offset = YCable.OFFSET_TARGET if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - buffer = bytearray([lane_mask]) - curr_offset = YCable.OFFSET_ENABLE_LOOPBACK - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + buffer = bytearray([lane_mask]) + curr_offset = YCable.OFFSET_ENABLE_LOOPBACK + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to enable the loopback mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to enable the loopback mode") return YCable.EEPROM_ERROR @@ -2588,17 +2844,19 @@ def disable_loopback_mode(self, target): curr_offset = YCable.OFFSET_TARGET if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - buffer = bytearray([0]) - curr_offset = YCable.OFFSET_ENABLE_LOOPBACK - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + buffer = bytearray([0]) + curr_offset = YCable.OFFSET_ENABLE_LOOPBACK + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + else: + self.log_error('acquire lock timeout, failed to disable loopback mode') + return YCableBase.EEPROM_ERROR else: - self.log_error("platform_chassis is not loaded, failed to disable the loopback mode") + self.log_error("platform_chassis is not loaded, failed to disable loopback mode") return YCable.EEPROM_ERROR return result @@ -2626,33 +2884,38 @@ def get_loopback_mode(self, target): """ if self.platform_chassis is not None: - buffer = bytearray([target]) - curr_offset = YCable.OFFSET_TARGET - - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return -1 - - buffer = bytearray([0]) - curr_offset = YCable.OFFSET_SYNC_DEBUG_MODE - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return -1 - time_start = time.time() - while(True): - done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - time_now = time.time() - time_diff = time_now - time_start - if done[0] == 1: - break - elif time_diff >= YCable.GET_DEBUG_MODE_TIMEOUT_SECS: - return YCable.EEPROM_TIMEOUT_ERROR - - curr_offset = YCable.OFFSET_ENABLE_LOOPBACK - result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - - if result[0]: - return YCableBase.LOOPBACK_MODE_NEAR_END + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + buffer = bytearray([target]) + curr_offset = YCable.OFFSET_TARGET + + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return -1 + + buffer = bytearray([0]) + curr_offset = YCable.OFFSET_SYNC_DEBUG_MODE + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return -1 + time_start = time.time() + while(True): + done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + time_now = time.time() + time_diff = time_now - time_start + if done[0] == 1: + break + elif time_diff >= YCable.GET_DEBUG_MODE_TIMEOUT_SECS: + return YCable.EEPROM_TIMEOUT_ERROR + + curr_offset = YCable.OFFSET_ENABLE_LOOPBACK + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + + if result[0]: + return YCableBase.LOOPBACK_MODE_NEAR_END + else: + self.log_error('acquire lock timeout, failed to get loopback mode') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get loopback mode") return YCable.EEPROM_ERROR @@ -2682,34 +2945,38 @@ def get_ber_info(self, target): ber_result = [] if self.platform_chassis is not None: - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - buffer = bytearray([0]) - curr_offset = YCable.OFFSET_INITIATE_BER_MEASUREMENT - result = self.platform_chassis.get_sfp( - self.port).write_eeprom(curr_offset, 1, buffer) - if result is False: - return result - time_start = time.time() - while(True): - done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - time_now = time.time() - time_diff = time_now - time_start - if done[0] == 1: - break - elif time_diff >= YCable.BER_TIMEOUT_SECS: - return YCable.EEPROM_TIMEOUT_ERROR - - idx = 0 - curr_offset = YCable.OFFSET_LANE_1_BER_RESULT - for lane in range(YCable.MAX_NUM_LANES): - msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+idx, 1) - lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+1+idx, 1) - lane_result = msb_result[0] * math.pow(10, (lsb_result[0]-24)) - ber_result.append(lane_result) - idx += 2 + with self.rlock.acquire_timeout(RLocker.ACQUIRE_LOCK_TIMEOUT) as lock_status: + if lock_status: + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + buffer = bytearray([0]) + curr_offset = YCable.OFFSET_INITIATE_BER_MEASUREMENT + result = self.platform_chassis.get_sfp( + self.port).write_eeprom(curr_offset, 1, buffer) + if result is False: + return result + time_start = time.time() + while(True): + done = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + time_now = time.time() + time_diff = time_now - time_start + if done[0] == 1: + break + elif time_diff >= YCable.BER_TIMEOUT_SECS: + return YCable.EEPROM_TIMEOUT_ERROR + + idx = 0 + curr_offset = YCable.OFFSET_LANE_1_BER_RESULT + for lane in range(YCable.MAX_NUM_LANES): + msb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+idx, 1) + lsb_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset+1+idx, 1) + lane_result = msb_result[0] * math.pow(10, (lsb_result[0]-24)) + ber_result.append(lane_result) + idx += 2 + else: + self.log_error('acquire lock timeout, failed to get ber info') + return YCableBase.EEPROM_ERROR else: self.log_error("platform_chassis is not loaded, failed to get ber info") return YCable.EEPROM_ERROR @@ -2740,42 +3007,46 @@ def debug_dump_registers(self, option=None): which would help diagnose the cable for proper functioning """ if self.platform_chassis is not None: - result = {} - result['pn'] = self.get_part_number() - result['sn'] = self.get_serial_number() - result['uart_stat'] = self.get_uart_stat() - result['nic_temp'] = self.get_nic_temperature() - result['nic_voltage'] = self.get_nic_voltage() - result['fw_init_status'] = self.get_dsp_fw_init_stat() - result['serdes_detect'] = self.get_dsp_link_Dect() - - lanes = [0,1,2,3,12,13,14,15,20,21,22,23] - - for ln in list(lanes): - data = self.get_serdes_params(ln) - serdes = {} - serdes['ch_est'] = struct.unpack_from('