diff --git a/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c index be28c81dd..df55f1f66 100644 --- a/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c @@ -28,6 +28,7 @@ #include #include "x86_64_accton_as7535_28xb_int.h" #include "x86_64_accton_as7535_28xb_log.h" +#include #define VALIDATE(_port) \ do { \ @@ -83,6 +84,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -135,7 +138,7 @@ onlp_sfpi_is_present(int port) VALIDATE(port); if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -153,7 +156,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) fp = fopen(MODULE_PRESENT_ALL_ATTR, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD"); + syslog(LOG_ERR, "Unable to open the module_present_all device file of CPLD"); return ONLP_STATUS_E_INTERNAL; } @@ -162,7 +165,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) if(count != AIM_ARRAYSIZE(bytes)) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD"); + syslog(LOG_ERR, "Unable to read all fields the module_present_all device file of CPLD"); return ONLP_STATUS_E_INTERNAL; } @@ -198,7 +201,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fp = fopen(MODULE_RXLOS_ALL_ATTR, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_rx_los_all device file of CPLD"); + syslog(LOG_ERR, "Unable to open the module_rx_los_all device file of CPLD"); return ONLP_STATUS_E_INTERNAL; } @@ -206,7 +209,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fclose(fp); if(count != AIM_ARRAYSIZE(bytes)) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields from the module_rx_los_all device file of CPLD"); + syslog(LOG_ERR, "Unable to read all fields from the module_rx_los_all device file of CPLD"); return ONLP_STATUS_E_INTERNAL; } @@ -243,12 +246,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) memset(data, 0, 256); if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -265,20 +268,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -318,6 +321,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; int mbit_identifier; int mbit_value; @@ -332,40 +336,43 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if (port >= 0 && port <= 3) { if ((identifier = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER)) < 0 ) { - AIM_LOG_ERROR("Failed to read Identifier, unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Identifier, unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (identifier == QSFP_DD_IDENTIFIER) { - if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { - AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; } if ((support_ctrls = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0 ) { - AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); rv = support_ctrls; goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to set Bank 0, unable to write tx_disable status to port(%d)", port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0 ) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", QSFP_DD_PAGE_LANE_CTRL, port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX, (value & 0xff))) < 0) { - AIM_LOG_ERROR("Failed to write tx_disable value(0x%02x) to Lane Control register on port(%d)\r\n", value, port); + syslog(LOG_ERR, "Failed to write tx_disable value(0x%02x) to Lane Control register on port(%d)", value, port); goto restore; } } else { - AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -373,10 +380,10 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) restore: if ((onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO)) < 0) { - AIM_LOG_ERROR("Failed to restore Page Select to Admin Info on port(%d)!\r\n", port); + syslog(LOG_ERR, "Failed to restore Page Select to Admin Info on port(%d)!", port); } if (rv < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); return (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } @@ -385,14 +392,14 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } else { /* QSFP */ /* txdis valid bit(bit0-bit3), xxxx 1111 */ if (onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, (value & 0xf)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; } } else { if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -405,7 +412,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_RESET_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -414,7 +421,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_LPMODE_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write lp mode status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write lp mode status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } else { @@ -432,7 +439,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (value == 0x0) { mbit_value = RESET_RATE_SELECT_BIT(mbit_value,3); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, MULTIRATE_OFFSET, mbit_value) < 0){ - AIM_LOG_ERROR("Unable to write multirate status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write multirate status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -440,7 +447,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) else if(value == 0x1) { mbit_value = SET_RATE_SELECT_BIT(mbit_value,3); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, MULTIRATE_OFFSET, mbit_value) < 0){ - AIM_LOG_ERROR("Unable to write multirate status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write multirate status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -448,12 +455,11 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) return ONLP_STATUS_E_INTERNAL; } else { - AIM_LOG_ERROR("Unable to support multirate for the port(%d)\r\n", port); return ONLP_STATUS_E_UNSUPPORTED; } } else { - AIM_LOG_ERROR("Unable to write multirate status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write multirate status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } @@ -469,6 +475,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; int multirate = 0; int mbit_identifier; @@ -479,7 +487,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -490,7 +498,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -505,41 +513,63 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (present == 1) { if (port >= 0 && port <= 3) { if ((identifier = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER)) < 0) { - AIM_LOG_ERROR("Failed to read Identifier, unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Identifier, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (identifier == QSFP_DD_IDENTIFIER) { - if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } + if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); + goto restore; + } + if ((support_ctrls = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); + rv = support_ctrls; goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { + syslog(LOG_ERR, "Failed to set Bank 0, unable to read tx_disable status from port(%d)", port); + goto restore; + } + if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + syslog(LOG_ERR, "Failed to read TX_DISABLE value from Lane Control register on port(%d)", port); + rv = tx_dis; + goto restore; + } + } else { + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } restore: if ((onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO)) < 0) { - AIM_LOG_ERROR("Failed to restore Page Select to Admin Info on port(%d)!\r\n", port); + syslog(LOG_ERR, "Failed to restore Page Select to Admin Info on port(%d)!", port); } if (rv < 0) { - AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - return ONLP_STATUS_E_INTERNAL; + syslog(LOG_ERR, "Unable to get tx_disable status from port(%d)", port); + return (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } *value = (tx_dis & 0xff); return ONLP_STATUS_OK; } else { /* QSFP */ if ((tx_dis = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } *value = (tx_dis & 0xf); @@ -547,7 +577,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } } else { /* SFP */ if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -560,7 +590,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_RESET_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -570,7 +600,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_LPMODE_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read lp mode status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read lp mode status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -593,7 +623,6 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } } else { - AIM_LOG_ERROR("Unable to read multirate status from port(%d)\r\n", port); return ONLP_STATUS_E_UNSUPPORTED; } } diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/sfpi.c index 3062f05ad..932b8e670 100644 --- a/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7926-40xfb/onlp/builds/x86_64_accton_as7926_40xfb/module/src/sfpi.c @@ -27,6 +27,7 @@ #include #include #include "platform_lib.h" +#include #define NUM_OF_SFP_PORT 55 @@ -99,6 +100,8 @@ static const int port_bus_index[NUM_OF_SFP_PORT] = { #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_LPMODE 0x10 @@ -162,7 +165,7 @@ onlp_sfpi_is_present(int port) } if (onlp_file_read_int(&present, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -179,7 +182,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) if ((i >= 53) && (i <= 54)) { if (onlp_file_read_int(&val, MODULE_RXLOS_FORMAT, 12, 62, i+1) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", i); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", i); } if (val) @@ -206,17 +209,17 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) */ int size = 0; if (port < 0 || port >= NUM_OF_SFP_PORT) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (onlp_file_read(data, 256, &size, PORT_FORMAT, PORT_BUS_INDEX(port), "eeprom") != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Invalid file size(%d)\r\n", size); + syslog(LOG_ERR, "Invalid file size(%d)", size); return ONLP_STATUS_E_INTERNAL; } @@ -260,6 +263,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int present = 0; int lpmode_value = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -272,7 +276,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { //SFP if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -282,36 +286,44 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) else{ identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /*QSFP DD*/ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else { eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if(eeprom_control < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT){ if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -319,11 +331,10 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) rv = ONLP_STATUS_OK; } } else { - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -333,7 +344,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) value = value&0xf; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) < 0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -369,7 +380,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to reset port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to reset port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -385,14 +396,14 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /*QSFP DD*/ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -402,7 +413,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) else lpmode_value &= ~QSFP_DD_LPMODE; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW, lpmode_value) < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -414,7 +425,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -426,7 +437,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE, lpmode_value)< 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -458,6 +469,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int present = 0; int lpmode_value = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE_PORT(port); @@ -467,7 +480,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -488,7 +501,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if(present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -498,35 +511,54 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) {/* QSFP DD */ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write bank to eeprom fail\r\n", - port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0){ + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1)) < 0){ + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } - else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0 ){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + else if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0){ + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", + QSFP_DD_PAGE_LANE_CTRL, port); + rv = ONLP_STATUS_E_INTERNAL; + } else { tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); if(tx_dis < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else{ - *value = tx_dis; + *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -534,7 +566,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { /* QSFP 28 or QSFP+ */ tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); if(tx_dis < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -571,7 +603,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -586,7 +618,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (present == 1) { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -594,7 +626,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) /* lpmode valid bit(bit4):Low power requset sw */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): set LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): set LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -606,7 +638,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): set LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): set LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c index 23eed5eb1..edef18dbe 100644 --- a/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c @@ -27,6 +27,7 @@ #include #include #include "platform_lib.h" +#include #define NUM_OF_SFP_PORT 30 @@ -44,6 +45,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -140,7 +143,7 @@ onlp_sfpi_is_present(int port) } if (onlp_file_read_int(&present, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -167,7 +170,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) } if ((i >= 26) && (i <= 29)) { if (onlp_file_read_int(&val, path, i+1) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", i); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", i); } if (val) @@ -197,12 +200,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) VALIDATE(port); if (onlp_file_read(data, 256, &size, PORT_FORMAT, PORT_BUS_INDEX(port), "eeprom") != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Invalid file size(%d)\r\n", size); + syslog(LOG_ERR, "Invalid file size(%d)", size); return ONLP_STATUS_E_INTERNAL; } @@ -219,20 +222,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -274,6 +277,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; VALIDATE(port); @@ -286,40 +290,43 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if(port >= 0 && port <= 25) { if ((identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER)) < 0) { - AIM_LOG_ERROR("Failed to read Identifier, unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Identifier, unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (identifier == QSFP_DD_IDENTIFIER) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { - AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; } if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { - AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); rv = support_ctrls; goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to set Bank 0, unable to write tx_disable status to port(%d)", port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", QSFP_DD_PAGE_LANE_CTRL, port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX, (value & 0xff))) < 0) { - AIM_LOG_ERROR("Failed to write tx_disable value(0x%02x) to Lane Control register on port(%d)\r\n", value, port); + syslog(LOG_ERR, "Failed to write tx_disable value(0x%02x) to Lane Control register on port(%d)", value, port); goto restore; } } else { - AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -327,11 +334,11 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) restore: if ((onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO)) < 0) { - AIM_LOG_ERROR("Failed to restore Page Select to Admin Info on port(%d)!\r\n", port); + syslog(LOG_ERR, "Failed to restore Page Select to Admin Info on port(%d)!", port); } if (rv < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -339,7 +346,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } else { /* QSFP */ /* txdis valid bit(bit0-bit3), xxxx 1111 */ if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, (value & 0xf)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -348,7 +355,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } else { path = MODULE_TXDISABLE_MAIN_BOARD_CPLD2_FORMAT; if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to set tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -373,7 +380,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) break; } if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -393,7 +400,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) break; } if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write lpmode status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write lpmode status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -414,6 +421,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE(port); @@ -434,7 +443,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -449,42 +458,64 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (present == 1) { if (port >= 0 && port <= 25) { if ((identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER)) < 0) { - AIM_LOG_ERROR("Failed to read Identifier, unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Identifier, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (identifier == QSFP_DD_IDENTIFIER) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); + rv = support_ctrls; + goto restore; + } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { + syslog(LOG_ERR, "Failed to set Bank 0, unable to read tx_disable status from port(%d)", port); + goto restore; + } + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + syslog(LOG_ERR, "Failed to read TX_DISABLE value from Lane Control register on port(%d)", port); + rv = tx_dis; + goto restore; + } + } else { + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } restore: if ((onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO)) < 0) { - AIM_LOG_ERROR("Failed to restore Page Select to Admin Info on port(%d)!\r\n", port); + syslog(LOG_ERR, "Failed to restore Page Select to Admin Info on port(%d)!", port); } if (rv < 0) { - AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - rv = ONLP_STATUS_E_INTERNAL; + syslog(LOG_ERR, "Unable to get tx_disable status from port(%d)", port); + rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } else { /* QSFP */ if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xf); @@ -494,7 +525,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } else { /* SFP */ path = MODULE_TXDISABLE_MAIN_BOARD_CPLD2_FORMAT; if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -519,7 +550,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -538,7 +569,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read lpmode status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read lpmode status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; diff --git a/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c index 595649b6f..b57a923a0 100644 --- a/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c @@ -27,6 +27,7 @@ #include #include #include "platform_lib.h" +#include #define NUM_OF_SFP_PORT 74 @@ -44,6 +45,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -150,7 +153,7 @@ onlp_sfpi_is_present(int port) } if (onlp_file_read_int(&present, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -180,7 +183,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) } if ((i >= 10) && (i <= 73)) { if (onlp_file_read_int(&val, path, i+1) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", i); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", i); } if (val) @@ -210,12 +213,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) VALIDATE(port); if (onlp_file_read(data, 256, &size, PORT_FORMAT, PORT_BUS_INDEX(port), "eeprom") != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Invalid file size(%d)\r\n", size); + syslog(LOG_ERR, "Invalid file size(%d)", size); return ONLP_STATUS_E_INTERNAL; } @@ -232,20 +235,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -287,6 +290,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; VALIDATE(port); @@ -299,40 +303,43 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if(port >= 0 && port <= 9) { if ((identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER)) < 0) { - AIM_LOG_ERROR("Failed to read Identifier, unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Identifier, unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (identifier == QSFP_DD_IDENTIFIER) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { - AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; } if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { - AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); rv = support_ctrls; goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to set Bank 0, unable to write tx_disable status to port(%d)", port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", QSFP_DD_PAGE_LANE_CTRL, port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX, (value & 0xff))) < 0) { - AIM_LOG_ERROR("Failed to write tx_disable value(0x%02x) to Lane Control register on port(%d)\r\n", value, port); + syslog(LOG_ERR, "Failed to write tx_disable value(0x%02x) to Lane Control register on port(%d)", value, port); goto restore; } } else { - AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -340,10 +347,10 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) restore: if ((onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO)) < 0) { - AIM_LOG_ERROR("Failed to restore Page Select to Admin Info on port(%d)!\r\n", port); + syslog(LOG_ERR, "Failed to restore Page Select to Admin Info on port(%d)!", port); } if (rv < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -351,7 +358,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } else { /* QSFP */ /* txdis valid bit(bit0-bit3), xxxx 1111 */ if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, (value & 0xf)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -372,7 +379,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) break; } if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to set tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -400,7 +407,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) break; } if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -417,7 +424,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) break; } if (onlp_file_write_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write LP mode status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write LP mode status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -437,6 +444,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE(port); @@ -460,7 +469,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -475,42 +484,64 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (present == 1) { if (port >= 0 && port <= 9) { if ((identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER)) < 0) { - AIM_LOG_ERROR("Failed to read Identifier, unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Failed to read Identifier, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (identifier == QSFP_DD_IDENTIFIER) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); + rv = support_ctrls; + goto restore; + } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { + syslog(LOG_ERR, "Failed to set Bank 0, unable to read tx_disable status from port(%d)", port); + goto restore; + } + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + syslog(LOG_ERR, "Failed to read TX_DISABLE value from Lane Control register on port(%d)", port); + rv = tx_dis; + goto restore; + } + } else { + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } restore: if ((onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO)) < 0) { - AIM_LOG_ERROR("Failed to restore Page Select to Admin Info on port(%d)!\r\n", port); + syslog(LOG_ERR, "Failed to restore Page Select to Admin Info on port(%d)!", port); } if (rv < 0) { - AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - rv = ONLP_STATUS_E_INTERNAL; + syslog(LOG_ERR, "Unable to get tx_disable status from port(%d)", port); + rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } else { /* QSFP */ if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xf); @@ -532,7 +563,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { rv = ONLP_STATUS_OK; @@ -560,7 +591,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; @@ -578,7 +609,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (onlp_file_read_int(value, path, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read LP mode status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read LP mode status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } break; diff --git a/packages/platforms/accton/x86-64/as9716_32d/onlp/builds/x86_64_accton_as9716_32d/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9716_32d/onlp/builds/x86_64_accton_as9716_32d/module/src/sfpi.c index e1c0736cf..82ebd152c 100755 --- a/packages/platforms/accton/x86-64/as9716_32d/onlp/builds/x86_64_accton_as9716_32d/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9716_32d/onlp/builds/x86_64_accton_as9716_32d/module/src/sfpi.c @@ -28,6 +28,7 @@ #include #include "x86_64_accton_as9716_32d_int.h" #include "x86_64_accton_as9716_32d_log.h" +#include #define SFP_PORT_MIN 32 #define SFP_PORT_MAX 33 @@ -85,6 +86,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_LPMODE 0x10 @@ -157,7 +160,7 @@ onlp_sfpi_is_present(int port) } if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -209,12 +212,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) memset(data, 0, 256); if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, onlp_sfpi_map_bus_index(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -230,20 +233,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, onlp_sfpi_map_bus_index(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -287,6 +290,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int present = 0; int lpmode_value = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -308,7 +312,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { //SFP if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -319,36 +323,44 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /*QSFP DD*/ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else { eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if(eeprom_control < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT){ if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -356,11 +368,10 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) rv = ONLP_STATUS_OK; } } else { - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -370,7 +381,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) value = value&0xf; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) < 0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -389,7 +400,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_RESET_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -404,7 +415,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -412,7 +423,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -422,7 +433,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) else lpmode_value &= ~QSFP_DD_LPMODE; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW, lpmode_value) < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -436,7 +447,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -448,7 +459,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE, lpmode_value)< 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -482,6 +493,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int present = 0; int lpmode_value = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE_PORT(port); @@ -501,7 +514,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -514,7 +527,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -531,7 +544,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if(present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -541,35 +554,54 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) {/* QSFP DD */ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write bank to eeprom fail\r\n", - port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0){ + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1)) < 0){ + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } - else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0 ){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + else if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0){ + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", + QSFP_DD_PAGE_LANE_CTRL, port); + rv = ONLP_STATUS_E_INTERNAL; + } else { tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); if(tx_dis < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else{ - *value = tx_dis; + *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -577,7 +609,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { /* QSFP 28 or QSFP+ */ tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); if(tx_dis < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -598,7 +630,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_RESET_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to get reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to get reset status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -614,7 +646,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (present == 1) { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -622,7 +654,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) /* lpmode valid bit(bit4):Low power requset sw */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -634,7 +666,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c index c5e52a31b..286d89b3d 100644 --- a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c @@ -383,10 +383,6 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (status_byte & QSFP_DD_FLAT_MEM) { return ONLP_STATUS_E_UNSUPPORTED; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - syslog(LOG_ERR, "Failed to set Bank 0, unable to write tx_disable status to port(%d)", port); - return ONLP_STATUS_E_INTERNAL; - } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; @@ -398,7 +394,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - syslog(LOG_ERR, "Failed to set Bank 0 on port(%d)", port); + syslog(LOG_ERR, "Failed to set Bank 0, unable to write tx_disable status to port(%d)", port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { @@ -554,10 +550,6 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (status_byte & QSFP_DD_FLAT_MEM) { return ONLP_STATUS_E_UNSUPPORTED; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - syslog(LOG_ERR, "Failed to set Bank 0, unable to read tx_disable status from port(%d)", port); - return ONLP_STATUS_E_INTERNAL; - } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); goto restore; @@ -569,7 +561,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - syslog(LOG_ERR, "Failed to set Bank 0 on port(%d)", port); + syslog(LOG_ERR, "Failed to set Bank 0, unable to read tx_disable status from port(%d)", port); goto restore; } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { diff --git a/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c index ff7fb62d6..833b285cf 100644 --- a/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c @@ -29,6 +29,7 @@ #include "x86_64_accton_as9736_64d_int.h" #include "x86_64_accton_as9736_64d_log.h" #include "platform_lib.h" +#include #define SFP_PORT_MIN 64 #define SFP_PORT_MAX 65 @@ -94,6 +95,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 @@ -155,7 +158,7 @@ int onlp_sfpi_is_present(int port) VALIDATE_PORT(port); if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n" + syslog(LOG_ERR, "Unable to read present status from port(%d)" , port); return ONLP_STATUS_E_INTERNAL; } @@ -189,7 +192,7 @@ int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fp = fopen(MODULE_RXLOS_ALL_ATTR, "r"); if (fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_rx_los_all device file."); + syslog(LOG_ERR, "Unable to open the module_rx_los_all device file."); return ONLP_STATUS_E_INTERNAL; } @@ -199,7 +202,7 @@ int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fclose(fp); if (count != 9) { /* Likely a read timeout. */ - AIM_LOG_ERROR("Unable to read all fields from the module_rx_los_all device file."); + syslog(LOG_ERR, "Unable to read all fields from the module_rx_los_all device file."); return ONLP_STATUS_E_INTERNAL; } @@ -232,7 +235,7 @@ int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) } else { if (onlp_file_read_int(&rx_loss, MODULE_RXLOS_FORMAT, (i+1)) < 0) { - AIM_LOG_ERROR("Unable to read rxloss status from port(%d)\r\n" + syslog(LOG_ERR, "Unable to read rxloss status from port(%d)" , i+1); return ONLP_STATUS_E_INTERNAL; } @@ -259,20 +262,20 @@ int onlp_sfpi_eeprom_read(int port, uint8_t data[256]) if (port <= 31) { if (onlp_file_read(data, 256, &size, UDB_PORT_EEPROM_FORMAT, port) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } else { if (onlp_file_read(data, 256, &size, LDB_PORT_EEPROM_FORMAT, port-32) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -289,14 +292,14 @@ int onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, onlp_sfpi_map_bus_index(port)); fp = fopen(file, "r"); if (fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -304,7 +307,7 @@ int onlp_sfpi_dom_read(int port, uint8_t data[256]) int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -419,6 +422,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int rv = ONLP_STATUS_E_INTERNAL; int present = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -431,7 +435,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { //SFP if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, (port + 1)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -442,36 +446,44 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) else { //QSFP identifier = onlp_sfpi_eeprom_readb(port, QSFP_EEPROM_OFFSET_IDENTIFIER); if (identifier < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_eeprom_readb(port, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else { eeprom_control = onlp_sfpi_eeprom_readb(port, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if (eeprom_control < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -479,11 +491,10 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) rv = ONLP_STATUS_OK; } } else { - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; } if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -493,7 +504,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) value = value & 0xf; if (onlp_sfpi_eeprom_writeb(port, QSFP_EEPROM_OFFSET_TXDIS, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -513,7 +524,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (onlp_file_write_int(value, MODULE_RESET_FORMAT, (port + 1)) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -527,7 +538,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (onlp_file_write_int(value, MODULE_LPMODE_FORMAT, (port + 1)) < 0) { - AIM_LOG_ERROR("Unable to write LP mode status to port(%d)\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -549,6 +560,8 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int rv = ONLP_STATUS_E_INTERNAL; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE_PORT(port); @@ -558,7 +571,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -571,7 +584,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -587,7 +600,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -598,35 +611,54 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { identifier = onlp_sfpi_eeprom_readb(port, QSFP_EEPROM_OFFSET_IDENTIFIER); if (identifier < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write bank to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_eeprom_readb(port, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + syslog(LOG_ERR, "Failed to switch to Advertising Page on port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if ((support_ctrls = onlp_sfpi_eeprom_readb(port, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1)) < 0) { + syslog(LOG_ERR, "Failed to read Support Control on port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", - port); + syslog(LOG_ERR, "Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)", + QSFP_DD_PAGE_LANE_CTRL, port); rv = ONLP_STATUS_E_INTERNAL; } else { tx_dis = onlp_sfpi_eeprom_readb(port, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); if (tx_dis < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else { - *value = tx_dis; + *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -634,7 +666,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { /* QSFP 28 or QSFP+ */ tx_dis = onlp_sfpi_eeprom_readb(port, QSFP_EEPROM_OFFSET_TXDIS); if (tx_dis < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -655,7 +687,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (onlp_file_read_int(value, MODULE_RESET_FORMAT, (port + 1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -669,7 +701,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (onlp_file_read_int(value, MODULE_LPMODE_FORMAT, (port + 1)) < 0) { - AIM_LOG_ERROR("Unable to read LP mode status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c index 1263413b5..b93a824ed 100644 --- a/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c @@ -28,6 +28,7 @@ #include #include "x86_64_accton_as9737_32db_int.h" #include "x86_64_accton_as9737_32db_log.h" +#include #define SFP_PORT_MIN 33 #define SFP_PORT_MAX 34 @@ -93,6 +94,8 @@ static const int port_bus_index[NUM_OF_SFP_PORT] = { #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 /*QSFP Specific*/ @@ -149,7 +152,7 @@ onlp_sfpi_is_present(int port) } if (onlp_file_read_int(&present, path, port) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; @@ -172,12 +175,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) if(onlp_file_read(data, 256, &size, MODULE_EEPROM_FORMAT, PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -194,14 +197,14 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, MODULE_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -209,7 +212,7 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -252,6 +255,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int present = 0; int identifier = 0; int eeprom_control; + int status_byte = 0; VALIDATE_PORT(port); @@ -264,7 +268,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -273,23 +277,31 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); + return ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if(eeprom_control < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } @@ -298,46 +310,44 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT){ if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } } else { if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); return ONLP_STATUS_E_UNSUPPORTED; } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } } @@ -345,7 +355,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) /* txdis valid bit(bit0-bit3), xxxx 1111 */ value = value&0xf; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -366,7 +376,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) : MODULE_RESET_CPLD3_FORMAT; if (onlp_file_write_int(value, path, port) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -380,7 +390,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) : MODULE_LPMODE_CPLD3_FORMAT; if (onlp_file_write_int(value, path, port) < 0) { - AIM_LOG_ERROR("Unable to write LP mode to port(%d)\r\n", + syslog(LOG_ERR, "Unable to write LP mode to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -401,6 +411,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int present = 0; int identifier = 0; int tx_disable; + int status_byte = 0; + int support_ctrls = 0; VALIDATE_PORT(port); @@ -409,7 +421,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) *value = 0; if (port >= 33 && port <= 34) { if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -422,7 +434,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -438,7 +450,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if(present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -446,21 +458,59 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read identifier from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disabled status from port(%d)", port); + return ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write bank to eeprom fail\r\n", + /* Switch to Advertising page to check TX_DISABLE support */ + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if (support_ctrls < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read support control from eeprom fail", + port); + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + } + return ONLP_STATUS_E_INTERNAL; + } + + if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + } + return ONLP_STATUS_E_UNSUPPORTED; + } - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write bank to eeprom fail", + port); + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + } + return ONLP_STATUS_E_INTERNAL; + } + + /* Switch to Lane Control page to read TX disable */ + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -468,16 +518,18 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); if(tx_disable < 0){ if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); } - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } *value = tx_disable; + + /* Restore page */ if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -485,7 +537,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { /* QSFP 28 or QSFP+ */ tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); if(tx_disable < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -506,7 +558,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) : MODULE_RESET_CPLD3_FORMAT; if (onlp_file_read_int(value, path, port) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -520,7 +572,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) : MODULE_LPMODE_CPLD3_FORMAT; if (onlp_file_read_int(value, path, port) < 0) { - AIM_LOG_ERROR("Unable to read LP mode status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/as9817-64-nb/src/x86_64_accton_as9817_64_nb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9817-64-nb/src/x86_64_accton_as9817_64_nb/module/src/sfpi.c index 9da75efe1..bd4b0df6b 100644 --- a/packages/platforms/accton/x86-64/as9817-64-nb/src/x86_64_accton_as9817_64_nb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9817-64-nb/src/x86_64_accton_as9817_64_nb/module/src/sfpi.c @@ -28,6 +28,7 @@ #include #include "x86_64_accton_as9817_64_nb_int.h" #include "x86_64_accton_as9817_64_nb_log.h" +#include #define SFP_PORT_MIN 65 #define SFP_PORT_MAX 66 @@ -81,6 +82,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 /* OSFP IDENTIFIER Specific*/ @@ -138,7 +141,7 @@ onlp_sfpi_is_present(int port) int present; if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -158,12 +161,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) memset(data, 0, 256); if(onlp_file_read(data, 256, &size, MODULE_EEPROM_FORMAT, PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -179,20 +182,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, MODULE_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -232,6 +235,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { int present = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -243,63 +247,70 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { //SFP if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } else { //QSFP identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } else { switch(identifier) { case QSFP_DD_IDENTIFIER: case OSFP_IDENTIFIER: { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if(eeprom_control < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT){ - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } } else { if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); return ONLP_STATUS_E_UNSUPPORTED; } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } break; @@ -308,7 +319,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) case QSFP_PLUS_IDENTIFIER:{ value = value&0xf; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } break; @@ -327,7 +338,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) case ONLP_SFP_CONTROL_RESET_STATE: { VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_RESET_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -335,7 +346,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) case ONLP_SFP_CONTROL_LP_MODE: { VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_LPMODE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write LP mode status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write LP mode status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -352,6 +363,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_disable; VALIDATE_PORT(port); @@ -361,7 +374,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) *value = 0; if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } @@ -370,7 +383,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_TX_FAULT: { VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -381,39 +394,75 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if(present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } else { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read identifier from eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read identifier from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } else { switch(identifier) { case QSFP_DD_IDENTIFIER: case OSFP_IDENTIFIER: { - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write bank to eeprom fail\r\n", port); + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", port); + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } return ONLP_STATUS_E_INTERNAL; } - tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); - if(tx_disable < 0){ + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if(support_ctrls < 0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read control from eeprom fail", port); if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); } - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail\r\n", port); return ONLP_STATUS_E_INTERNAL; } - *value = tx_disable; + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write bank to eeprom fail", port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } + return ONLP_STATUS_E_INTERNAL; + } + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } + return ONLP_STATUS_E_INTERNAL; + } + tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); + if(tx_disable < 0){ + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail", port); + return ONLP_STATUS_E_INTERNAL; + } + *value = tx_disable; + } else { + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } + return ONLP_STATUS_E_UNSUPPORTED; + } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } break; @@ -422,7 +471,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case QSFP_PLUS_IDENTIFIER:{ tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); if(tx_disable < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } *value = tx_disable; @@ -442,7 +491,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_RESET_STATE: { VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_RESET_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; @@ -450,7 +499,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_LP_MODE: { VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_LPMODE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read LP mode status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read LP mode status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } return ONLP_STATUS_OK; diff --git a/packages/platforms/accton/x86-64/as9817-64/src/x86_64_accton_as9817_64/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9817-64/src/x86_64_accton_as9817_64/module/src/sfpi.c index d1f901ec3..e6c30bf74 100644 --- a/packages/platforms/accton/x86-64/as9817-64/src/x86_64_accton_as9817_64/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9817-64/src/x86_64_accton_as9817_64/module/src/sfpi.c @@ -28,6 +28,7 @@ #include #include "x86_64_accton_as9817_64_int.h" #include "x86_64_accton_as9817_64_log.h" +#include #define SFP_PORT_MIN 65 #define SFP_PORT_MAX 66 @@ -92,6 +93,8 @@ static const int port_bus_index[NUM_OF_SFP_PORT] = { #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 @@ -140,7 +143,7 @@ onlp_sfpi_is_present(int port) int present; if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -160,12 +163,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) memset(data, 0, 256); if(onlp_file_read(data, 256, &size, MODULE_EEPROM_FORMAT, PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -181,20 +184,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, MODULE_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -234,6 +237,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { int present = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -245,14 +249,14 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { //SFP if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } else { //QSFP identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -260,17 +264,25 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) switch(identifier) { case QSFP_DD_IDENTIFIER: //for as9817-64D case OSFP_IDENTIFIER: { //for as9817-64O + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to write tx_disable status to port(%d)", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if(eeprom_control < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } @@ -278,47 +290,45 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT){ - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } return ONLP_STATUS_E_INTERNAL; } } else { if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); } - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); return ONLP_STATUS_E_UNSUPPORTED; } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } break; @@ -328,7 +338,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) /* txdis valid bit(bit0-bit3), xxxx 1111 */ value = value&0xf; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -351,7 +361,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_RESET_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -361,7 +371,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) VALIDATE_QSFP(port); if (onlp_file_write_int(value, MODULE_LPMODE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to write LP mode status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write LP mode status to port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -379,6 +389,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_disable; VALIDATE_PORT(port); @@ -388,7 +400,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) *value = 0; if (port >= 65 && port <= 66) { if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } @@ -400,7 +412,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -415,14 +427,14 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if(present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } } else { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read identifier from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -430,33 +442,75 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) switch(identifier) { case QSFP_DD_IDENTIFIER: //for as9817-64D case OSFP_IDENTIFIER: { //for as9817-64O - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + syslog(LOG_ERR, "Failed to read Status byte, unable to read tx_disable status from port(%d)", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + return ONLP_STATUS_E_UNSUPPORTED; + } + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write bank to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } return ONLP_STATUS_E_INTERNAL; } - - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if(support_ctrls < 0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read control from eeprom fail", + port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); + } return ONLP_STATUS_E_INTERNAL; } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); - if(tx_disable < 0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write bank to eeprom fail", + port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + } + return ONLP_STATUS_E_INTERNAL; + } + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + } + return ONLP_STATUS_E_INTERNAL; + } + tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); + if(tx_disable < 0){ + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", + port); + } + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail", + port); + return ONLP_STATUS_E_INTERNAL; + } + *value = tx_disable; + } else { if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); } - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail\r\n", - port); - return ONLP_STATUS_E_INTERNAL; + return ONLP_STATUS_E_UNSUPPORTED; } - *value = tx_disable; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : write page to eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -466,7 +520,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case QSFP_PLUS_IDENTIFIER:{ //for as9817-64D tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); if(tx_disable < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d) : read TX disable from eeprom fail", port); return ONLP_STATUS_E_INTERNAL; } @@ -491,7 +545,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_RESET_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -501,7 +555,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) VALIDATE_QSFP(port); if (onlp_file_read_int(value, MODULE_LPMODE_FORMAT, port) < 0) { - AIM_LOG_ERROR("Unable to read LP mode status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read LP mode status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/as9926-24d/onlp/builds/x86_64_accton_as9926_24d/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9926-24d/onlp/builds/x86_64_accton_as9926_24d/module/src/sfpi.c index dca56b114..5ef3577b4 100644 --- a/packages/platforms/accton/x86-64/as9926-24d/onlp/builds/x86_64_accton_as9926_24d/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9926-24d/onlp/builds/x86_64_accton_as9926_24d/module/src/sfpi.c @@ -28,6 +28,7 @@ #include #include "x86_64_accton_as9926_24d_int.h" #include "x86_64_accton_as9926_24d_log.h" +#include #define SFP_PORT_MIN 24 #define SFP_PORT_MAX 25 @@ -89,6 +90,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_LPMODE 0x10 @@ -135,7 +138,7 @@ onlp_sfpi_is_present(int port) int bus = (port < 16) ? 20 : 21; if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -160,7 +163,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) sprintf(file, MODULE_PRESENT_ALL_ATTR, bus, addr); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD."); + syslog(LOG_ERR, "Unable to open the module_present_all device file of CPLD."); return ONLP_STATUS_E_INTERNAL; } @@ -169,7 +172,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) if(count != 2) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD."); + syslog(LOG_ERR, "Unable to read all fields the module_present_all device file of CPLD."); return ONLP_STATUS_E_INTERNAL; } @@ -207,7 +210,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD3, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_rx_los_all device file of CPLD(0x62)"); + syslog(LOG_ERR, "Unable to open the module_rx_los_all device file of CPLD(0x62)"); return ONLP_STATUS_E_INTERNAL; } @@ -215,7 +218,7 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fclose(fp); if(count != 1) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields from the module_rx_los_all device file of CPLD(0x62)"); + syslog(LOG_ERR, "Unable to read all fields from the module_rx_los_all device file of CPLD(0x62)"); return ONLP_STATUS_E_INTERNAL; } @@ -247,12 +250,12 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) memset(data, 0, 256); if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -268,20 +271,20 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to open the eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); + syslog(LOG_ERR, "Unable to set the file position indicator of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + syslog(LOG_ERR, "Unable to read the module_eeprom device file of port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -323,6 +326,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int present = 0; int lpmode_value = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -337,7 +341,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { //SFP if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, 21, 62, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -348,36 +352,46 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /*QSFP DD*/ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS); + if (status_byte < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read status byte from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; - } + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", + port); + rv = ONLP_STATUS_E_INTERNAL; + } else { eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); if(eeprom_control < 0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read control from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT){ if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -385,11 +399,10 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) rv = ONLP_STATUS_OK; } } else { - AIM_LOG_ERROR("Setting tx disable to port(%d) is not supported\r\n", port); rv = ONLP_STATUS_E_UNSUPPORTED; } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -399,7 +412,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) value = value&0xf; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) < 0 ){ - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -422,7 +435,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int bus = (port < 16) ? 20 : 21; if (onlp_file_write_int(value, MODULE_RESET_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to write reset status to port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to write reset status to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -439,7 +452,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) if (present == 1) { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -447,7 +460,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -457,7 +470,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) else lpmode_value &= ~QSFP_DD_LPMODE; if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW, lpmode_value) < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -471,7 +484,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -483,7 +496,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE, lpmode_value)< 0){ - AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -515,6 +528,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int present = 0; int lpmode_value = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE_PORT(port); @@ -525,7 +540,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, 21, 62, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -538,7 +553,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, 21, 62, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -555,7 +570,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if(present == 1) { if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, 21, 62, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -565,43 +580,70 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) else { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) {/* QSFP DD */ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write bank to eeprom fail\r\n", + /* Flat-memory CMIS modules do not implement page 01h/10h */ + status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS); + if (status_byte < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read status byte from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } - else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0 ){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0){ + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } else { - tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); - if(tx_dis < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if (support_ctrls < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read support control from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } - else{ - *value = tx_dis; - rv = ONLP_STATUS_OK; + else if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write bank to eeprom fail", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0 ){ + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); + if(tx_dis < 0){ + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else{ + *value = tx_dis; + rv = ONLP_STATUS_OK; + } + } + } else { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0){ + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", + port); + rv = ONLP_STATUS_E_INTERNAL; } - } - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", - port); - rv = ONLP_STATUS_E_INTERNAL; } } else { /* QSFP 28 or QSFP+ */ tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); if(tx_dis < 0){ - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read TX disable from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -626,7 +668,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int bus = (port < 16) ? 20 : 21; if (onlp_file_read_int(value, MODULE_RESET_FORMAT, bus, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -643,7 +685,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (present == 1) { identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); if(identifier < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read identifier from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -651,7 +693,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) /* lpmode valid bit(bit4):Low power requset sw */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -663,7 +705,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); if(lpmode_value < 0){ - AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read LP mode value from eeprom fail\r\n", + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read LP mode value from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/as9926-24db/onlp/builds/x86_64_accton_as9926_24db/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9926-24db/onlp/builds/x86_64_accton_as9926_24db/module/src/sfpi.c index 54e81348b..a7e89057e 100644 --- a/packages/platforms/accton/x86-64/as9926-24db/onlp/builds/x86_64_accton_as9926_24db/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9926-24db/onlp/builds/x86_64_accton_as9926_24db/module/src/sfpi.c @@ -28,9 +28,67 @@ #include #include "x86_64_accton_as9926_24db_int.h" #include "x86_64_accton_as9926_24db_log.h" +#include #define PORT_BUS_INDEX(port) (port+9) +#define SFP_PORT_MIN 24 +#define SFP_PORT_MAX 25 +#define QSFP_PORT_MIN 0 +#define QSFP_PORT_MAX 23 +#define MIN_PORT QSFP_PORT_MIN +#define MAX_PORT SFP_PORT_MAX + +#define VALIDATE_SFP(_port) \ + do { \ + if (_port < SFP_PORT_MIN || _port > SFP_PORT_MAX) \ + return ONLP_STATUS_E_UNSUPPORTED; \ + } while(0) + +#define VALIDATE_QSFP(_port) \ + do { \ + if (_port < QSFP_PORT_MIN || _port > QSFP_PORT_MAX) \ + return ONLP_STATUS_E_UNSUPPORTED; \ + } while(0) + +#define VALIDATE_PORT(_port) \ + do { \ + if (_port < MIN_PORT || _port > MAX_PORT) \ + return ONLP_STATUS_E_UNSUPPORTED; \ + } while(0) + +/* QSFP device address of eeprom */ +#define PORT_EEPROM_DEVADDR 0x50 + +/*QSFP identify offsets*/ +#define QSFP_EEPROM_OFFSET_IDENTIFIER 0x0 + +/* QSFP eeprom offsets*/ +#define QSFP_EEPROM_OFFSET_TXDIS 0x56 + +/* QSFP DD eeprom offsets*/ +#define QSFP_DD_EEPROM_OFFSET_BANK_SELECT 0x7E +#define QSFP_DD_EEPROM_OFFSET_PAGE_SELECT 0x7F +#define QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1 0x9B +#define QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 +#define QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW 0x1A + +/*QSFP Specific*/ +#define QSFP_EEPROM_OFFSET_LPMODE 0x5D +#define QSFP_LPMODE 0x3 + +/* QSFP DD Specific*/ +#define QSFP_DD_PAGE_ADMIN_INFO 0x0 +#define QSFP_DD_PAGE_ADVERTISING 0x1 +#define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ +#define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 +#define QSFP_DD_LPMODE 0x10 + +/* OSFP IDENTIFIER Specific*/ +#define QSFP_DD_IDENTIFIER 0x18 + #define PORT_EEPROM_FORMAT \ "/sys/bus/i2c/devices/%d-0050/eeprom" #define MODULE_PRESENT_FORMAT \ @@ -85,7 +143,7 @@ int onlp_sfpi_is_present(int port) if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", + syslog(LOG_ERR, "Unable to read present status from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -103,7 +161,7 @@ int onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) fp = fopen(MODULE_PRESENT_ALL_ATTR, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_present_all \ + syslog(LOG_ERR, "Unable to open the module_present_all \ device file from (%s).", MODULE_PRESENT_ALL_ATTR); return ONLP_STATUS_E_INTERNAL; @@ -116,7 +174,7 @@ int onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) if(count != 4) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the \ + syslog(LOG_ERR, "Unable to read all fields the \ module_present_all device file from(%s).", MODULE_PRESENT_ALL_ATTR); return ONLP_STATUS_E_INTERNAL; @@ -157,7 +215,7 @@ int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) fp = fopen(MODULE_RXLOS_ALL_ATTR, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_rxlos_all \ + syslog(LOG_ERR, "Unable to open the module_rxlos_all \ device file from (%s).", MODULE_RXLOS_ALL_ATTR); @@ -170,7 +228,7 @@ int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) if(count != 1) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_rxlos_all \ + syslog(LOG_ERR, "Unable to read all fields the module_rxlos_all \ device file from(%s).", MODULE_RXLOS_ALL_ATTR); return ONLP_STATUS_E_INTERNAL; @@ -212,13 +270,13 @@ int onlp_sfpi_eeprom_read(int port, uint8_t data[256]) if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is \ - different!\r\n", port); + syslog(LOG_ERR, "Unable to read eeprom from port(%d), size is \ + different!", port); return ONLP_STATUS_E_INTERNAL; } @@ -233,14 +291,14 @@ int onlp_sfpi_dom_read(int port, uint8_t data[256]) sprintf(file, PORT_EEPROM_FORMAT, PORT_BUS_INDEX(port)); fp = fopen(file, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of \ + syslog(LOG_ERR, "Unable to open the eeprom device file of \ port(%d)", port); return ONLP_STATUS_E_INTERNAL; } if (fseek(fp, 256, SEEK_CUR) != 0) { fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of \ + syslog(LOG_ERR, "Unable to set the file position indicator of \ port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -248,7 +306,7 @@ int onlp_sfpi_dom_read(int port, uint8_t data[256]) int ret = fread(data, 1, 256, fp); fclose(fp); if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of \ + syslog(LOG_ERR, "Unable to read the module_eeprom device file of \ port(%d)", port); return ONLP_STATUS_E_INTERNAL; } @@ -258,16 +316,106 @@ int onlp_sfpi_dom_read(int port, uint8_t data[256]) int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { - int rv; + int rv = ONLP_STATUS_E_INTERNAL; + int present = 0; + int lpmode_value = 0; + int identifier = 0; + int status_byte = 0; + int eeprom_control; + + VALIDATE_PORT(port); switch(control) { case ONLP_SFP_CONTROL_TX_DISABLE: + case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL: + { + present = onlp_sfpi_is_present(port); + if (present == 1) { + if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { /* SFP */ + if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, + (port+1)) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + } + else { /* QSFP */ + identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); + if (identifier < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read identifier from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ + /* Flat-memory CMIS modules do not implement page 01h/10h */ + status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS); + if (status_byte < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read status byte from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + eeprom_control = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if (eeprom_control < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): read control from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write bank to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX, value) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + } else { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write page to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + } + } else { /* QSFP 28 or QSFP+ */ + value = value & 0xf; + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS, value) < 0) { + syslog(LOG_ERR, "Unable to write tx_disable status to port(%d): write TX disable to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + } + } + } + else { + rv = ONLP_STATUS_E_INTERNAL; + } + break; + } + + case ONLP_SFP_CONTROL_RESET: { - if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, + VALIDATE_QSFP(port); + if (onlp_file_write_int(value, MODULE_RESET_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to set tx_disable status to \ - port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to set reset to port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -276,22 +424,58 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) break; } - case ONLP_SFP_CONTROL_RESET: + case ONLP_SFP_CONTROL_LP_MODE: { - if(port <= 23) - { - if (onlp_file_write_int(value, MODULE_RESET_FORMAT, - (port+1)) < 0) { - AIM_LOG_ERROR("Unable to set reset to \ - port(%d)\r\n", port); + VALIDATE_QSFP(port); + present = onlp_sfpi_is_present(port); + if (present == 1) { + identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); + if (identifier < 0) { + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read identifier from eeprom fail", port); rv = ONLP_STATUS_E_INTERNAL; } - else { - rv = ONLP_STATUS_OK; + else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ + lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); + if (lpmode_value < 0) { + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + if (value) + lpmode_value |= QSFP_DD_LPMODE; + else + lpmode_value &= ~QSFP_DD_LPMODE; + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW, lpmode_value) < 0) { + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + } + } else { /* QSFP 28 or QSFP+ */ + lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); + if (lpmode_value < 0) { + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): read LP mode value from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + if (value) + lpmode_value |= QSFP_LPMODE; + else + lpmode_value &= ~QSFP_LPMODE; + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE, lpmode_value) < 0) { + syslog(LOG_ERR, "Unable to write LP mode status to port(%d): write LP mode value to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + } } } else { - return ONLP_STATUS_E_UNSUPPORTED; + rv = ONLP_STATUS_E_INTERNAL; } break; } @@ -332,43 +516,37 @@ onlp_sfpi_dev_writew(int port, uint8_t devaddr, uint8_t addr, uint16_t value) int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { - int rv; + int rv = ONLP_STATUS_E_INTERNAL; + int present = 0; + int lpmode_value = 0; + int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; + int tx_dis = 0; - if (port < 0) { - return ONLP_STATUS_E_UNSUPPORTED; - } + VALIDATE_PORT(port); switch(control) { case ONLP_SFP_CONTROL_RESET: { - if(port <= 23) - { - if(onlp_file_read_int(value, MODULE_RESET_FORMAT, - (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read reset status \ - from port(%d)\r\n", port); - rv = ONLP_STATUS_E_INTERNAL; - } - else { - rv = ONLP_STATUS_OK; - } + VALIDATE_QSFP(port); + if (onlp_file_read_int(value, MODULE_RESET_FORMAT, + (port+1)) < 0) { + syslog(LOG_ERR, "Unable to read reset status from port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; } else { - return ONLP_STATUS_E_UNSUPPORTED; + rv = ONLP_STATUS_OK; } break; - } case ONLP_SFP_CONTROL_RX_LOS: { - if (port <= 23) - return ONLP_STATUS_E_UNSUPPORTED; - - if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, + VALIDATE_SFP(port); + if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read rx_loss status \ - from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read rx_loss status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -379,13 +557,10 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_TX_FAULT: { - if (port <= 23) - return ONLP_STATUS_E_UNSUPPORTED; - + VALIDATE_SFP(port); if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_fault status \ - from port(%d)\r\n", port); + syslog(LOG_ERR, "Unable to read tx_fault status from port(%d)", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -395,25 +570,137 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } case ONLP_SFP_CONTROL_TX_DISABLE: + case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL: { - if(port <= 23) - return ONLP_STATUS_E_UNSUPPORTED; - - if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, - (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read tx_disabled status \ - from port(%d)\r\n", port); + present = onlp_sfpi_is_present(port); + if (present == 1) { + if (port >= SFP_PORT_MIN && port <= SFP_PORT_MAX) { /* SFP */ + if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, + (port+1)) < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d)", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + } + else { /* QSFP */ + identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); + if (identifier < 0) { + syslog(LOG_ERR, "Unable to read tx_disabled status from port(%d): read identifier from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ + /* Flat-memory CMIS modules do not implement page 01h/10h */ + status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS); + if (status_byte < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read status byte from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if (support_ctrls < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read support control from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write bank to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); + if (tx_dis < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + *value = tx_dis; + rv = ONLP_STATUS_OK; + } + } + } else { + rv = ONLP_STATUS_E_UNSUPPORTED; + } + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): write page to eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + } + } + else { /* QSFP 28 or QSFP+ */ + tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_TXDIS); + if (tx_dis < 0) { + syslog(LOG_ERR, "Unable to read tx_disable status from port(%d): read TX disable from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + *value = tx_dis; + rv = ONLP_STATUS_OK; + } + } + } + } + else { rv = ONLP_STATUS_E_INTERNAL; } + break; + } + + case ONLP_SFP_CONTROL_LP_MODE: + { + VALIDATE_QSFP(port); + present = onlp_sfpi_is_present(port); + if (present == 1) { + identifier = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_IDENTIFIER); + if (identifier < 0) { + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read identifier from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ + /* lpmode valid bit(bit4): Low power request sw */ + lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_LOWPWR_REQUEST_SW); + if (lpmode_value < 0) { + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read LP mode value from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + *value = !!(lpmode_value & QSFP_DD_LPMODE); + rv = ONLP_STATUS_OK; + } + } else { /* QSFP 28 or QSFP+ */ + /* lpmode valid bit(bit0):set LP/txdis mode bit(bit1):set low/high power mode */ + lpmode_value = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_LPMODE); + if (lpmode_value < 0) { + syslog(LOG_ERR, "Unable to read LP mode status from port(%d): read LP mode value from eeprom fail", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + *value = ((lpmode_value & QSFP_LPMODE) == QSFP_LPMODE); + rv = ONLP_STATUS_OK; + } + } + } else { - rv = ONLP_STATUS_OK; + rv = ONLP_STATUS_E_INTERNAL; } break; } default: rv = ONLP_STATUS_E_UNSUPPORTED; - } + } return rv; }