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/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/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 034639c6f..6454d9fa3 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; }