diff --git a/sonic_y_cable/broadcom/y_cable_broadcom.py b/sonic_y_cable/broadcom/y_cable_broadcom.py index be800400b7..32576b8f6b 100644 --- a/sonic_y_cable/broadcom/y_cable_broadcom.py +++ b/sonic_y_cable/broadcom/y_cable_broadcom.py @@ -1,14 +1,10 @@ # -# bcm_cable_api.py -# -# property -# $Copyright: (c) 2021 Broadcom. -# Broadcom Proprietary and Confidential. All rights reserved. +# y_cable_broadcom.py # # definitions for implementing Y cable access and configurations # API's for Y cable functionality in SONiC # - +#from y_cable_base import YCableBase from sonic_y_cable.y_cable_base import YCableBase try: @@ -21,6 +17,7 @@ from ctypes import c_int16 from datetime import datetime from contextlib import contextmanager + #import chassis #from chassis import chassis import sonic_platform.platform @@ -33,65 +30,125 @@ # 1. If any python package is not available, there will be exception when use it # 2. Vendors know their platform API version, they are responsible to use correct python # version when importing this file. - #pass + # pass # strut definitions used in fw related functions + + class cable_image_version_s(object): def __init__(self): self.image_version_minor = 0 self.image_version_major = 0 + class cable_image_info_s(object): def __init__(self): - self.image_fw_version = cable_image_version_s() - self.image_api_version = cable_image_version_s() - self.image_crc32 = 0 - self.image_ptr = array.array('H', []) - self.image_size = 0 + self.image_fw_version = cable_image_version_s() + self.image_api_version = cable_image_version_s() + self.image_crc32 = 0 + self.image_ptr = array.array('H', []) + self.image_size = 0 + class cable_bank_info_s(object): def __init__(self): - self.image_fw_version = cable_image_version_s() - self.image_api_version = cable_image_version_s() - self.image_crc32 = 0 + self.image_fw_version = cable_image_version_s() + self.image_api_version = cable_image_version_s() + self.image_crc32 = 0 + class cable_status_info_s(): def __init__(self): self.current_bank = 0 self.next_bank = 0 - self.bank1_info = cable_bank_info_s() - self.bank2_info = cable_bank_info_s() + self.bank1_info = cable_bank_info_s() + self.bank2_info = cable_bank_info_s() + -class cable_upgrade_info_s(): +class cable_upgrade_info_s(object): def __init__(self): - self.image_info = cable_image_info_s() + self.image_info = cable_image_info_s() self.status_info = cable_status_info_s() self.destination = 0 - self.bank = 0 + self.bank = 0 + + +class cable_upgrade_head_s(): + + def __init__(self): + self.compression = 0 + self.compressed_size = 0 + self.compressed_crc32 = 0 + self.add_size = 0 + self.add_crc32 = 0 + self.header_crc32 = 0 + self.cable_up_info = cable_upgrade_info_s() + + +class cmd_handle_s(object): + + def __init__(self): + self.cmd_wr = 0 + self.read_info = 0 + self.cmd_rd = 0 + self.info_len = 0 + self.data_read = bytearray(30) -class valid_port_option_table_s: - - def __init__(self, speed, fec_tor, fec_nic, anlt_tor, anlt_nic, mode): +class valid_port_option_table_s: + + def __init__(self, speed, fec_tor, fec_nic, anlt_tor, anlt_nic, mode): self.speed = speed - self.fec_tor = fec_tor - self.fec_nic = fec_nic - self.anlt_tor = anlt_tor - self.anlt_nic = anlt_nic - self.mode = mode + self.fec_tor = fec_tor + self.fec_nic = fec_nic + self.anlt_tor = anlt_tor + self.anlt_nic = anlt_nic + self.mode = mode + + +class context_state_frame_s(object): + def __init__(self): + self.r0 = 0 + self.r1 = 0 + self.r2 = 0 + self.r3 = 0 + self.r12 = 0 + self.lr = 0 + self.return_address = 0 + self.xpsr = 0 + + +class ram2_exp_hdr_s(object): + def __init__(self): + self.crash = 0 + self.crash_len = 0 + self.cfsr_reg = 0 + self.ufsr_reg = 0 + self.bfsr_reg = 0 + self.mmfsr_reg = 0 + self.val = context_state_frame_s() + self.exp_sp_depth = 0 + + +class ram2_exp_s(object): + def __init__(self): + self.hdr_val = ram2_exp_hdr_s() + self.exp_stack = array.array('I', []) ENABLE_DBG_PRINT = False + def enable_debug_print(flag): - global ENABLE_DBG_PRINT + global ENABLE_DBG_PRINT ENABLE_DBG_PRINT = flag + def debug_print(log_msg): if ENABLE_DBG_PRINT: curr_timestamp = datetime.utcnow() @@ -102,12 +159,14 @@ def debug_print(log_msg): # # Lock for port access for thread safe # + + class PortLock(object): def __init__(self, port_nbr): self.port_nbr = port_nbr self.lock = threading.RLock() - #def __del__(self): + # def __del__(self): # print("PortLock {} destroyed".format(self.port_nbr)) def __enter__(self): @@ -141,8 +200,12 @@ def release(self): # # BCM Y Cable implementation derived from y_cable_base # + + class YCable(YCableBase): + WARMBOOT = 0 + COLDBOOT = 1 # definitions of the modes to be run for loopback mode # on the port/cable @@ -153,7 +216,7 @@ class YCable(YCableBase): PRBS_DIRECTION_GENERATOR = 1 PRBS_DIRECTION_CHECKER = 2 - BCM_API_VERSION = "1.0" + BCM_API_VERSION = "1.2" CONSOLE_PRINT = False # Log levels @@ -164,236 +227,263 @@ class YCable(YCableBase): CABLE_MODE_100G_FEC = 0 CABLE_MODE_100G_PCS = 1 - CABLE_MODE_50G_FEC = 2 - CABLE_MODE_50G_PCS = 3 - + CABLE_MODE_50G_FEC = 2 + CABLE_MODE_50G_PCS = 3 + PORT_SPEED_50 = 0 - PORT_SPEED_100 = 1 + PORT_SPEED_100 = 1 - FEC_MODE_NONE = 0 - FEC_MODE_RS = 1 - PORT_FEC_FC = 2 + FEC_MODE_NONE = 0 + FEC_MODE_RS = 1 + PORT_FEC_FC = 2 - ANLT_DISABLED = 1 - ANLT_ENABLED = 2 + ANLT_DISABLED = 1 + ANLT_ENABLED = 2 ANLT_DONT_CARE = 3 #ANLT_DONT_CARE = True - CABLE_MODE_50G = 50000 - CABLE_MODE_100G = 100000 - - PORT_LOCK_TIMEOUT = 30 # in seconds + CABLE_MODE_50G = 50000 + CABLE_MODE_100G = 100000 + PORT_LOCK_TIMEOUT = 30 # in seconds # Register absolute addresses - QSFP28_LP_3_TX_RX_LOSS = 0x00000003 - QSFP28_LP_5_TX_RX_CDR_LOL = 0x00000005 - QSFP28_LOS_LOL_SEC = 0x0000004A - QSFP28_LINK_DOWN = 0x0000004B - QSFP28_LINK_FAULT = 0x0000004C - QSFP28_MESC_FAULT = 0x0000004D - QSFP28_LP_22_TEMP_MSB = 0x00000016 - QSFP_SQL_STATUS = 0x0000004E - QSFP_LP_31_VENDOR = 0x0000004F # CHANGED to 79 -- Not used. Check! - QSFP_LINK_FAULT_MASK = 0x00007F61 - QSFP_MESC_MASK = 0x00007F62 - QSFP28_LP_100_TX_RX_LOS_MASK = 0x00000064 - QSFP28_LP_102_TX_RX_CDR_LOL_MASK = 0x00000066 - QSFP28_LOS_LOL_SEC_MASK = 0x00007F63 - QSFP28_UP_DOWN_MASK = 0x00007F64 - QSFP28_UP0_148_VENDOR_NAME_0 = 0x00000094 - QSFP28_UP0_168_PN_1 = 0x000000a8 - QSFP28_UP0_224_SPECIFIC_1_RSV = 0x000000e0 - QSFP_BRCM_CABLE_CMD = 0x00000013 - QSFP_BRCM_CABLE_CTRL_CMD_STS = 0x00000014 - QSFP_VEN_FE_130_BRCM_DATA_LENGHT_LSB = 0x00007f82 - QSFP28_VENFD_129_DIE_TEMP_MSB = 0x00007f01 - QSFP28_VENFD_130_DIE_VOLTAGE_LSB = 0x00007f02 - QSFP28_VENFD_184_NIC_TORB_TORA_RESET = 0x00007f38 - QSFP28_VENFD_216_LINK_STATUS = 0x00007f58 - QSFP28_RESET_SELF_OFFSET = 0x0000005D + QSFP28_LP_3_TX_RX_LOSS = 0x00000003 + QSFP28_LP_5_TX_RX_CDR_LOL = 0x00000005 + QSFP28_LOS_LOL_SEC = 0x0000004A + QSFP28_LINK_DOWN = 0x0000004B + QSFP28_LINK_FAULT = 0x0000004C + QSFP28_MESC_FAULT = 0x0000004D + QSFP28_BIP_CW_ERR_FAULT = 0x00000050 + QSFP28_LP_22_TEMP_MSB = 0x00000016 + QSFP_SQL_STATUS = 0x0000004E + QSFP_LP_31_VENDOR = 0x0000004F # CHANGED to 79 -- Not used. Check! + QSFP_LINK_FAULT_MASK = 0x00007F61 + QSFP_MESC_MASK = 0x00007F62 + QSFP28_LP_100_TX_RX_LOS_MASK = 0x00000064 + QSFP28_LP_102_TX_RX_CDR_LOL_MASK = 0x00000066 + QSFP28_LOS_LOL_SEC_MASK = 0x00007F63 + QSFP28_UP_DOWN_MASK = 0x00007F64 + QSFP28_BIP_UNCORR_MASK = 0x00007F65 + QSFP28_UP0_148_VENDOR_NAME_0 = 0x00000094 + QSFP28_UP0_168_PN_1 = 0x000000a8 + QSFP28_UP0_224_SPECIFIC_1_RSV = 0x000000e0 + QSFP_BRCM_CABLE_CMD = 0x00000013 + QSFP_BRCM_CABLE_CTRL_CMD_STS = 0x00000014 + QSFP_VEN_FE_130_BRCM_DATA_LENGHT_LSB = 0x00007f82 + QSFP28_VENFD_129_DIE_TEMP_MSB = 0x00007f01 + QSFP28_VENFD_130_DIE_VOLTAGE_LSB = 0x00007f02 + QSFP28_VENFD_184_NIC_TORB_TORA_RESET = 0x00007f38 + QSFP28_VENFD_216_LINK_STATUS = 0x00007f58 + QSFP28_RESET_SELF_OFFSET = 0x0000005D # temperature and voltage register offsets - QSFP28_VENFD_128_DIE_TEMP_LSB = 0x00007f00 - QSFP28_VENFD_131_DIE_VOLTAGE_MSB = 0x00007f03 - QSFP28_VENFD_134_TORA_TEMP_MSB = 0x00007f06 - QSFP28_VENFD_135_TORA_TEMP_LSB = 0x00007f07 - QSFP28_VENFD_138_TORB_TEMP_MSB = 0x00007f0a - QSFP28_VENFD_139_TORB_TEMP_LSB = 0x00007f0b - QSFP28_VENFD_142_NIC_TEMP_MSB = 0x00007f0e - QSFP28_VENFD_143_NIC_TEMP_LSB = 0x00007f0f - - QSFP28_LP_QSFP28_LP_2_STATUS_CR = 0x00000002 - + QSFP28_VENFD_128_DIE_TEMP_LSB = 0x00007f00 + QSFP28_VENFD_131_DIE_VOLTAGE_MSB = 0x00007f03 + QSFP28_VENFD_134_TORA_TEMP_MSB = 0x00007f06 + QSFP28_VENFD_135_TORA_TEMP_LSB = 0x00007f07 + QSFP28_VENFD_138_TORB_TEMP_MSB = 0x00007f0a + QSFP28_VENFD_139_TORB_TEMP_LSB = 0x00007f0b + QSFP28_VENFD_142_NIC_TEMP_MSB = 0x00007f0e + QSFP28_VENFD_143_NIC_TEMP_LSB = 0x00007f0f + + QSFP28_LP_QSFP28_LP_2_STATUS_CR = 0x00000002 + QSFP_BRCM_FW_UPGRADE_COMP_SET = 0x00000094 # User defined CMD_REQ_PARAM_START_OFFSET = 0x7F87 CMD_RSP_PARAM_START_OFFSET = 0x7FB8 - + MAX_REQ_PARAM_LEN = 0x30 MAX_RSP_PARAM_LEN = 0x77 - - # command IDs - CABLE_CMD_ID_PRBS_SET = 0x01 - CABLE_CMD_ID_PRBS_CHK = 0x03 - CABLE_CMD_ID_SET_LOOPBACK = 0x04 - CABLE_CMD_ID_GET_LOOPBACK = 0x05 - CABLE_CMD_ID_SET_TXFIR = 0x06 - CABLE_CMD_ID_GET_TXFIR = 0x07 - CABLE_CMD_ID_SET_ANLT = 0x08 - CABLE_CMD_ID_GET_ANLT = 0x09 - CABLE_CMD_ID_GET_ANLT_RESTART = 0x0A + + # command IDs + CABLE_CMD_ID_PRBS_SET = 0x01 + CABLE_CMD_ID_PRBS_CHK = 0x03 + CABLE_CMD_ID_SET_LOOPBACK = 0x04 + CABLE_CMD_ID_GET_LOOPBACK = 0x05 + CABLE_CMD_ID_SET_TXFIR = 0x06 + CABLE_CMD_ID_GET_TXFIR = 0x07 + CABLE_CMD_ID_SET_ANLT = 0x08 + CABLE_CMD_ID_GET_ANLT = 0x09 + CABLE_CMD_ID_GET_ANLT_RESTART = 0x0A CABLE_CMD_ID_GET_ANLT_GET_STATUS = 0x0B - CABLE_CMD_ID_SET_POLARITY = 0x0C - CABLE_CMD_ID_GET_POLARITY = 0x0D - CABLE_CMD_ID_SET_MODE = 0x0E - CABLE_CMD_ID_GET_MODE = 0x0F - CABLE_CMD_ID_GET_SQUELCH = 0x10 - CABLE_CMD_ID_SET_SQUELCH = 0x11 - CABLE_CMD_ID_GET_HMUX_CONFIG = 0x12 - CABLE_CMD_ID_SET_HMUX_CONFIG = 0x13 - CABLE_CMD_ID_GET_HMUX_CONTEXT = 0x14 - CABLE_CMD_ID_SET_HMUX_CONTEXT = 0x15 - CABLE_CMD_ID_GET_HMUX_STATS = 0x16 - CABLE_CMD_ID_READ_REG = 0x17 - CABLE_CMD_ID_WRITE_REG = 0x18 - CABLE_CMD_ID_ENABLE_PHY_CHIP = 0x19 - CABLE_CMD_ID_DISABLE_PHY_CHIP = 0x1A - CABLE_CMD_ID_DUMP_PAGE = 0x1B - CABLE_CMD_ID_GET_EYE_MARGIN = 0x1F - CABLE_CMD_ID_GET_SNR = 0x20 - CABLE_CMD_ID_SET_HMUX_CONTEXT_PRI= 0x21 - CABLE_CMD_ID_SET_HMUX_CONTEXT_SEC= 0x22 + CABLE_CMD_ID_SET_POLARITY = 0x0C + CABLE_CMD_ID_GET_POLARITY = 0x0D + CABLE_CMD_ID_SET_MODE = 0x0E + CABLE_CMD_ID_GET_MODE = 0x0F + CABLE_CMD_ID_GET_SQUELCH = 0x10 + CABLE_CMD_ID_SET_SQUELCH = 0x11 + CABLE_CMD_ID_GET_HMUX_CONFIG = 0x12 + CABLE_CMD_ID_SET_HMUX_CONFIG = 0x13 + CABLE_CMD_ID_GET_HMUX_CONTEXT = 0x14 + CABLE_CMD_ID_SET_HMUX_CONTEXT = 0x15 + CABLE_CMD_ID_GET_HMUX_STATS = 0x16 + CABLE_CMD_ID_READ_REG = 0x17 + CABLE_CMD_ID_WRITE_REG = 0x18 + CABLE_CMD_ID_ENABLE_PHY_CHIP = 0x19 + CABLE_CMD_ID_DISABLE_PHY_CHIP = 0x1A + CABLE_CMD_ID_DUMP_PAGE = 0x1B + CABLE_CMD_ID_GET_EYE_MARGIN = 0x1F + CABLE_CMD_ID_GET_SNR = 0x20 + CABLE_CMD_ID_SET_HMUX_CONTEXT_PRI = 0x21 + CABLE_CMD_ID_SET_HMUX_CONTEXT_SEC = 0x22 + CABLE_CMD_ID_GET_TOT_MAN_SWT_CNT = 0x23 + CABLE_CMD_ID_GET_TOT_MAN_SWT_CNT_CLR = 0x24 + CABLE_CMD_ID_GET_TO_TORA_MAN_SWT_CNT = 0x25 + CABLE_CMD_ID_GET_TO_TORA_MAN_SWT_CNT_CLR = 0x26 + CABLE_CMD_ID_GET_TO_TORB_MAN_SWT_CNT = 0x27 + CABLE_CMD_ID_GET_TO_TORB_MAN_SWT_CNT_CLR = 0x28 + CABLE_CMD_ID_GET_FM_TORA_MAN_SWT_CNT = 0x29 + CABLE_CMD_ID_GET_FM_TORA_MAN_SWT_CNT_CLR = 0x2A + CABLE_CMD_ID_GET_FM_TORB_MAN_SWT_CNT = 0x2B + CABLE_CMD_ID_GET_FM_TORB_MAN_SWT_CNT_CLR = 0x2C + CABLE_CMD_ID_GET_TOT_AUT_SWT_CNT = 0x2D + CABLE_CMD_ID_GET_TOT_AUT_SWT_CNT_CLR = 0x2E + CABLE_CMD_ID_GET_TO_TORA_AUT_SWT_CNT = 0x2F + CABLE_CMD_ID_GET_TO_TORA_AUT_SWT_CNT_CLR = 0x30 + CABLE_CMD_ID_GET_TO_TORB_AUT_SWT_CNT = 0x31 + CABLE_CMD_ID_GET_TO_TORB_AUT_SWT_CNT_CLR = 0x32 + CABLE_CMD_ID_READ_MCU_RAM = 0x33 + CABLE_CMD_ID_CLEAR_CRASH = 0x34 # Download commands - FW_CMD_START = 1 - FW_CMD_TRANSFER = 2 - FW_CMD_COMPLETE = 3 - FW_CMD_SWAP = 4 - FW_CMD_ABORT = 5 - FW_CMD_INFO = 6 - FW_CMD_RESET = 7 - - FW_UP_SUCCESS = 1 - FW_UP_IN_PROGRESS = 2 - + FW_CMD_START = 1 + FW_CMD_TRANSFER = 2 + FW_CMD_COMPLETE = 3 + FW_CMD_SWAP = 4 + FW_CMD_ABORT = 5 + FW_CMD_INFO = 6 + FW_CMD_RESET = 7 + + FW_UP_SUCCESS = 1 + FW_UP_IN_PROGRESS = 2 + + FW_CMD_WARM_BOOT = 13 + FW_CMD_BOOT_STATUS = 14 + # destination values - TOR_MCU = 0x01 - TOR_MCU_SELF = 0x01 - NIC_MCU = 0x02 - MUX_CHIP = 0x03 - TOR_MCU_PEER = 0x04 + TOR_MCU = 0x01 + TOR_MCU_SELF = 0x01 + NIC_MCU = 0x02 + MUX_CHIP = 0x03 + TOR_MCU_PEER = 0x04 # FW image address - MCU_FW_IMG_INFO_ADDR = 0x3E7F0 - MCU_FW_IMG_SIZE = 0x3E800 - MUX_FW_IMG_INFO_ADDR = 0x3FFE0 - MUX_FW_IMG_SIZE = 0x40000 - FW_IMG_INFO_SIZE = 12 - FW_UP_PACKET_SIZE = 128 - - QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 = 0x81 - QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2 = 0x82 - QSFP_BRCM_FW_UPGRADE_DATA_START = 0x80 - QSFP_BRCM_DIAGNOSTIC_PAGE = 0x04 - QSFP_BRCM_DIAGNOSTIC_STATUS = 0x81 - - QSFP_BRCM_FW_UPGRADE_PACKET_SIZE = 0x92 - QSFP_BRCM_FW_UPGRADE_CURRENT_BANK = 0x80 - - QSFP_BRCM_FW_UPGRADE_CTRL_CMD = 0x80 - QSFP_BRCM_FW_UPGRADE_CMD_STS = 0x81 - QSFP_BRCM_FW_UPGRADE_CTRL_STS = 0x81 - - QSFP_BRCM_FW_UPGRADE_PAGE = 0x80 - QSFP_BRCM_FW_UPGRADE_HEADER_0_7 = 0x82 - QSFP_BRCM_FW_UPGRADE_HEADER_24_31 = 0x85 + MCU_FW_IMG_INFO_ADDR = 0x3E7F0 + MCU_FW_IMG_SIZE = 0x3E800 + MUX_FW_IMG_INFO_ADDR = 0x3FFE0 + MUX_FW_IMG_SIZE = 0x40000 + FW_IMG_INFO_SIZE = 12 + FW_UP_PACKET_SIZE = 128 + + QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 = 0x81 + QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2 = 0x82 + QSFP_BRCM_FW_UPGRADE_DATA_START = 0x80 + QSFP_BRCM_DIAGNOSTIC_PAGE = 0x04 + QSFP_BRCM_DIAGNOSTIC_STATUS = 0x81 + + QSFP_BRCM_FW_UPGRADE_PACKET_SIZE = 0x92 + QSFP_BRCM_FW_UPGRADE_CURRENT_BANK = 0x80 + + QSFP_BRCM_FW_UPGRADE_CTRL_CMD = 0x80 + QSFP_BRCM_FW_UPGRADE_CMD_STS = 0x81 + QSFP_BRCM_FW_UPGRADE_CTRL_STS = 0x81 + + QSFP_BRCM_FW_UPGRADE_PAGE = 0x80 + QSFP_BRCM_FW_UPGRADE_HEADER_0_7 = 0x82 + QSFP_BRCM_FW_UPGRADE_HEADER_24_31 = 0x85 + QSFP_BRCM_FW_UPGRADE_BOOT_STATUS = 0x9A # muxchip return codes - RR_ERROR = -1 #-255 # Error Category - RR_ERROR_SYSTEM_UNAVAILABLE = -1 #-250 # System Unavailable Error - RR_SUCCESS = 0 # Success + RR_ERROR = -1 # -255 # Error Category + RR_ERROR_SYSTEM_UNAVAILABLE = -1 # -250 # System Unavailable Error + RR_SUCCESS = 0 # Success # PRBS polynomials - CABLE_PRBS7 = 0 # PRBS poly 7 - CABLE_PRBS9 = 1 # PRBS poly 9 - CABLE_PRBS11 = 2 # PRBS poly 11 - CABLE_PRBS15 = 3 # PRBS poly 15 - CABLE_PRBS23 = 4 # PRBS poly 23 - CABLE_PRBS31 = 5 # PRBS poly 31 - CABLE_PRBS58 = 6 # PRBS poly 58 - CABLE_PRBS49 = 7 # PRBS poly 49 - CABLE_PRBS13 = 8 # PRBS poly 13 + CABLE_PRBS7 = 0 # PRBS poly 7 + CABLE_PRBS9 = 1 # PRBS poly 9 + CABLE_PRBS11 = 2 # PRBS poly 11 + CABLE_PRBS15 = 3 # PRBS poly 15 + CABLE_PRBS23 = 4 # PRBS poly 23 + CABLE_PRBS31 = 5 # PRBS poly 31 + CABLE_PRBS58 = 6 # PRBS poly 58 + CABLE_PRBS49 = 7 # PRBS poly 49 + CABLE_PRBS13 = 8 # PRBS poly 13 # Loopback modes - CABLE_NIC_GLOOPBACK_MODE = 0 #Global NIC loopback mode, line/NIC side deep or G-Loop - CABLE_NIC_RLOOPBACK_MODE = 1 #Remote NIC loopback mode, line/NIC side R-LOOP - CABLE_TOR_GLOOPBACK_MODE = 2 #Global TOR loopback mode, TOR side deep or G-Loop - CABLE_TOR_RLOOPBACK_MODE = 3 #Remote TOR loopback mode, side R-LOOP + CABLE_NIC_GLOOPBACK_MODE = 0 # Global NIC loopback mode, line/NIC side deep or G-Loop + CABLE_NIC_RLOOPBACK_MODE = 1 # Remote NIC loopback mode, line/NIC side R-LOOP + CABLE_TOR_GLOOPBACK_MODE = 2 # Global TOR loopback mode, TOR side deep or G-Loop + CABLE_TOR_RLOOPBACK_MODE = 3 # Remote TOR loopback mode, side R-LOOP # core ip's - CORE_IP_ALL = 0 #Core IP ALL - CORE_IP_LW = 2 #Core IP Line Wrapper - CORE_IP_CLIENT = 3 #Core IP SerDes - CORE_IP_NIC = 1 - CORE_IP_TOR = 2 + CORE_IP_ALL = 0 # Core IP ALL + CORE_IP_LW = 2 # Core IP Line Wrapper + CORE_IP_CLIENT = 3 # Core IP SerDes + CORE_IP_NIC = 1 + CORE_IP_TOR = 2 CORE_IP_CENTRAL = 3 - - # Error codes returned from y_cable functions - ERROR_PLATFORM_NOT_LOADED = -1 #-1 - ERROR_CMD_STS_CHECK_FAILED = -1 #-2 - ERROR_WRITE_EEPROM_FAILED = -1 #-3 - ERROR_CMD_PROCESSING_FAILED = -1 #-4 - ERROR_MCU_NOT_RELEASED = -1 #-5 - ERROR_MCU_BUSY = -1 #-6 - ERROR_INVALID_PRBS_MODE = -1 #-8 - ERROR_INVALID_TARGET = -1 #-9 - ERROR_INVALID_DIRECTION = -1 #-10 - ERROR_INVALID_POLARITY = -1 #-11 - ERROR_CMD_EXEC_FAILED = -1 #-12 - ERROR_PORT_LOCK_TIMEOUT = -1 #-13 - ERROR_INVALID_INPUT = -1 #-14 - - ERROR_FW_GET_STATUS_FAILED = -1 #-15 - ERROR_NO_MATCHING_FW = -1 #-16 - ERROR_RESET_FAILED = -1 #-17 - ERROR_TOGGLE_FAILED = -1 #-18 - ERROR_FW_ACTIVATE_FAILURE = -1 #-19 - ERROR_FW_ROLLBACK_FAILURE = -1 #-20 - - WARNING_FW_ALREADY_ACTIVE = -1 #-50 - WARNING_FW_ALREADY_ROLLEDBACK = -1 #-51 - - EEPROM_READ_DATA_INVALID = -1 #-100 - EEPROM_ERROR = -1 #-101 - API_FAIL = -1 #-102 - - ERROR_RW_NIC_FAILED = -1 #-30 #Unable to communicate with NIC MCU - ERROR_RW_TOR_FAILED = -1 #-31 #Unable to communicate with TOR MCU - ERROR_GET_VERSION_FAILED = -1 #-32 #Unable to get firmware version from MCU - ERROR_FLASH_SIZE_INVALID = -1 #-33 #Firmware image size is greater than flash bank size - ERROR_FLASH_ERASE_FAILED = -1 #-34 #Flash erase failed - ERROR_FLASH_WRITE_FAILED = -1 #-35 #Flash write failed - ERROR_FLASH_READ_FAILED = -1 #-36 #Flash read failed - ERROR_CRC32_FAILED = -1 #-37 #Flash CRC validation failed - ERROR_CMD_TIMEOUT = -1 #-38 #No response after command sent - ERROR_SYSTEM_BUSY = -1 #-39 #System is busy + # Error codes returned from y_cable functions + ERROR_PLATFORM_NOT_LOADED = -1 # -1 + ERROR_CMD_STS_CHECK_FAILED = -1 # -2 + ERROR_WRITE_EEPROM_FAILED = -1 # -3 + ERROR_CMD_PROCESSING_FAILED = -1 # -4 + ERROR_MCU_NOT_RELEASED = -1 # -5 + ERROR_MCU_BUSY = -1 # -6 + ERROR_INVALID_PRBS_MODE = -1 # -8 + ERROR_INVALID_TARGET = -1 # -9 + ERROR_INVALID_DIRECTION = -1 # -10 + ERROR_INVALID_POLARITY = -1 # -11 + ERROR_CMD_EXEC_FAILED = -1 # -12 + ERROR_PORT_LOCK_TIMEOUT = -1 # -13 + ERROR_INVALID_INPUT = -1 # -14 + ERROR_WR_EEPROM_FAILED = -1 + + ERROR_FW_GET_STATUS_FAILED = -1 # -15 + ERROR_NO_MATCHING_FW = -1 # -16 + ERROR_RESET_FAILED = -1 # -17 + ERROR_TOGGLE_FAILED = -1 # -18 + # ERROR_FW_ACTIVATE_FAILURE = -1 #-19 + # ERROR_FW_ROLLBACK_FAILURE = -1 #-20 + ERROR_GET_FEC_MODE_FAILED = -1 # -21 + ERROR_READ_SIDE_FAILED = -1 # -22 + + WARNING_FW_ALREADY_ACTIVE = -50 + WARNING_FW_ALREADY_ROLLEDBACK = -51 + + EEPROM_READ_DATA_INVALID = -1 # -100 + EEPROM_ERROR = -1 # -101 + API_FAIL = -1 # -102 + + ERROR_RW_NIC_FAILED = -1 # -30 #Unable to communicate with NIC MCU + ERROR_RW_TOR_FAILED = -1 # -31 #Unable to communicate with TOR MCU + ERROR_GET_VERSION_FAILED = -1 # -32 #Unable to get firmware version from MCU + ERROR_FLASH_SIZE_INVALID = -1 # -33 #Firmware image size is greater than flash bank size + ERROR_FLASH_ERASE_FAILED = -1 # -34 #Flash erase failed + ERROR_FLASH_WRITE_FAILED = -1 # -35 #Flash write failed + ERROR_FLASH_READ_FAILED = -1 # -36 #Flash read failed + ERROR_CRC32_FAILED = -1 # -37 #Flash CRC validation failed + ERROR_CMD_TIMEOUT = -1 # -38 #No response after command sent + ERROR_SYSTEM_BUSY = -1 # -39 #System is busy def __init__(self, port, logger1): - self.port = port + self.port = port self.platform_chassis = None - self.sfp = None - self.lock = PortLock(port) - self.logger = logger1 + self.sfp = None + self.lock = PortLock(port) + self.fp_lock = PortLock(port) + self.dl_lock = PortLock(port) + self.logger = logger1 self.download_firmware_status = self.FIRMWARE_DOWNLOAD_STATUS_NOT_INITIATED_OR_FINISHED super(YCable, self).__init__(port, logger1) try: #self.platform_chassis = chassis() self.platform_chassis = sonic_platform.platform.Platform().get_chassis() self.sfp = self.platform_chassis.get_sfp(self.port) - + logger1.log_info("chassis loaded {}".format(self.platform_chassis)) except Exception as e: logger1.log_warning("Failed to load chassis due to {}".format(repr(e))) @@ -413,7 +503,7 @@ def enable_all_log(self, enable): if self.logger is not None: self.logger.set_min_log_priority(7) print("Logging disabled...") - + def __get_pid_str(self): pid_str = "[{},{}] Port-{} : ".format(os.getpid(), threading.currentThread().getName(), self.port) return pid_str @@ -429,7 +519,6 @@ def log_timestamp(self, last_timestamp, log_msg): return curr_timestamp - def log(self, level, msg, also_print_to_console=False): msg = self.__get_pid_str() + msg @@ -452,34 +541,34 @@ def log(self, level, msg, also_print_to_console=False): def __util_convert_to_phyinfo_details(self, target, lane_map): """ - + This util API is internally used to simplify the calculation of core_ip, lane_mask - + """ - + if target == self.TARGET_NIC or target == self.EYE_PRBS_LOOPBACK_TARGET_NIC: core_ip = self.CORE_IP_NIC else: core_ip = self.CORE_IP_TOR - + read_side = self.get_read_side() is_torA = False - + if read_side == 1: is_torA = True if (target == self.EYE_PRBS_LOOPBACK_TARGET_LOCAL): target = read_side - + # if check is on TOR-B, make is_torA False if (target == self.TARGET_TOR_B or target == self.EYE_PRBS_LOOPBACK_TARGET_TOR_B) and read_side == self.TARGET_TOR_A: is_torA = False # if check is on TOR-A and read side is TOR-B, make is_torA False elif (target == self.TARGET_TOR_A or target == self.EYE_PRBS_LOOPBACK_TARGET_TOR_A) and read_side == self.TARGET_TOR_B: is_torA = True - + #lane_mask = lane_map - + if core_ip == self.CORE_IP_NIC: lane_mask = lane_map else: @@ -487,47 +576,46 @@ def __util_convert_to_phyinfo_details(self, target, lane_map): lane_mask = ((lane_map << 4) & 0xF0) | ((lane_map >> 4) & 0x0F) else: lane_mask = lane_map - + if core_ip == self.CORE_IP_TOR: core_ip = self.CORE_IP_CLIENT elif core_ip == self.CORE_IP_NIC: core_ip = self.CORE_IP_LW else: core_ip = self.CORE_IP_ALL - + return core_ip, lane_mask def __util_convert_to_loopback_phyinfo(self, target, lane_map, lb_mode): """ - + This util API is internally used to simplify the calculation of core_ip, lane_mask - + """ - + if target == self.TARGET_NIC or target == self.EYE_PRBS_LOOPBACK_TARGET_NIC: core_ip = self.CORE_IP_NIC else: core_ip = self.CORE_IP_TOR - + read_side = self.get_read_side() is_torA = False - + if read_side == self.TARGET_TOR_A: is_torA = True if (target == self.EYE_PRBS_LOOPBACK_TARGET_LOCAL): target = read_side - # if target is TOR-B, but read_side is TOR-A, make is_torA False if (target == self.TARGET_TOR_B or target == self.EYE_PRBS_LOOPBACK_TARGET_TOR_B) and read_side == self.TARGET_TOR_A: is_torA = False # if target is TOR-A but read_side is TOR-B, make is_torA True elif (target == self.TARGET_TOR_A or target == self.EYE_PRBS_LOOPBACK_TARGET_TOR_A) and read_side == self.TARGET_TOR_B: is_torA = True - + #lane_mask = lane_map - + if core_ip == self.CORE_IP_NIC: lane_mask = lane_map if lb_mode == self.LOOPBACK_MODE_FAR_END: @@ -536,7 +624,7 @@ def __util_convert_to_loopback_phyinfo(self, target, lane_map, lb_mode): mode = self.CABLE_NIC_RLOOPBACK_MODE else: self.log(self.LOG_ERROR, "Incorrect mode value") - + else: if is_torA is False: lane_mask = ((lane_map << 4) & 0xF0) | ((lane_map >> 4) & 0x0F) @@ -554,17 +642,16 @@ def __util_convert_to_loopback_phyinfo(self, target, lane_map, lb_mode): mode = self.CABLE_TOR_RLOOPBACK_MODE else: self.log(self.LOG_ERROR, "Incorrect mode value") - - + if core_ip == self.CORE_IP_TOR: core_ip = self.CORE_IP_CLIENT elif core_ip == self.CORE_IP_NIC: core_ip = self.CORE_IP_LW else: core_ip = self.CORE_IP_ALL - + return core_ip, lane_mask, mode - + def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): """ Internal function, sends command request to MCU and returns the response from MCU @@ -624,6 +711,8 @@ def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): sta = 0 curr_offset = self.QSFP_BRCM_CABLE_CTRL_CMD_STS result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if result is None: + return self.EEPROM_ERROR, None sta = result[0] if (sta & 0x01) == 0x0: @@ -644,22 +733,33 @@ def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): # - write the LW lane mask (Line) # - write the core ip value # - + # skip sending cmd_hdr for SET_HMUX_CONTEXT_PRI and SET_HMUX_CONTEXT_SEC - if (command_id != self.CABLE_CMD_ID_SET_HMUX_CONTEXT_PRI and \ - command_id != self.CABLE_CMD_ID_SET_HMUX_CONTEXT_SEC): + if ((command_id < self.CABLE_CMD_ID_SET_HMUX_CONTEXT_PRI) or + (command_id == self.CABLE_CMD_ID_READ_MCU_RAM) or + (command_id == self.CABLE_CMD_ID_CLEAR_CRASH)): curr_offset = self.QSFP_VEN_FE_130_BRCM_DATA_LENGHT_LSB result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 5, cmd_hdr) if result is False: self.log(self.LOG_ERROR, "write_eeprom() failed") return self.ERROR_WRITE_EEPROM_FAILED, None ts = self.log_timestamp(ts, "writing of cmd_hdr 5 bytes done") + else: + curr_offset = self.QSFP_VEN_FE_130_BRCM_DATA_LENGHT_LSB + 1 + cmd_rsp_len = cmd_hdr[1] + buffer1 = bytearray([cmd_rsp_len]) + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buffer1) + if result is False: + self.log(self.LOG_ERROR, "write_eeprom() failed") + return self.ERROR_WRITE_EEPROM_FAILED, None + ts = self.log_timestamp(ts, "writing of cmd_hdr (only rsp_len) 1 byte done") # write request data wr_len = cmd_hdr[0] if wr_len > 0: curr_offset = self.CMD_REQ_PARAM_START_OFFSET - result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, wr_len, cmd_req_body) + result = self.platform_chassis.get_sfp( + self.port).write_eeprom(curr_offset, wr_len, cmd_req_body) if result is False: return self.ERROR_WR_EEPROM_FAILED, None ts = self.log_timestamp(ts, "write request data done - bytes {}".format(wr_len)) @@ -682,6 +782,8 @@ def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): sta = 0 curr_offset = self.QSFP_BRCM_CABLE_CTRL_CMD_STS result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if result is None: + return self.EEPROM_ERROR, None sta = result[0] if (sta & 0x7F) == 0x11: @@ -696,7 +798,7 @@ def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): ms_elapsed = (time.monotonic_ns()//1000000) - (start//1000000) else: - self.log(self.LOG_ERROR, "CMD_STS never read as 0x11 or 0x31") + self.log(self.LOG_ERROR, "CMD_STS never read as 0x11 or 0x31. reg_value: {}".format(hex(sta))) ret_val = self.ERROR_CMD_PROCESSING_FAILED ts = self.log_timestamp(ts, "polling for status done") @@ -706,6 +808,8 @@ def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): if rd_len > 0: curr_offset = self.CMD_RSP_PARAM_START_OFFSET cmd_rsp_body = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, rd_len) + if cmd_rsp_body is None: + return self.EEPROM_ERROR, None ts = self.log_timestamp(ts, "read cmd response bytes {} done".format(rd_len)) # set the command request to idle state @@ -725,6 +829,8 @@ def __cable_cmd_execute(self, command_id, cmd_hdr, cmd_req_body): sta = 0 curr_offset = self.QSFP_BRCM_CABLE_CTRL_CMD_STS result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if result is None: + return self.EEPROM_ERROR, None sta = result[0] if (sta & 0x01) == 0x0: @@ -754,7 +860,7 @@ def __validate_read_data(self, result, size, message): ''' This API specifically used to validate the register read value ''' - + if result is not None: if isinstance(result, bytearray): if len(result) != size: @@ -773,9 +879,11 @@ def __validate_read_data(self, result, size, message): ############################################################################## # -### Public APIs +# Public APIs # ############################################################################## + + def get_api_version(self): """ Returns Broadcom y_cable api version @@ -792,34 +900,33 @@ def get_part_number(self): Returns: a string, with part number """ - + if self.sfp is not None: curr_offset = self.QSFP28_UP0_168_PN_1 part_result = self.sfp.read_eeprom(curr_offset, 15) else: self.log(self.LOG_ERROR, "platform_chassis is not loaded, failed to get vendor name and pn_number") return self.ERROR_PLATFORM_NOT_LOADED - + if self.__validate_read_data(part_result, 15, "get part_number") == self.EEPROM_READ_DATA_INVALID: return self.EEPROM_ERROR part_number = str(part_result.decode()) self.log(self.LOG_DEBUG, "Part number = {}".format(part_number)) - + return part_number - + 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: None Returns: a string, with vendor name """ - if self.platform_chassis is not None: curr_offset = self.QSFP28_UP0_148_VENDOR_NAME_0 vendor_result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 15) @@ -851,9 +958,9 @@ def get_read_side(self): TARGET_NIC, if reading the Y cable from NIC side. TARGET_UNKNOWN, if reading the Y cable API fails. """ - + start_ts = datetime.utcnow() - ts = self.log_timestamp(start_ts," get_read_side() start") + ts = self.log_timestamp(start_ts, " get_read_side() start") if self.platform_chassis is not None: curr_offset = self.QSFP28_UP0_224_SPECIFIC_1_RSV @@ -861,22 +968,22 @@ def get_read_side(self): else: self.log(self.LOG_ERROR, "platform_chassis is not loaded, failed to check read side") return self.ERROR_PLATFORM_NOT_LOADED - + if self.__validate_read_data(result, 1, "read side") == self.EEPROM_READ_DATA_INVALID: return self.EEPROM_ERROR read_side = struct.unpack("> 8) & 0xFF + dat[2] = (upgrade_head.cable_up_info.image_info.image_size >> 16) & 0xFF + dat[3] = upgrade_head.cable_up_info.destination + dat[4] = upgrade_head.cable_up_info.image_info.image_fw_version.image_version_minor & 0xFF + dat[5] = (upgrade_head.cable_up_info.image_info.image_fw_version.image_version_minor >> 8) & 0xFF + dat[6] = upgrade_head.cable_up_info.image_info.image_fw_version.image_version_major & 0xFF + dat[7] = (upgrade_head.cable_up_info.image_info.image_fw_version.image_version_major >> 8) & 0xFF + dat[8] = upgrade_head.cable_up_info.image_info.image_api_version.image_version_minor & 0xFF + dat[9] = (upgrade_head.cable_up_info.image_info.image_api_version.image_version_minor >> 8) & 0xFF + dat[10] = upgrade_head.cable_up_info.image_info.image_api_version.image_version_major & 0xFF + dat[11] = (upgrade_head.cable_up_info.image_info.image_api_version.image_version_major >> 8) & 0xFF + dat[12] = upgrade_head.cable_up_info.image_info.image_crc32 & 0xFF + dat[13] = (upgrade_head.cable_up_info.image_info.image_crc32 >> 8) & 0xFF + dat[14] = (upgrade_head.cable_up_info.image_info.image_crc32 >> 16) & 0xFF + dat[15] = (upgrade_head.cable_up_info.image_info.image_crc32 >> 24) & 0xFF + dat[16] = self.FW_UP_PACKET_SIZE + dat[17] = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 + + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_HEADER_0_7, 18, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + ts = self.log_timestamp(ts, "Image header sent") + + # Write compression header + dat[0] = (upgrade_head.compression & 0xFF) + dat[1] = (upgrade_head.compressed_size & 0xFF) + dat[2] = ((upgrade_head.compressed_size >> 8) & 0xFF) + dat[3] = ((upgrade_head.compressed_size >> 16) & 0xFF) + dat[4] = ((upgrade_head.compressed_size >> 24) & 0xFF) + dat[5] = (upgrade_head.compressed_crc32 & 0xFF) + dat[6] = ((upgrade_head.compressed_crc32 >> 8) & 0xFF) + dat[7] = ((upgrade_head.compressed_crc32 >> 16) & 0xFF) + dat[8] = ((upgrade_head.compressed_crc32 >> 24) & 0xFF) + dat[9] = (upgrade_head.add_size & 0xFF) + dat[10] = ((upgrade_head.add_size >> 8) & 0xFF) + dat[11] = ((upgrade_head.add_size >> 16) & 0xFF) + dat[12] = ((upgrade_head.add_size >> 24) & 0xFF) + dat[13] = (upgrade_head.add_crc32 & 0xFF) + dat[14] = ((upgrade_head.add_crc32 >> 8) & 0xFF) + dat[15] = ((upgrade_head.add_crc32 >> 16) & 0xFF) + dat[16] = ((upgrade_head.add_crc32 >> 24) & 0xFF) + + # Header CRC + dat[17] = (upgrade_head.header_crc32 & 0xFF) + dat[18] = ((upgrade_head.header_crc32 >> 8) & 0xFF) + dat[19] = ((upgrade_head.header_crc32 >> 16) & 0xFF) + dat[20] = ((upgrade_head.header_crc32 >> 24) & 0xFF) + + curr_offset = ((self.QSFP_BRCM_FW_UPGRADE_PAGE*128) + self.QSFP_BRCM_FW_UPGRADE_COMP_SET) + if self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 21, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + ts = self.log_timestamp(ts, "compression header sent") + + # Send request firmware upgrad to START + self.log(self.LOG_INFO, "START ERASING") + + dat[0] = (self.FW_CMD_START << 1) | 1 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + time.sleep(3.5) + ts = self.log_timestamp(ts, "Erase command sent") + + # Check response status + self.log(self.LOG_DEBUG, "check MCU ready status") for i in range(3000): - curr_offset = (self.QSFP_BRCM_DIAGNOSTIC_PAGE * 128) + self.QSFP_BRCM_DIAGNOSTIC_STATUS - status = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) - if status[0] == 0: - break + status = self.__util_read_eeprom( + (self.QSFP_BRCM_FW_UPGRADE_PAGE * 128 + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if status[0] & 0x01: + if (status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): + self.log(self.LOG_DEBUG, "MCU is Ready") + req_status = True + break + else: + if (status[0] & 0xFC) == (self.FW_UP_IN_PROGRESS << 2): + ret_val = self.RR_ERROR_SYSTEM_UNAVAILABLE + self.log(self.LOG_WARN, "System Unavailable/busy...") + #self.__handle_error_abort(upgrade_head.cable_up_info, 1) + return ret_val + time.sleep(0.001) - if status[0]: - self.log(self.LOG_ERROR, "Unable to communicate with NIC MCU") - #return self.RR_ERROR - return self.ERROR_RW_NIC_FAILED - ts = self.log_timestamp(ts,"TOR to NIC MCU communication is alive") + ts = self.log_timestamp(ts, "MCU ready check done") + # if MCU is ready + if req_status: + req_status = False + # set the command request to idle state + self.log(self.LOG_DEBUG, "set the command request to idle state ") + dat[0] = 0x00 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED - with self.lock.acquire_timeout(self.PORT_LOCK_TIMEOUT) as result: - if result: - # read cable command and status offsets - self.log(self.LOG_DEBUG, "read cable command and status offsets") - result = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD), 2, "cable_fw_upgrade") - if result != self.EEPROM_READ_DATA_INVALID: - dat[0] = result[0] - dat[1] = result[1] - if ((dat[0] & 0x01) != 0) or ((dat[1] & 0x01) != 0): - self.log(self.LOG_DEBUG, "MCU not in the right state. Sending abort") - ret_val = self.__cable_fw_mcu_abort(upgrade_info) - if ret_val != self.RR_SUCCESS: - self.log(self.LOG_ERROR, "MCU abort failed") - return ret_val + # wait for mcu response to be pulled down + self.log(self.LOG_DEBUG, "wait for mcu response to be pulled down ") + for _ in range(100): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self. QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if (status[0] & 0x01) == 0: + req_status = True + break time.sleep(0.001) - result = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD), 2, "cable_fw_upgrade") - dat[0] = result[0] - dat[1] = result[1] - - # check if any command is currently being executed - self.log(self.LOG_DEBUG, "check if any command is currently being executed") - if ((dat[0] & 0x01) == 0) and ((dat[1] & 0x01) == 0): - # Start command - Debug Prints - destination = None - - if upgrade_info.destination == self.TOR_MCU_SELF: - destination = "TOR MCU SELF" - elif upgrade_info.destination == self.TOR_MCU_PEER: - destination = "TOR MCU PEER" - elif upgrade_info.destination == self.NIC_MCU: - destination = "NIC MCU" - elif upgrade_info.destination == self.MUX_CHIP: - destination = "MUX CHIP" - else: - self.log(self.LOG_ERROR, "Wrong destination") - return self.ERROR_INVALID_TARGET - - self.log(self.LOG_DEBUG, "Starting firmware upgrade to {}".format(destination)) - - self.log(self.LOG_DEBUG, "FW Version minor: {}".format(hex(upgrade_info.image_info.image_fw_version.image_version_minor))) - self.log(self.LOG_DEBUG, "FW Version major: {}".format(hex(upgrade_info.image_info.image_fw_version.image_version_major))) - if upgrade_info.destination == self.TOR_MCU_SELF or upgrade_info.destination == self.TOR_MCU_PEER: - self.log(self.LOG_DEBUG, "API version minor: {}".format(hex(upgrade_info.image_info.image_api_version.image_version_minor))) - self.log(self.LOG_DEBUG, "API version major: {}".format(hex(upgrade_info.image_info.image_api_version.image_version_major))) - self.log(self.LOG_DEBUG, "CRC32 : {}".format(hex(upgrade_info.image_info.image_crc32))) - self.log(self.LOG_DEBUG, "Image size : {}".format(hex(upgrade_info.image_info.image_size))) - - # Send image header - self.log(self.LOG_DEBUG, "send image header") - dat[0] = upgrade_info.image_info.image_size & 0xff - dat[1] = (upgrade_info.image_info.image_size >> 8) & 0xFF - dat[2] = (upgrade_info.image_info.image_size >> 16) & 0xFF - dat[3] = upgrade_info.destination - dat[4] = upgrade_info.image_info.image_fw_version.image_version_minor & 0xFF - dat[5] = (upgrade_info.image_info.image_fw_version.image_version_minor >> 8) & 0xFF - dat[6] = upgrade_info.image_info.image_fw_version.image_version_major & 0xFF - dat[7] = (upgrade_info.image_info.image_fw_version.image_version_major >> 8) & 0xFF - dat[8] = upgrade_info.image_info.image_api_version.image_version_minor & 0xFF - dat[9] = (upgrade_info.image_info.image_api_version.image_version_minor >> 8) & 0xFF - dat[10] = upgrade_info.image_info.image_api_version.image_version_major & 0xFF - dat[11] = (upgrade_info.image_info.image_api_version.image_version_major >> 8) & 0xFF - dat[12] = upgrade_info.image_info.image_crc32 & 0xFF - dat[13] = (upgrade_info.image_info.image_crc32 >> 8) & 0xFF - dat[14] = (upgrade_info.image_info.image_crc32 >> 16) & 0xFF - dat[15] = (upgrade_info.image_info.image_crc32 >> 24) & 0xFF - dat[16] = self.FW_UP_PACKET_SIZE - dat[17] = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 - - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_HEADER_0_7, 18, dat) - - ts = self.log_timestamp(ts,"Image header sent") - - # Send request firmware upgrad to START - self.log(self.LOG_INFO, "START ERASING") - - dat[0] = (self.FW_CMD_START << 1) | 1 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - - time.sleep(3.5) - - ts = self.log_timestamp(ts,"Erase command sent") - - # Check response status - self.log(self.LOG_DEBUG, "check MCU ready status") - for i in range(3000): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + + if not req_status: + self.log(self.LOG_ERROR, "Timeout ") + self.__handle_error_abort(upgrade_head.cable_up_info, 2) + return ret_val + ts = self.log_timestamp(ts, "MCU response pulled down") + + else: + self.log(self.LOG_ERROR, "ERROR MCU is not ready ") + self.__handle_error_abort(upgrade_head.cable_up_info, 17) + return ret_val + + # if MCU response pulled down + if req_status: + # TRANSFER command + self.log(self.LOG_INFO, "FW image transfer start ") + tmp_image_ptr = upgrade_head.cable_up_info.image_info.image_ptr + remain_page_size = 0 + image_to_page_size = 0 + count = 0 + page_loc = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 + if((upgrade_head.compression & 0xFF)): + tmp_image_size = upgrade_head.compressed_size + else: + tmp_image_size = upgrade_head.cable_up_info.image_info.image_size + + remain_page_size = tmp_image_size % self.FW_UP_PACKET_SIZE + image_to_page_size = tmp_image_size - remain_page_size + + # MCU is now ready for firmware upgrade, Start the loop to transfre the data + self.log(self.LOG_DEBUG, "MCU is now ready for firmware upgrade, Start the loop to transfer the data") + dat[0] = self.FW_UP_PACKET_SIZE + dat[1] = page_loc + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_PACKET_SIZE, 2, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + self.log(self.LOG_DEBUG, "Writing packet to page_loc {} fw_up_packet_size : {}".format( + page_loc, self.FW_UP_PACKET_SIZE)) + + for i in range(0, self.FW_UP_PACKET_SIZE, 4): + dat[0 + i] = tmp_image_ptr[count] & 0xFF + dat[1 + i] = (tmp_image_ptr[count] >> 8) & 0xFF + dat[2 + i] = (tmp_image_ptr[count] >> 16) & 0xFF + dat[3 + i] = (tmp_image_ptr[count] >> 24) & 0xFF + count += 1 + + if self.platform_chassis.get_sfp(self.port).write_eeprom((page_loc*128) + self.QSFP_BRCM_FW_UPGRADE_DATA_START, self.FW_UP_PACKET_SIZE, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + ts = self.log_timestamp(ts, "First packet written") + + self.log(self.LOG_INFO, "TRANSFERING remaining packets..") + + dat[0] = (self.FW_CMD_TRANSFER << 1) | 1 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + # prepare and send remaining packets + for _ in range(self.FW_UP_PACKET_SIZE, image_to_page_size, self.FW_UP_PACKET_SIZE): + req_status = False + + # Toggle data page_loc + page_loc = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 if( + page_loc == self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2) else self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2 + + # prepare packet data + for i in range(0, self.FW_UP_PACKET_SIZE, 4): + dat[0 + i] = tmp_image_ptr[count] & 0xFF + dat[1 + i] = (tmp_image_ptr[count] >> 8) & 0xFF + dat[2 + i] = (tmp_image_ptr[count] >> 16) & 0xFF + dat[3 + i] = (tmp_image_ptr[count] >> 24) & 0xFF + count += 1 + + # write packet + if self.platform_chassis.get_sfp(self.port).write_eeprom((page_loc*128) + self.QSFP_BRCM_FW_UPGRADE_DATA_START, self.FW_UP_PACKET_SIZE, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + # Check response status for previous packet + for i in range(500): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR if status[0] & 0x01: - if (status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): - self.log(self.LOG_DEBUG, "MCU is Ready") + if(status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): req_status = True + tmp_cnt += self.FW_UP_PACKET_SIZE + if tmp_cnt >= (tmp_image_size / 100): + tmp_cnt = 0 + tmp_print += 1 + #_logger.log_info(" {}%".format(tmp_print),CONSOLE_PRINT) + print(" {}% (tmp_cnt {})".format(tmp_print, tmp_cnt)) break else: - if (status[0] & 0xFC) == (self.FW_UP_IN_PROGRESS << 2): - ret_val = self.RR_ERROR_SYSTEM_UNAVAILABLE - self.__handle_error_abort(upgrade_info, 1) - return ret_val + # ERROR + self.log(self.LOG_ERROR, "ERROR: TRANSFER error {}".format((status[0] & 0xFC) >> 2)) + self.__handle_error_abort(upgrade_head.cable_up_info, 3) + return ret_val time.sleep(0.001) - ts = self.log_timestamp(ts,"MCU ready check done") - - # if MCU is ready + # if previous packet sent successfully if req_status: req_status = False - # set the command request to idle state - self.log(self.LOG_DEBUG, "set the command request to idle state ") + + # Set the command request to idle state dat[0] = 0x00 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED # wait for mcu response to be pulled down - self.log(self.LOG_DEBUG, "wait for mcu response to be pulled down ") - for i in range(100): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self. QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - if (status[0] & 0x01) == 0: + for i in range(1000): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if(status[0] & 0x01) == 0: + # Previous packet is OK + # Set MCU write the next packet + dat[0] = self.FW_UP_PACKET_SIZE + dat[1] = page_loc + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_PACKET_SIZE, 2, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + dat[0] = (self.FW_CMD_TRANSFER << 1) | 1 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED req_status = True break - time.sleep(0.001) if not req_status: - self.log(self.LOG_ERROR, "MCU state - not pulled down ") - self.__handle_error_abort(upgrade_info, 2) + # Time out how to handle + self.log(self.LOG_ERROR, "cable_fw_upgrade : handle erro abort1") + self.__handle_error_abort(upgrade_head.cable_up_info, 4) return ret_val - ts = self.log_timestamp(ts, "MCU response pulled down") else: - self.log(self.LOG_ERROR, "ERROR MCU is not ready ") - self.__handle_error_abort(upgrade_info, 17) - return ret_val + # Check if error status or timeout + if not req_status: + self.log(self.LOG_ERROR, "ERROR: TRANSFER timed out") - # if MCU response pulled down - if req_status: - # TRANSFER command - self.log(self.LOG_INFO, "FW image transfer start ") - tmp_image_ptr = upgrade_info.image_info.image_ptr - count = 0 - page_loc = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 - - # MCU is now ready for firmware upgrade, Start the loop to transfre the data - self.log(self.LOG_DEBUG, "MCU is now ready for firmware upgrade, Start the loop to transfer the data") - dat[0] = self.FW_UP_PACKET_SIZE - dat[1] = page_loc - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_PACKET_SIZE, 2, dat) - self.log(self.LOG_DEBUG, "fw_up_packet_size : {}".format(dat[0]),"page_loc : {}".format(dat[1])) - - for i in range(0, self.FW_UP_PACKET_SIZE, 4): - dat[0 + i] = tmp_image_ptr[count] & 0xFF - dat[1 + i] = (tmp_image_ptr[count] >> 8) & 0xFF - dat[2 + i] = (tmp_image_ptr[count] >> 16) & 0xFF - dat[3 + i] = (tmp_image_ptr[count] >> 24) & 0xFF + self.__handle_error_abort(upgrade_head.cable_up_info, 5) + return ret_val + ts = self.log_timestamp(ts, "All packets written... Check response for last page") + + # Transfer remaining bytes if less than a page + if remain_page_size: + req_status = False + + # Toggle data page_loc + page_loc = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 if( + page_loc == self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2) else self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2 + j = 0 + for i in range(remain_page_size): + dat[i] = ((tmp_image_ptr[count] >> (8 * j)) & 0xFF) + j += 1 + if j >= 4: count += 1 - - self.platform_chassis.get_sfp(self.port).write_eeprom((page_loc*128) + self.QSFP_BRCM_FW_UPGRADE_DATA_START, self.FW_UP_PACKET_SIZE, dat) - ts = self.log_timestamp(ts, "First packet written") - - self.log(self.LOG_DEBUG, "TRANSFERING remaining packets..") - - dat[0] = (self.FW_CMD_TRANSFER << 1) | 1 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - - # prepare and send remaining packets - for _ in range(self.FW_UP_PACKET_SIZE, upgrade_info.image_info.image_size, self.FW_UP_PACKET_SIZE): - req_status = False - - # Toggle data page_loc - page_loc = self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_1 if(page_loc == self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2) else self.QSFP_BRCM_FW_UPGRADE_DATA_PAGE_2 - - # prepare packet data - for i in range(0, self.FW_UP_PACKET_SIZE, 4): - dat[0 + i] = tmp_image_ptr[count] & 0xFF - dat[1 + i] = (tmp_image_ptr[count] >> 8) & 0xFF - dat[2 + i] = (tmp_image_ptr[count] >> 16) & 0xFF - dat[3 + i] = (tmp_image_ptr[count] >> 24) & 0xFF - count += 1 - - # write packet - self.platform_chassis.get_sfp(self.port).write_eeprom((page_loc*128) + self.QSFP_BRCM_FW_UPGRADE_DATA_START, self.FW_UP_PACKET_SIZE, dat) - - # Check response status for previous packet - for i in range(500): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - if status[0] & 0x01: - if(status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): - req_status = True - tmp_cnt += self.FW_UP_PACKET_SIZE - if tmp_cnt >= (upgrade_info.image_info.image_size / 100): - tmp_cnt = 0 - tmp_print += 1 - #_logger.log_info(" {}%".format(tmp_print),CONSOLE_PRINT) - print(" {}%".format(tmp_print)) - break - else: - #ERROR - self.log(self.LOG_ERROR, "ERROR: TRANSFER error {}".format((status[0] & 0xFC) >> 2)) - self.__handle_error_abort(upgrade_info, 3) - return ret_val - - time.sleep(0.001) - - # if previous packet sent successfully - if req_status: - req_status = False - - # Set the command request to idle state - dat[0] = 0x00 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - - # wait for mcu response to be pulled down - for i in range(100): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - - if(status[0] & 0x01) == 0: - # Previous packet is OK - # Set MCU write the next packet - dat[0] = self.FW_UP_PACKET_SIZE - dat[1] = page_loc - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_PACKET_SIZE, 2, dat) - - dat[0] = (self.FW_CMD_TRANSFER << 1) | 1 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - req_status = True - break - time.sleep(0.001) - - if not req_status: - self.log(self.LOG_ERROR, "cable_fw_upgrade : handle error abort1") - self.__handle_error_abort(upgrade_info, 4) - return ret_val - + j = 0 + # write packet + if self.platform_chassis.get_sfp(self.port).write_eeprom(((page_loc*128) + self.QSFP_BRCM_FW_UPGRADE_DATA_START), remain_page_size, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + # Check response status for previous packet + for i in range(500): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if status[0] & 0x01: + if(status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): + req_status = True + tmp_cnt += self.FW_UP_PACKET_SIZE + if tmp_cnt >= (upgrade_head.cable_up_info.image_info.image_size / 100): + tmp_cnt = 0 + tmp_print += 1 + #_logger.log_info(" {}%".format(tmp_print),CONSOLE_PRINT) + print(" {}% (tmp_cnt: {})".format(tmp_print, tmp_cnt)) + break else: - if not req_status: - self.log(self.LOG_ERROR, "ERROR: TRANSFER timed out") - - self.__handle_error_abort(upgrade_info, 5) + # ERROR + self.log(self.LOG_ERROR, "ERROR: TRANSFER error {}".format((status[0] & 0xFC) >> 2)) + self.__handle_error_abort(upgrade_head.cable_up_info, 3) return ret_val - ts = self.log_timestamp(ts,"All packets written... Check response for last page") - # Check response status for last page - for i in range(100): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - - if status[0] & 0x01: - if (status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): - req_status = True - self.log(self.LOG_DEBUG, " 100% ") - break - else: - # ERROR - self.log(self.LOG_ERROR, "ERROR: TRANSFER error{}".format((status[0] & 0xFC) >> 2)) - self.__handle_error_abort(upgrade_info, 3) - return ret_val + time.sleep(0.001) + + # if previous packet sent successfully + if req_status: + req_status = False + # Set the command request to idle state + dat[0] = 0x00 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED, + + # Wait for mcu response to be pulled down + for i in range(1000): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self. QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if (status[0] & 0x01) == 0: + # Previous packet is OK + # Set MCU to write the next packet + dat[0] = remain_page_size + dat[1] = page_loc + curr_offset = ((self.QSFP_BRCM_FW_UPGRADE_PAGE*128) + + self.QSFP_BRCM_FW_UPGRADE_PACKET_SIZE) + if self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 2, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + dat[0] = (self.FW_CMD_TRANSFER << 1) | 1 + curr_offset = ((self.QSFP_BRCM_FW_UPGRADE_PAGE*128) + + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD) + if self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + req_status = True + break time.sleep(0.001) + if not req_status: + self.__handle_error_abort(upgrade_head.cable_up_info, 4) + # return ret_val + return self.ERROR_CMD_TIMEOUT + else: + if not req_status: + # Timeout + self.log(self.LOG_ERROR, "Transfer timeout") + self.__handle_error_abort(upgrade_head.cable_up_info, 5) + # return ret_val + return self.ERROR_CMD_TIMEOUT + + # Check response status for last page + for i in range(100): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR - ts = self.log_timestamp(ts,"Check response for last page done") - - if req_status: - req_status = False - - # Set the command request to idle state - dat[0] = 0x00 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - - # Wait for mcu response to be pulled down - for i in range(100): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self. QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - if (status[0] & 0x01) == 0: - # Last packet is OK - req_status = True - break - time.sleep(0.001) - if not req_status: - # Timeout, how to handle? - self.__handle_error_abort(upgrade_info, 4) - #return ret_val - return self.ERROR_CMD_TIMEOUT - - ts = self.log_timestamp(ts,"Wait for mcu response to be pulled down2") + if status[0] & 0x01: + if (status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): + req_status = True + self.log(self.LOG_DEBUG, " 100% ") + break else: - if not req_status: - self.log(self.LOG_ERROR, "ERROR: TRANSFER timed out") - self.__handle_error_abort( upgrade_info, 5) + # ERROR + self.log(self.LOG_ERROR, "ERROR: TRANSFER error{}".format((status[0] & 0xFC) >> 2)) + self.__handle_error_abort(upgrade_head.cable_up_info, 3) return ret_val - # COMPLETE command - # Send firmware upgrade complete - req_status = False - self.log(self.LOG_INFO, "TRANSFER COMPLETE") - ts = self.log_timestamp(ts,"TRANSFER complete") - - dat[0] = (self.FW_CMD_COMPLETE << 1) | 1 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - - # Check response status - for i in range(100): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - - # Check response status - if status[0] & 0x01: - if (status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): - # MCU SUCCEEDED - req_status = True - break - else: - # ERROR - self.__handle_error_abort(upgrade_info, 6) - return ret_val - time.sleep(0.001) + time.sleep(0.001) + ts = self.log_timestamp(ts, "Check response for last page done") + + if req_status: + req_status = False + + # Set the command request to idle state + dat[0] = 0x00 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + # Wait for mcu response to be pulled down + for i in range(100): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self. QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if (status[0] & 0x01) == 0: + # Last packet is OK + req_status = True + break + time.sleep(0.001) + if not req_status: + # Timeout, how to handle? + self.__handle_error_abort(upgrade_head.cable_up_info, 4) + # return ret_val + return self.ERROR_CMD_TIMEOUT + ts = self.log_timestamp(ts, "Wait for mcu response to be pulled down2") + + else: + if not req_status: + self.log(self.LOG_ERROR, "ERROR: TRANSFER timed out") + self.__handle_error_abort(upgrade_head.cable_up_info, 5) + return ret_val + + # COMPLETE command + # Send firmware upgrade complete + req_status = False + self.log(self.LOG_INFO, "TRANSFER COMPLETE") + ts = self.log_timestamp(ts, "TRANSFER complete") + + dat[0] = (self.FW_CMD_COMPLETE << 1) | 1 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED + + # Check response status + for i in range(100): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR - ts = self.log_timestamp(ts,"MCU check response state good") - if req_status: - req_status = False - # Set the command request to idle state - dat[0] = 0x00 - self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) - - # wait for mcu response to be pulled down - for i in range(100): - status = self.__util_read_eeprom((QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") - if (status[0] & 0x01) == 0: - # MCU is Ready - req_status = True - ret_val = self.RR_SUCCESS - break - time.sleep(0.001) - - if not req_status: - # Timeout - self.log(self.LOG_ERROR, "Timed out - MCU pull down polling") - self.__handle_error_abort(upgrade_info, 7) - #return ret_val - return self.ERROR_CMD_TIMEOUT - - self.log_timestamp(ts,"wait for mcu response to be pulled down3") + # Check response status + if status[0] & 0x01: + if (status[0] & 0xFC) == (self.FW_UP_SUCCESS << 2): + # MCU SUCCEEDED + req_status = True + break else: # ERROR - self.log(self.LOG_ERROR, "ERROR") - self.__handle_error_abort(upgrade_info, 8) + self.__handle_error_abort(upgrade_head.cable_up_info, 6) return ret_val - else: - self.log(self.LOG_WARN, "MCU not in the right state") - else: - self.log(self.LOG_ERROR, "Port lock timed-out!") - return self.ERROR_PORT_LOCK_TIMEOUT + time.sleep(0.001) - self.log_timestamp(start_tstamp, "FW upgrade complete") + ts = self.log_timestamp(ts, "MCU check response state good") + if req_status: + req_status = False + # Set the command request to idle state + dat[0] = 0x00 + if self.platform_chassis.get_sfp(self.port).write_eeprom(QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CTRL_CMD, 1, dat) is False: + return self.ERROR_WR_EEPROM_FAILED - return ret_val + # wait for mcu response to be pulled down + for i in range(100): + status = self.__util_read_eeprom( + (QSFP_PAGE_OFFSET + self.QSFP_BRCM_FW_UPGRADE_CMD_STS), 1, "cable_fw_upgrade") + if status is None: + return self.EEPROM_ERROR + if (status[0] & 0x01) == 0: + # MCU is Ready + req_status = True + ret_val = self.RR_SUCCESS + break + time.sleep(0.001) + + if not req_status: + # Timeout + self.log(self.LOG_ERROR, "Timed out - MCU pull down polling") + self.__handle_error_abort(upgrade_head.cable_up_info, 7) + # return ret_val + return self.ERROR_CMD_TIMEOUT + self.log_timestamp(ts, "wait for mcu response to be pulled down3") + else: + # ERROR + self.log(self.LOG_ERROR, "ERROR") + self.__handle_error_abort(upgrade_head.cable_up_info, 8) + return ret_val + else: + self.log(self.LOG_WARN, "MCU not in the right state") + self.log_timestamp(start_tstamp, "FW upgrade complete") + return ret_val def get_firmware_version(self, target): """ @@ -2262,14 +2884,15 @@ def get_firmware_version(self, target): and their corresponding values """ - dat = [1000] - dat1 = [1000] + dat = [] + dat1 = [] i = 0 - result = {} + fw_ver_dict = {} upgrade_info = cable_upgrade_info_s() if (target != self.TARGET_TOR_A) and (target != self.TARGET_TOR_B) and (target != self.TARGET_NIC): - return self.RR_ERROR + self.log(self.LOG_ERROR, "Invalid target : {}".format(target)) + return self.ERROR_INVALID_TARGET if self.platform_chassis is not None: @@ -2284,72 +2907,95 @@ def get_firmware_version(self, target): target = self.TOR_MCU_SELF if (read_side == 2) else self.TOR_MCU_PEER else: target = self.NIC_MCU - - upgrade_info.destination = target - - self.log(self.LOG_DEBUG, "read_side {} target {}".format(read_side, target)) - - ret_val = self.cable_fw_get_status(upgrade_info) - if ret_val != self.RR_ERROR: - if upgrade_info.status_info.current_bank == 1: - # Active version - dat.append(format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) - # Inactive version - dat.append(format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) - else: - dat.append(format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) - dat.append(format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) - if upgrade_info.status_info.next_bank == 1: - dat.append(format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) - else: - dat.append(format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + # 1s timeout + with self.dl_lock.acquire_timeout(1) as result: + + if result: + upgrade_info.destination = target + + self.log(self.LOG_DEBUG, "read_side {} target {}".format(read_side, target)) + + ret_val = self.cable_fw_get_status(upgrade_info) + if ret_val != self.RR_ERROR: + if upgrade_info.status_info.current_bank == 1: + # Active version + dat.append(format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) + # Inactive version + dat.append(format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + else: + dat.append(format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + dat.append(format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) + + if upgrade_info.status_info.next_bank == 1: + dat.append(format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) + else: + dat.append(format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) - else: - self.log(self.LOG_ERROR, "Error getting version for {}".format("TOR MCU SELF" if target == self.TOR_MCU_SELF else "TOR MCU PEER" if target == self.TOR_MCU_PEER else "NIC MCU")) - #return self.RR_ERROR - return self.ERROR_GET_VERSION_FAILED - - if target == self.NIC_MCU: - upgrade_info.destination = self.MUX_CHIP - ret_val = self.cable_fw_get_status(upgrade_info) - if ret_val != self.RR_ERROR: - if upgrade_info.status_info.current_bank == 1: - # Active version - # Active version - dat1.append('.' + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) - dat1.append('.' + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) - # Inactive version - else: - dat1.append('.' + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) - dat1.append('.' + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) - if upgrade_info.status_info.next_bank == 1: - # Active version - dat1.append('.' + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) else: - dat1.append('.' + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + self.log(self.LOG_ERROR, "Error getting version for {}".format("TOR MCU SELF" if target == + self.TOR_MCU_SELF else "TOR MCU PEER" if target == self.TOR_MCU_PEER else "NIC MCU")) + # return self.RR_ERROR + return self.ERROR_GET_VERSION_FAILED + + if target == self.NIC_MCU: + upgrade_info.destination = self.MUX_CHIP + ret_val = self.cable_fw_get_status(upgrade_info) + if ret_val != self.RR_ERROR: + if upgrade_info.status_info.current_bank == 1: + # Active version + # Active version + dat1.append('.' + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, + 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) + dat1.append('.' + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, + 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + # Inactive version + else: + dat1.append('.' + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, + 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + dat1.append('.' + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, + 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) + if upgrade_info.status_info.next_bank == 1: + # Active version + dat1.append('.' + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_major, + 'X') + "." + format(upgrade_info.status_info.bank1_info.image_fw_version.image_version_minor, 'X')) + else: + dat1.append('.' + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_major, + 'X') + "." + format(upgrade_info.status_info.bank2_info.image_fw_version.image_version_minor, 'X')) + else: + self.log(self.LOG_ERROR, "Error getting version for MUX CHIP") + # return self.RR_ERROR + return self.ERROR_GET_VERSION_FAILED + + for i in range(0, 3): + dat[i] = dat[i] + dat1[i] + + if target == self.TOR_MCU_SELF: + fw_ver_dict["version_active"] = dat[0] + fw_ver_dict["version_inactive"] = dat[1] + fw_ver_dict["version_next"] = dat[2] + elif target == self.TOR_MCU_PEER: + fw_ver_dict["version_active"] = dat[0] + fw_ver_dict["version_inactive"] = dat[1] + fw_ver_dict["version_next"] = dat[2] + elif target == self.NIC_MCU: + fw_ver_dict["version_active"] = dat[0] + fw_ver_dict["version_inactive"] = dat[1] + fw_ver_dict["version_next"] = dat[2] + + return fw_ver_dict + else: - self.log(self.LOG_ERROR, "Error getting version for MUX CHIP") - #return self.RR_ERROR - return self.ERROR_GET_VERSION_FAILED + self.log(self.LOG_ERROR, "DL Port lock timed-out!") + #ret_val = self.ERROR_PORT_LOCK_TIMEOUT - for i in range(0, 4): - dat[i] = dat[i] + dat1[i] - - if target == self.TOR_MCU_SELF: - result["version_active"] = dat[1] - result["version_inactive"] = dat[2] - result["version_next"] = dat[3] - elif target == self.TOR_MCU_PEER: - result["version_active"] = dat[1] - result["version_inactive"] = dat[2] - result["version_next"] = dat[3] - elif target == self.NIC_MCU: - result["version_active"] = dat[1] - result["version_inactive"] = dat[2] - result["version_next"] = dat[3] - - return result + return None def get_local_temperature(self): """ @@ -2362,9 +3008,20 @@ def get_local_temperature(self): Returns: an Integer, the temperature of the local MCU """ + read_side = self.get_read_side() + + if read_side == self.TARGET_TOR_A: + curr_offset = 0xFD * 128 + 0x86 + elif read_side == self.TARGET_TOR_B: + curr_offset = 0xFD * 128 + 0x8a + elif read_side == self.TARGET_NIC: + curr_offset = 0xFD * 128 + 0x8e + else: + self.log(self.LOG_ERROR, "get_local_temperature: unknown read_side") + return -1 if self.platform_chassis is not None: - curr_offset = self.QSFP28_VENFD_129_DIE_TEMP_MSB + #curr_offset = self.QSFP28_VENFD_129_DIE_TEMP_MSB result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) if result is None: self.log(self.LOG_ERROR, "get local temperature read eeprom failed") @@ -2389,8 +3046,30 @@ def get_local_voltage(self): a float, the voltage of the local MCU """ - return None + read_side = self.get_read_side() + + if read_side == self.TARGET_TOR_A: + curr_offset = 0xFD * 128 + 0x88 + elif read_side == self.TARGET_TOR_B: + curr_offset = 0xFD * 128 + 0x8c + elif read_side == self.TARGET_NIC: + return None + else: + self.log(self.LOG_ERROR, "get_local_voltage: unknown read_side") + return -1 + + if self.platform_chassis is not None: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 2) + if result is None: + self.log(self.LOG_ERROR, "get local temperature read eeprom failed") + return self.EEPROM_ERROR + else: + temperature = result[0] << 8 | result[1] + else: + self.log(self.LOG_ERROR, "platform_chassis is not loaded, failed to check read side") + temperature = None + return temperature def get_nic_voltage(self): """ @@ -2412,8 +3091,30 @@ def get_nic_temperature(self): an Integer, the temperature of the NIC MCU """ - return None + read_side = self.get_read_side() + if read_side == self.TARGET_TOR_A: + curr_offset = 0xFD * 128 + 0x8e + elif read_side == self.TARGET_TOR_B: + curr_offset = 0xFD * 128 + 0x8e + elif read_side == self.TARGET_NIC: + curr_offset = 0xFD * 128 + 0x81 + else: + self.log(self.LOG_ERROR, "get_nic_temperature: unknown read_side") + return -1 + + if self.platform_chassis is not None: + result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if result is None: + self.log(self.LOG_ERROR, "get local temperature read eeprom failed") + return self.EEPROM_ERROR + else: + temperature = result[0] + else: + self.log(self.LOG_ERROR, "platform_chassis is not loaded, failed to check read side") + temperature = None + + return temperature def get_eye_heights(self, target): """ @@ -2433,9 +3134,13 @@ def get_eye_heights(self, target): if target == self.EYE_PRBS_LOOPBACK_TARGET_NIC or target == self.TARGET_NIC: self.log(self.LOG_WARN, "Get eye heights not supported for NIC target ") return None + elif (target != self.EYE_PRBS_LOOPBACK_TARGET_TOR_A) and (target != self.EYE_PRBS_LOOPBACK_TARGET_TOR_B) and \ + (target != self.EYE_PRBS_LOOPBACK_TARGET_LOCAL): + self.log(self.LOG_ERROR, "Invalid target : {}".format(target)) + return self.ERROR_INVALID_TARGET core_ip, lane_mask = self.__util_convert_to_phyinfo_details(target, 0X0F) - print(lane_mask) + cmd_hdr = bytearray(10) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) @@ -2447,21 +3152,22 @@ def get_eye_heights(self, target): cmd_hdr[4] = self.CORE_IP_CLIENT ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_GET_EYE_MARGIN, cmd_hdr, cmd_req_body) - + if ret_val == 0: eye_heights = [[] for i in range(4)] values = [] lrud_list = [] - ind = 0 for i in range(0, 32): + #values.append(struct.unpack("h", cmd_rsp_body[ind:ind+2])) byte_list = [] for j in range(0, 2): byte_list.append(cmd_rsp_body[ind + j]) byte_array = bytearray(byte_list) values.append(struct.unpack("h", byte_array)[0]) + ind += 2 - + if lane_mask == 0x0F: j = 0 l = 0 @@ -2493,10 +3199,9 @@ def get_eye_heights(self, target): return lrud_list else: + self.log(self.LOG_ERROR, "Command execute failed ret_val: {}".format(ret_val)) return None - - def get_ber_info(self, target): """ This API returns the BER (Bit error rate) value for a specfic port. @@ -2512,6 +3217,12 @@ def get_ber_info(self, target): Returns: a list, with BER values of lane 0 lane 1 lane 2 lane 3 with corresponding index """ + + if (target != self.EYE_PRBS_LOOPBACK_TARGET_LOCAL and target != self.EYE_PRBS_LOOPBACK_TARGET_TOR_A and + target != self.EYE_PRBS_LOOPBACK_TARGET_TOR_B and target != self.EYE_PRBS_LOOPBACK_TARGET_NIC): + self.log(self.LOG_ERROR, "Invalid Traget : {}".format(target)) + return self.ERROR_INVALID_TARGET + mode_value = 0xff lane = 0x0f ber_result = [] @@ -2525,16 +3236,13 @@ def get_ber_info(self, target): if ret_val != 0: return False - for i in range(0, 8): + for i in range(0, 8): prbs_error_per_lane = err_cnt_list[i] self.log(self.LOG_DEBUG, "prbs_error_per_lane : {}".format(hex(prbs_error_per_lane))) ber_result.append(prbs_error_per_lane/(25.78125*(math.pow(10, 9)))) return ber_result - - - def get_target_cursor_values(self, lane, target): """ This API returns the cursor equalization parameters for a target(NIC, TOR_A, TOR_B). @@ -2560,9 +3268,13 @@ def get_target_cursor_values(self, lane, target): # validate lane number if lane < 1 or lane > 4: self.log(self.LOG_ERROR, "Invalid lane = {} valid lane is 1 to 4".format(lane)) - return self.ERROR_INVALID_INPUT, None + return self.ERROR_INVALID_INPUT - lane -= 1 # internally lane starts from 0 + if (target != self.TARGET_TOR_A) and (target != self.TARGET_TOR_B) and (target != self.TARGET_NIC) and (target != self.EYE_PRBS_LOOPBACK_TARGET_LOCAL): + self.log(self.LOG_ERROR, "Invalid target : {}".format(target)) + return self.ERROR_INVALID_TARGET + + lane -= 1 # internally lane starts from 0 lane_mask = 1 << lane ret_val = self.__util_convert_to_phyinfo_details(target, lane_mask) @@ -2584,22 +3296,20 @@ def get_target_cursor_values(self, lane, target): if ret_val == 0: txfir = [] ind = 0 - for _ in range(0, 7): - byte_list = [] - for j in range(0, 2): - byte_list.append(cmd_rsp_body[ind + j]) - byte_array = bytearray(byte_list) - txfir.append(struct.unpack("h", byte_array)[0]) + for i in range(0, 7): + txfir.append(struct.unpack("h", cmd_rsp_body[ind:ind+2])[0]) ind += 2 - self.log(self.LOG_DEBUG, "lane {} : pre1 = {}".format(lane,txfir[0])) - self.log(self.LOG_DEBUG, "lane {} : pre2 = {}".format(lane,txfir[1])) - self.log(self.LOG_DEBUG, "lane {} : main = {}".format(lane,txfir[2])) - self.log(self.LOG_DEBUG, "lane {} : post1 = {}".format(lane,txfir[3])) - self.log(self.LOG_DEBUG, "lane {} : post2 = {}".format(lane,txfir[4])) - self.log(self.LOG_DEBUG, "lane {} : post3 = {}".format(lane,txfir[5])) - self.log(self.LOG_DEBUG, "lane {} : taps = {}".format(lane,txfir[6])) + self.log(self.LOG_DEBUG, "lane {} : pre1 = {}".format(lane, txfir[0])) + self.log(self.LOG_DEBUG, "lane {} : pre2 = {}".format(lane, txfir[1])) + self.log(self.LOG_DEBUG, "lane {} : main = {}".format(lane, txfir[2])) + self.log(self.LOG_DEBUG, "lane {} : post1 = {}".format(lane, txfir[3])) + self.log(self.LOG_DEBUG, "lane {} : post2 = {}".format(lane, txfir[4])) + self.log(self.LOG_DEBUG, "lane {} : post3 = {}".format(lane, txfir[5])) + self.log(self.LOG_DEBUG, "lane {} : taps = {}".format(lane, txfir[6])) return txfir + else: + self.log(self.LOG_ERROR, "command execution failed ret_val: {}".format(ret_val)) return None @@ -2628,9 +3338,13 @@ def set_target_cursor_values(self, lane, cursor_values, target): if lane < 1 or lane > 4: self.log(self.LOG_ERROR, "Invalid lane = {} valid lane is 1 to 4".format(lane)) - return self.ERROR_INVALID_INPUT, None + return self.ERROR_INVALID_INPUT + + if (target != self.TARGET_TOR_A) and (target != self.TARGET_TOR_B) and (target != self.TARGET_NIC) and (target != self.EYE_PRBS_LOOPBACK_TARGET_LOCAL): + self.log(self.LOG_ERROR, "Invalid target : {}".format(target)) + return self.ERROR_INVALID_TARGET - lane -= 1 # internally lane starts from 0 + lane -= 1 # internally lane starts from 0 lane_mask = 1 << lane ret_val = self.__util_convert_to_phyinfo_details(target, lane_mask) core_ip = ret_val[0] @@ -2649,13 +3363,14 @@ def set_target_cursor_values(self, lane, cursor_values, target): cmd_req_body1 += struct.pack("LW IPC registers:") - for i in range(0,4): + output_str += "GP_REG_45_int register = {} (cmd_ret: {})\n".format(hex(reg_val), ret_code) + + output_str += "\nCW=>LW IPC registers:\n" + for i in range(0, 4): reg_addr = 0x5200CC20 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) - print("Lane {} = {} (cmd_ret: {})".format(i, hex(reg_val), ret_code)) - - print("LW=>CW IPC registers") - for i in range(0,4): + output_str += "Lane {} = {} (cmd_ret: {})\n".format(i, hex(reg_val), ret_code) + + output_str += "\nLW=>CW IPC registers\n" + for i in range(0, 4): reg_addr = 0x5200CC40 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) - print("Lane {} = {} (cmd_ret: {})".format(i, hex(reg_val), ret_code)) - - print("CW=>BH IPC registers") - for i in range(0,8): + output_str += "Lane {} = {} (cmd_ret: {})\n".format(i, hex(reg_val), ret_code) + + output_str += "\nCW=>BH IPC registers\n" + for i in range(0, 8): reg_addr = 0x5200CC60 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) - print("{} Lane {} = {} (cmd_ret: {})".format( "TORB" if i> 3 else "TORA", i, hex(reg_val), ret_code)) - - print("BH=>CW IPC registers") - for i in range(0,8): + output_str += "{} Lane {} = {} (cmd_ret: {})\n".format("TORB" if i > + 3 else "TORA", i, hex(reg_val), ret_code) + + output_str += "\nBH=>CW IPC registers\n" + for i in range(0, 8): reg_addr = 0x5200CCA0 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) - print("{} Lane {} = {} (cmd_ret: {})".format( "TORB" if i> 3 else "TORA", i, hex(reg_val), ret_code)) - + output_str += "{} Lane {} = {} (cmd_ret: {})\n".format("TORB" if i > + 3 else "TORA", i, hex(reg_val), ret_code) + mode = self.cable_get_mode() - print("pcs receive irq status registers") - print("lanes 0 to 3") - for i in range(0,3): + output_str += "\npcs receive irq status registers\n" + output_str += "lanes 0 to 3\n" + for i in range(0, 3): reg_addr = 0x52007E80 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: print("ERROR: rd_reg_ex {} Failed!".format(hex(reg_addr))) - ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - if(i==0): - print("{} {} = {}".format( "DESK_ALIGN_LOSS:", hex(reg_addr), hex(reg_val))) - elif i==1: - print("{} {} = {}".format( "DSKW0:", hex(reg_addr), hex(reg_val))) - elif i==2: - print("{} {} = {}".format( "DSKW1:", hex(reg_addr), hex(reg_val))) - - for i in range(0,4): + if(i == 0): + output_str += "{} {} = {}\n".format("DESK_ALIGN_LOSS:", hex(reg_addr), hex(reg_val)) + elif i == 1: + output_str += "{} {} = {}\n".format("DSKW0:", hex(reg_addr), hex(reg_val)) + elif i == 2: + output_str += "{} {} = {}\n".format("DSKW1:", hex(reg_addr), hex(reg_val)) + + for i in range(0, 4): reg_addr = 0x52007E8C + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: print("ERROR: rd_reg_ex {} Failed!".format(hex(reg_addr))) - reg_val = reg_val & 0x7FFF#dont clear bit 15 + reg_val = reg_val & 0x7FFF # dont clear bit 15 ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - print("Lane {} {} = {}".format( i, hex(reg_addr), hex(reg_val))) - if(mode == 0 or mode == 2):#for fec modes - print("FEC irq status") - for i in range(0,4): + output_str += "Lane {} {} = {}\n".format(i, hex(reg_addr), hex(reg_val)) + if(mode == 0 or mode == 2): # for fec modes + output_str += "FEC irq status\n" + for i in range(0, 4): reg_addr = 0x52007ED0 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: @@ -5233,15 +5647,15 @@ def debug_dump_registers(self): ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - if(i==0): - print("{} {} = {}".format( "DEC_AM_LOCK_UNLOCK:", hex(reg_addr), hex(reg_val))) - elif i==1: - print("{} {} = {}".format( "DEC_DGBOX:", hex(reg_addr), hex(reg_val))) - elif i==2: - print("{} {} = {}".format( "DEC_IGBOX:", hex(reg_addr), hex(reg_val))) - elif i==3: - print("{} {} = {}".format( "XDEC_ERR:", hex(reg_addr), hex(reg_val))) - for i in range(0,2): + if(i == 0): + output_str += "{} {} = {}\n".format("DEC_AM_LOCK_UNLOCK:", hex(reg_addr), hex(reg_val)) + elif i == 1: + output_str += "{} {} = {}\n".format("DEC_DGBOX:", hex(reg_addr), hex(reg_val)) + elif i == 2: + output_str += "{} {} = {}\n".format("DEC_IGBOX:", hex(reg_addr), hex(reg_val)) + elif i == 3: + output_str += "{} {} = {}\n".format("XDEC_ERR:", hex(reg_addr), hex(reg_val)) + for i in range(0, 2): reg_addr = 0x52007E60 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: @@ -5249,12 +5663,12 @@ def debug_dump_registers(self): ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - if(i==0): - print("{} {} = {}".format( "ENC_GBOX:", hex(reg_addr), hex(reg_val))) - elif i==1: - print("{} {} = {}".format( "ENC_PFIFO:", hex(reg_addr), hex(reg_val))) - print("lanes 4 to 7") - for i in range(0,3): + if(i == 0): + output_str += "{} {} = {}\n".format("ENC_GBOX:", hex(reg_addr), hex(reg_val)) + elif i == 1: + output_str += "{} {} = {}".format("ENC_PFIFO:", hex(reg_addr), hex(reg_val)) + output_str += "lanes 4 to 7\n" + for i in range(0, 3): reg_addr = 0x52017E80 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: @@ -5262,26 +5676,26 @@ def debug_dump_registers(self): ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - if(i==0): - print("{} {} = {}".format( "DESK_ALIGN_LOSS:", hex(reg_addr), hex(reg_val))) - elif i==1: - print("{} {} = {}".format( "DSKW0:", hex(reg_addr), hex(reg_val))) - elif i==2: - print("{} {} = {}".format( "DSKW1:", hex(reg_addr), hex(reg_val))) - - for i in range(0,4): + if(i == 0): + output_str += "{} {} = {}\n".format("DESK_ALIGN_LOSS:", hex(reg_addr), hex(reg_val)) + elif i == 1: + output_str += "{} {} = {}\n".format("DSKW0:", hex(reg_addr), hex(reg_val)) + elif i == 2: + output_str += "{} {} = {}\n".format("DSKW1:", hex(reg_addr), hex(reg_val)) + + for i in range(0, 4): reg_addr = 0x52017E8C + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: print("ERROR: rd_reg_ex {} Failed!".format(hex(reg_addr))) - reg_val = reg_val & 0x7FFF#dont clear bit 15 + reg_val = reg_val & 0x7FFF # dont clear bit 15 ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - print("Lane {} {} = {}".format( i, hex(reg_addr), hex(reg_val))) - if(mode == 0 or mode == 2):#for fec modes - print("FEC irq status") - for i in range(0,4): + output_str += "Lane {} {} = {}\n".format(i, hex(reg_addr), hex(reg_val)) + if(mode == 0 or mode == 2): # for fec modes + output_str += "FEC irq status\n" + for i in range(0, 4): reg_addr = 0x52017ED0 + i * 4 ret_code, reg_val = self.rd_reg_ex(reg_addr, 0x0) if ret_code == -1: @@ -5289,17 +5703,17 @@ def debug_dump_registers(self): ret_code = self.wr_reg_ex(reg_addr, reg_val, 0x0) if ret_code is False: print("ERROR: wr_reg_ex to {} Failed!".format(hex(reg_addr))) - if(i==0): - print("{} {} = {}".format( "DEC_AM_LOCK_UNLOCK:", hex(reg_addr), hex(reg_val))) - elif i==1: - print("{} {} = {}".format( "DEC_DGBOX:", hex(reg_addr), hex(reg_val))) - elif i==2: - print("{} {} = {}".format( "DEC_IGBOX:", hex(reg_addr), hex(reg_val))) - elif i==3: - print("{} {} = {}".format( "XDEC_ERR:", hex(reg_addr), hex(reg_val))) + if(i == 0): + output_str += "{} {} = {}\n".format("DEC_AM_LOCK_UNLOCK:", hex(reg_addr), hex(reg_val)) + elif i == 1: + output_str += "{} {} = {}\n".format("DEC_DGBOX:", hex(reg_addr), hex(reg_val)) + elif i == 2: + output_str += "{} {} = {}\n".format("DEC_IGBOX:", hex(reg_addr), hex(reg_val)) + elif i == 3: + output_str += "{} {} = {}\n".format("XDEC_ERR:", hex(reg_addr), hex(reg_val)) print("\n") - - return True + + return output_str ############################################################################## # @@ -5310,27 +5724,27 @@ def debug_dump_registers(self): def rd_reg_ex(self, reg_addr, lane_map): """ This API specifically used to read the register values - + Args: reg_addr: an hexadecomal,the register address which we intrested to read lane_map: register belong to lane_map to be read - + Returns: - an integer, on sucess returns the register values + an integer, on sucess returns the register values unsigned integer, register value - + """ cmd_hdr = bytearray(5) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) - + cmd_hdr[0] = 5 cmd_hdr[1] = 4 cmd_hdr[2] = 0 cmd_hdr[3] = 0 cmd_hdr[4] = 0 - + if lane_map == 0 or lane_map is None: cmd_req_body[0] = 0 else: @@ -5339,24 +5753,24 @@ def rd_reg_ex(self, reg_addr, lane_map): cmd_req_body[0] = 1 else: cmd_req_body[0] = 0 - + cmd_req_body[1] = (reg_addr & 0xFF) cmd_req_body[2] = ((reg_addr >> 8) & 0xFF) - cmd_req_body[3] = ((reg_addr >>16) & 0xFF) - cmd_req_body[4] = ((reg_addr >>24) & 0xFF) - + cmd_req_body[3] = ((reg_addr >> 16) & 0xFF) + cmd_req_body[4] = ((reg_addr >> 24) & 0xFF) + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_READ_REG, cmd_hdr, cmd_req_body) if ret_val == 0: out = struct.unpack('I', cmd_rsp_body)[0] else: out = None - + return ret_val, out - + def wr_reg_ex(self, reg_addr, reg_value, lane_map): """ This API specifically used to write the register values - + Args: reg_addr: an hexadecomal,the register address where we want to write value @@ -5364,21 +5778,21 @@ def wr_reg_ex(self, reg_addr, reg_value, lane_map): an hexadecomal,the register value which we want to write lane_map: Write register to be performed to given lane_map block - + Returns: - a Boolean, true if the write register succeeded and false if it did not succeed. - + a Boolean, true if the write register succeeded and false if it did not succeed. + """ - + cmd_hdr = bytearray(5) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) - + cmd_hdr[0] = 9 cmd_hdr[1] = 0 cmd_hdr[2] = 0 cmd_hdr[3] = 0 cmd_hdr[4] = 0 - + if lane_map == 0 or lane_map is None: cmd_req_body[0] = 0 else: @@ -5387,19 +5801,19 @@ def wr_reg_ex(self, reg_addr, reg_value, lane_map): cmd_req_body[0] = 1 else: cmd_req_body[0] = 0 - + cmd_req_body[1] = (reg_addr & 0xFF) cmd_req_body[2] = ((reg_addr >> 8) & 0xFF) - cmd_req_body[3] = ((reg_addr >>16) & 0xFF) - cmd_req_body[4] = ((reg_addr >>24) & 0xFF) + cmd_req_body[3] = ((reg_addr >> 16) & 0xFF) + cmd_req_body[4] = ((reg_addr >> 24) & 0xFF) cmd_req_body[5] = (reg_value & 0xFF) cmd_req_body[6] = ((reg_value >> 8) & 0xFF) - cmd_req_body[7] = ((reg_value >>16) & 0xFF) - cmd_req_body[8] = ((reg_value >>24) & 0xFF) - + cmd_req_body[7] = ((reg_value >> 16) & 0xFF) + cmd_req_body[8] = ((reg_value >> 24) & 0xFF) + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_WRITE_REG, cmd_hdr, cmd_req_body) - if cmd_rsp_body is not None: + if cmd_rsp_body is not None: self.log(self.LOG_ERROR, "ERROR: response not expected") return ret_val @@ -5420,50 +5834,50 @@ def util_print_ctx_debug(self): ret_code, tmp_bh_ppm = self.rd_reg_ex(0x5200CCEC, 0x0) if ret_code != 0: return self.EEPROM_ERROR - + start_ppm = c_int16(tmp_start_ppm).value stop_ppm = c_int16(tmp_stop_ppm).value bh_ppm = c_int16(tmp_bh_ppm).value #print("cnt_val {} start_ppm {} stop_ppm {} bh_ppm {}".format(cnt_val, start_ppm, stop_ppm, bh_ppm)) - + if (start_ppm & 0x1000): start_ppm = start_ppm | 0xFFFF0000 - + if (bh_ppm & 0x1000): bh_ppm = bh_ppm | 0xFFFF0000 - + if (stop_ppm & 0x1000): stop_ppm = stop_ppm | 0xFFFF0000 - + start_ppm = (start_ppm * 10)/105 stop_ppm = (stop_ppm * 10)/105 bh_ppm = (bh_ppm * 10)/105 - + ret_code, switch_time = self.rd_reg_ex(0x5200C7D4, 0x0) if ret_code != 0: return self.EEPROM_ERROR - + print("cnt_val = {}".format(cnt_val)) print("start_ppm = {}".format(start_ppm)) print("stop_ppm = {}".format(stop_ppm)) print("bh_ppm = {}".format(bh_ppm)) print("switch_time = {}".format(switch_time)) - + return ret_code def __qsfp_is_valid_page(self, page): - - if ((page == 5 or page == 6 or page == 7 or page == 8 or page == 9 or page == 10 or page == 11 or page == 12) or \ - (page == 0 or page == 1 or page == 2 or page == 4 or page == 3 or page == 0x80 or page == 0x81 or \ + + if ((page == 5 or page == 6 or page == 7 or page == 8 or page == 9 or page == 10 or page == 11 or page == 12) or + (page == 0 or page == 1 or page == 2 or page == 4 or page == 3 or page == 0x80 or page == 0x81 or page == 0x82 or page == 0xB1 or page == 0xFF or page == 0xFE or page == 0xFD)): return True - + return False def cable_print_qsfp_page(self, interface, page_no): """ This API prints QSFP registers for give interface/side and page number - + Args: interface: 0 - TORA @@ -5471,56 +5885,58 @@ def cable_print_qsfp_page(self, interface, page_no): 2 - NIC page_no: an Integer, indicates the page number - + Returns: an bool, True on success False on failure """ + if interface != self.TARGET_NIC and interface != self.TARGET_TOR_A and interface != self.TARGET_TOR_B: + self.log(self.LOG_ERROR, "Invalid target {}".format(interface)) + return False + if self.__qsfp_is_valid_page(page_no) == False: self.log(self.LOG_ERROR, "Error: invalid page no {}".format(hex(page_no))) return False cmd_hdr = bytearray(5) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) - + cmd_hdr[0] = 4 cmd_hdr[1] = 16 cmd_hdr[2] = 0 cmd_hdr[3] = 0 cmd_hdr[4] = 0 - + cmd_req_body[0] = interface cmd_req_body[1] = page_no - + if (page_no): itr = 8 else: itr = 16 - + for i in range(0, itr): if (page_no): start_off = 0x80 + i*16 else: start_off = i*16 - + cmd_req_body[2] = start_off cmd_req_body[3] = 16 ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_DUMP_PAGE, cmd_hdr, cmd_req_body) - + if ret_val == 0: - print('0x{0:0{1}x}'.format((i*16), 2), end = " ") + print('0x{0:0{1}x}'.format((i*16), 2), end=" ") for j in range(0, 16): - print('0x{0:0{1}x}'.format(cmd_rsp_body[j], 2), end = " ") + print('0x{0:0{1}x}'.format(cmd_rsp_body[j], 2), end=" ") print("\n") - + else: self.log(self.LOG_ERROR, "QSFP_DUMP_PAGE failed! interface {} page {}".format(interface, page_no)) return False - - return True - + return True def cable_set_mode(self, cable_mode): """ @@ -5561,7 +5977,6 @@ def cable_set_mode(self, cable_mode): self.log(self.LOG_ERROR, "CABLE MODE input is wrong") return False - cmd_req_body[0] = cable_mode ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_SET_MODE, cmd_hdr, cmd_req_body) @@ -5576,19 +5991,16 @@ def cable_set_mode(self, cable_mode): if cmd_rsp_body is not None: self.log(self.LOG_ERROR, "ERROR: Responce unexpected") - self.log(self.LOG_WARN, "CABLE MODE SET {} NOT SUCCESSFUL".format(mode)) + self.log(self.LOG_ERROR, "CABLE MODE SET {} NOT SUCCESSFUL".format(mode)) return False - - - def cable_get_mode(self): """ This API specifically set the cable mode on the port user provides. - + Args: None - + Returns: integer , specifies one of the cable_mode (0 - CABLE_MODE_100G_FEC, 1 - CABLE_MODE_100G_PCS, 2 - CABLE_MODE_50G_FEC, 3 - CABLE_MODE_50G_PCS) @@ -5596,18 +6008,18 @@ def cable_get_mode(self): """ cmd_hdr = bytearray(5) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) - + cmd_hdr[0] = 0 cmd_hdr[1] = 1 cmd_hdr[2] = 0 cmd_hdr[3] = 0 cmd_hdr[4] = 0 - + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_GET_MODE, cmd_hdr, cmd_req_body) - + if self.__validate_read_data(cmd_rsp_body, 1, "get cable mode") == self.EEPROM_READ_DATA_INVALID: return self.EEPROM_ERROR - + if ret_val == 0: regval_read = struct.unpack(" is documented below - + Byte offset bits Name Description < > 0 squelch 0x01 enable squelch 0x00 enable un-squelch @@ -5887,35 +6313,41 @@ def cable_set_squelch(self, target, lane_map, enable, direction): a Boolean, True on sucess False on api fail """ - - + + if (target != self.TARGET_TOR_A) and (target != self.TARGET_TOR_B) and (target != self.TARGET_NIC) and (target != self.EYE_PRBS_LOOPBACK_TARGET_LOCAL): + self.log(self.LOG_ERROR, "Invalid target : {}".format(target)) + return self.ERROR_INVALID_TARGET + elif lane_map & 0xF == 0: + self.log(self.LOG_ERROR, "Invalid Lane map {}".format(lane_map)) + return self.ERROR_INVALID_INPUT + ret_val = self.__util_convert_to_phyinfo_details(target, lane_map) core_ip = ret_val[0] lane_mask = ret_val[1] - + cmd_hdr = bytearray(5) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) - + cmd_hdr[0] = 4 cmd_hdr[1] = 0 cmd_hdr[2] = lane_mask if (core_ip == self.CORE_IP_CLIENT) else 0 cmd_hdr[3] = lane_mask if (core_ip == self.CORE_IP_LW) else 0 cmd_hdr[4] = core_ip - + cmd_req_body[0] = enable cmd_req_body[1] = direction - + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_SET_SQUELCH, cmd_hdr, cmd_req_body) if ret_val == 0 and cmd_rsp_body is None: return True else: + self.log(self.LOG_ERROR, "Command execution failed. ret_val: {}".format(ret_val)) return False def cable_get_squelch(self): - """ This API specifically returns the Rx squelch and Tx squelch status on TOR and NIC - + Args: physical_port: an Integer, the actual physical port connected to a Y cable @@ -5923,33 +6355,32 @@ def cable_get_squelch(self): an integer, 0 and cmd_rsp_body contains squelch status on success -1 on api fail """ - + if self.platform_chassis is not None: curr_offset = self.QSFP_SQL_STATUS result = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) if result is None: - self.log(self.LOG_ERROR,"get_squelch read eeprom failed") + self.log(self.LOG_ERROR, "get_squelch read eeprom failed") return self.EEPROM_ERROR else: self.log(self.LOG_ERROR, "platform_chassis is not loaded") return self.ERROR_PLATFORM_NOT_LOADED - - + cmd_hdr = bytearray(5) cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) - + cmd_hdr[0] = 0 cmd_hdr[1] = 4 cmd_hdr[2] = 0 cmd_hdr[3] = 0 cmd_hdr[4] = self.CORE_IP_ALL - + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_GET_SQUELCH, cmd_hdr, cmd_req_body) if ret_val == 0: lane = 0 for _ in range(0, 8): - if cmd_rsp_body[0] & (1<> 8) & 0xFF + cmd_req_body[2] = (address >> 16) & 0xFF + cmd_req_body[3] = (address >> 24) & 0xFF + cmd_req_body[4] = 4 + + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_READ_MCU_RAM, cmd_hdr, cmd_req_body) + if ret_val == 0 and cmd_rsp_body is not None: + return cmd_rsp_body + else: + self.log(self.LOG_ERROR, "cable_read_nic_mcu_ram failed ") + + return None + + def cable_clear_nic_mcu_dump(self): + """ + utility function reads RAM address and returns value + + """ + + cmd_hdr = bytearray(5) + cmd_req_body = bytearray(self.MAX_REQ_PARAM_LEN) + + cmd_hdr[0] = 0 + cmd_hdr[1] = 0 + cmd_hdr[2] = 0 + cmd_hdr[3] = 0 + cmd_hdr[4] = self.CORE_IP_CENTRAL + + ret_val, cmd_rsp_body = self.__cable_cmd_execute(self.CABLE_CMD_ID_CLEAR_CRASH, cmd_hdr, cmd_req_body) + if ret_val == 0: + self.log(self.LOG_ERROR, "nic_mcu_crash cleared ") + if cmd_rsp_body is not None: + self.log(self.LOG_DEBUG, "CABLE_CMD_ID_CLEAR_CRASH returned value?") + else: + self.log(self.LOG_ERROR, "cable_clear_nic_mcu_crash failed ") + + return None + + def read_tor_ram(self, address): + """ + Utility function to read SRAM address + """ + addr_array = bytearray(4) + buf = bytearray(4) + + addr_array[0] = address & 0xFF + addr_array[1] = (address >> 8) & 0xFF + addr_array[2] = (address >> 16) & 0xFF + addr_array[3] = (address >> 24) & 0xFF + + # write the ram address to read + curr_offset = (0xFD * 128) + 0xF8 + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 4, addr_array) + if result is False: + return self.ERROR_WR_EEPROM_FAILED + + # write count + curr_offset = (0xFD * 128) + 0xF6 + buf[0] = 4 + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buf) + if result is False: + return self.ERROR_WR_EEPROM_FAILED + + curr_offset = (0xFD * 128) + 0xF6 + for _ in range(0, 3000): + status = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if status is None: + self.log(self.LOG_ERROR, "read_tor_ram: read_eeprom failed") + return self.EEPROM_ERROR + + if status[0] == 0: + break + + curr_offset = (0xFD * 128) + 0xF7 + status = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if status is None: + self.log(self.LOG_ERROR, "read_tor_ram: read_eeprom failed") + return self.EEPROM_ERROR + + if status[0] == 0: + curr_offset = (0xFD * 128) + 0xFC + val_arr = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 4) + if val_arr is None: + return self.EEPROM_ERROR + else: + return -1 + + return val_arr + + def cable_clear_tor_mcu_dump(self): + """ + Utility function to cear TOR crash info + """ + # clear TOR crash + buf = bytearray(1) + buf[0] = 1 + curr_offset = ((0xFD * 128) + 0xF2) + result = self.platform_chassis.get_sfp(self.port).write_eeprom(curr_offset, 1, buf) + if result is False: + return self.ERROR_WR_EEPROM_FAILED + + curr_offset = ((0xFD * 128) + 0xF2) + for _ in range(0, 3000): + status = self.platform_chassis.get_sfp(self.port).read_eeprom(curr_offset, 1) + if status is None: + self.log(self.LOG_ERROR, "clear_tor_crash_info: read_eeprom failed") + return self.EEPROM_ERROR + if status[0] == 0: + break + + def cable_print_nic_mcu_dump(self): + """ + Dump NIC crash info + """ + buff = bytearray() + itr_count = 2048 + address = 0x20030000 + no_crash = 1 + exp_val = ram2_exp_s() + + self.log(self.LOG_DEBUG, "Reading NIC dump data...") + for i in range(0, itr_count): + tval = self.cable_read_nic_mcu_ram(address) + # if tval is None or tval == -1: + if (tval is None) or (tval == self.EEPROM_ERROR): + self.log(self.LOG_ERROR, "cable_print_nic_mcu_dump: read_tor_ram failed") + break + + if i == 0: + value = struct.unpack("