diff --git a/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c index be28c81dd..94c7d4453 100644 --- a/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c @@ -83,6 +83,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -318,6 +320,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; int mbit_identifier; int mbit_value; @@ -337,6 +340,15 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (identifier == QSFP_DD_IDENTIFIER) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; @@ -351,10 +363,6 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { - if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); - goto restore; - } if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0 ) { AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", QSFP_DD_PAGE_LANE_CTRL, port); @@ -469,6 +477,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; int multirate = 0; int mbit_identifier; @@ -510,18 +520,42 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (identifier == QSFP_DD_IDENTIFIER) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if ((support_ctrls = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = support_ctrls; + goto restore; + } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, XCVR_PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); + rv = tx_dis; + goto restore; + } + } else { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -533,7 +567,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (rv < 0) { AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - return ONLP_STATUS_E_INTERNAL; + return (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } *value = (tx_dis & 0xff); return ONLP_STATUS_OK; 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..8ff70af72 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 @@ -99,6 +99,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 @@ -260,6 +262,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); @@ -287,7 +290,21 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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 ){ + /* 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); + rv = ONLP_STATUS_E_INTERNAL; + } + else 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); rv = ONLP_STATUS_E_INTERNAL; @@ -300,12 +317,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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", - 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) { + 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); rv = ONLP_STATUS_E_INTERNAL; @@ -458,6 +470,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); @@ -503,14 +517,35 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) 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){ + /* 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); 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", - port); + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0){ + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", 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){ + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + 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("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -521,7 +556,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) rv = ONLP_STATUS_E_INTERNAL; } else{ - *value = tx_dis; + *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } diff --git a/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c index 23eed5eb1..0b90b54f1 100644 --- a/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7946-30xb/onlp/builds/x86_64_accton_as7946_30xb/module/src/sfpi.c @@ -44,6 +44,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -274,6 +276,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; VALIDATE(port); @@ -291,6 +294,15 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (identifier == QSFP_DD_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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; @@ -305,10 +317,6 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); - goto restore; - } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", QSFP_DD_PAGE_LANE_CTRL, port); @@ -414,6 +422,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE(port); @@ -454,18 +464,42 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (identifier == QSFP_DD_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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = support_ctrls; + goto restore; + } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); + rv = tx_dis; + goto restore; + } + } else { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -477,7 +511,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (rv < 0) { AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - rv = ONLP_STATUS_E_INTERNAL; + rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; diff --git a/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c b/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c index 595649b6f..f2efd6362 100644 --- a/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as7946-74xkb/onlp/builds/x86_64_accton_as7946_74xkb/module/src/sfpi.c @@ -44,6 +44,8 @@ #define QSFP_DD_PAGE_ADMIN_INFO 0x0 #define QSFP_DD_PAGE_ADVERTISING 0x1 #define QSFP_DD_PAGE_LANE_CTRL 0x10 +#define QSFP_DD_LOWER_OFFSET_STATUS 0x02 +#define QSFP_DD_FLAT_MEM 0x80 /* byte 0x02 bit 7 */ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -287,6 +289,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; VALIDATE(port); @@ -304,6 +307,15 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (identifier == QSFP_DD_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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; @@ -318,10 +330,6 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); - goto restore; - } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", QSFP_DD_PAGE_LANE_CTRL, port); @@ -437,6 +445,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) char *path = NULL; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE(port); @@ -480,18 +490,42 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (identifier == QSFP_DD_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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); + goto restore; + } + if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = support_ctrls; goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); + rv = tx_dis; + goto restore; + } + } else { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -503,7 +537,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (rv < 0) { AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - rv = ONLP_STATUS_E_INTERNAL; + rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; 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..35a6e7989 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 @@ -85,6 +85,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 @@ -287,6 +289,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); @@ -324,7 +327,21 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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 ){ + /* 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); + rv = ONLP_STATUS_E_INTERNAL; + } + else 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); rv = ONLP_STATUS_E_INTERNAL; @@ -337,12 +354,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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", - 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) { + 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); rv = ONLP_STATUS_E_INTERNAL; @@ -482,6 +494,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); @@ -546,14 +560,35 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) 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){ + /* 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); 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", - port); + else if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0){ + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", 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){ + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + 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("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -564,7 +599,7 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) rv = ONLP_STATUS_E_INTERNAL; } else{ - *value = tx_dis; + *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } diff --git a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c index 748d861f6..e20845835 100644 --- a/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9726-32d/onlp/builds/x86_64_accton_as9726_32d/module/src/sfpi.c @@ -82,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_OFFSET_CONTROL_1 0x9B #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2 #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82 @@ -353,6 +355,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int bus = 10; int present = 0; int identifier = 0; + int status_byte = 0; int support_ctrls = 0; VALIDATE(port); @@ -370,6 +373,15 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) } if (identifier == QSFP_DD_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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to write tx_disable status to port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; @@ -384,10 +396,6 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) goto restore; } if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { - AIM_LOG_ERROR("Failed to set Bank 0 on port(%d)\r\n", port); - goto restore; - } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", QSFP_DD_PAGE_LANE_CTRL, port); @@ -485,6 +493,8 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int bus = 10; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE(port); @@ -532,18 +542,42 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) } if (identifier == QSFP_DD_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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_BANK_SELECT, 0)) < 0) { AIM_LOG_ERROR("Failed to set Bank 0, unable to read tx_disable status from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } - if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { - AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", - QSFP_DD_PAGE_LANE_CTRL, port); + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING)) < 0) { + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); goto restore; } - if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { - AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); - rv = tx_dis; + if ((support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P01H_OFFSET_CONTROL_1)) < 0) { + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = support_ctrls; + goto restore; + } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if ((rv = onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL)) < 0) { + AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); + goto restore; + } + if ((tx_dis = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX)) < 0) { + AIM_LOG_ERROR("Failed to read TX_DISABLE value from Lane Control register on port(%d)\r\n", port); + rv = tx_dis; + goto restore; + } + } else { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; goto restore; } @@ -555,7 +589,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) if (rv < 0) { AIM_LOG_ERROR("Unable to get tx_disable status from port(%d)\r\n", port); - rv = ONLP_STATUS_E_INTERNAL; + rv = (rv == ONLP_STATUS_E_UNSUPPORTED) ? rv : ONLP_STATUS_E_INTERNAL; } else { *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; diff --git a/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c index ff7fb62d6..05d84dce0 100644 --- a/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9736-64d/onlp/builds/x86_64_accton_as9736_64d/module/src/sfpi.c @@ -94,6 +94,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 @@ -419,6 +421,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int rv = ONLP_STATUS_E_INTERNAL; int present = 0; int identifier = 0; + int status_byte = 0; int eeprom_control; VALIDATE_PORT(port); @@ -447,7 +450,21 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_eeprom_readb(port, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); rv = ONLP_STATUS_E_INTERNAL; @@ -460,12 +477,7 @@ int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) rv = ONLP_STATUS_E_INTERNAL; } else if (eeprom_control & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { - if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { - AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write bank to eeprom fail\r\n", - port); - rv = ONLP_STATUS_E_INTERNAL; - } - else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write page to eeprom fail\r\n", port); rv = ONLP_STATUS_E_INTERNAL; @@ -549,6 +561,8 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int rv = ONLP_STATUS_E_INTERNAL; int present = 0; int identifier = 0; + int status_byte = 0; + int support_ctrls = 0; int tx_dis = 0; VALIDATE_PORT(port); @@ -603,14 +617,35 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) rv = ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_eeprom_readb(port, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write bank to eeprom fail\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } + else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) < 0) { + AIM_LOG_ERROR("Failed to switch to Advertising Page on port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if ((support_ctrls = onlp_sfpi_eeprom_readb(port, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1)) < 0) { + AIM_LOG_ERROR("Failed to read Support Control on port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } else if (onlp_sfpi_eeprom_writeb(port, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", - port); + AIM_LOG_ERROR("Failed to switch to Lane Control Page (Page 0x%02x) on port(%d)\r\n", + QSFP_DD_PAGE_LANE_CTRL, port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -621,7 +656,7 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) rv = ONLP_STATUS_E_INTERNAL; } else { - *value = tx_dis; + *value = (tx_dis & 0xff); rv = ONLP_STATUS_OK; } } diff --git a/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c index 1263413b5..2c555f63c 100644 --- a/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/as9737-32db/onlp/builds/x86_64_accton_as9737_32db/module/src/sfpi.c @@ -93,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 /*QSFP Specific*/ @@ -252,6 +254,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) int present = 0; int identifier = 0; int eeprom_control; + int status_byte = 0; VALIDATE_PORT(port); @@ -278,7 +281,21 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) return ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADVERTISING) <0 ){ + /* 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } + else 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); + return ONLP_STATUS_E_INTERNAL; + } + else 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); return ONLP_STATUS_E_INTERNAL; @@ -297,17 +314,6 @@ 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_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); - } - - 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); @@ -401,6 +407,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) int present = 0; int identifier = 0; int tx_disable; + int status_byte = 0; + int support_ctrls = 0; VALIDATE_PORT(port); @@ -451,15 +459,51 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) return ONLP_STATUS_E_INTERNAL; } else if (identifier == QSFP_DD_IDENTIFIER) { /* QSFP DD */ - if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_BANK_SELECT, 0) < 0) { + /* Flat-memory CMIS modules do not implement page 01h/10h */ + if ((status_byte = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_LOWER_OFFSET_STATUS)) < 0) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disabled status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Reading tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } + /* Switch to Advertising page to check 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 read tx_disabled status from port(%d) : write bank to eeprom fail\r\n", 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) { + 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 page to eeprom fail\r\n", + port); + return ONLP_STATUS_E_INTERNAL; + } + + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if (support_ctrls < 0) { + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read support control from eeprom fail\r\n", + 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); + } + return ONLP_STATUS_E_INTERNAL; + } + + if (!(support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT)) { + AIM_LOG_ERROR("Reading tx_disable from port(%d) is not supported\r\n", 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); + } + return ONLP_STATUS_E_UNSUPPORTED; + } + /* Switch to Lane Control page to read TX disable */ + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", port); return ONLP_STATUS_E_INTERNAL; @@ -476,6 +520,8 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) return ONLP_STATUS_E_INTERNAL; } *value = tx_disable; + + /* Restore page */ if(onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) <0){ AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", port); 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..50e404174 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 @@ -81,6 +81,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*/ @@ -232,6 +234,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); @@ -257,6 +260,19 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } + 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); + return ONLP_STATUS_E_INTERNAL; + } 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); return ONLP_STATUS_E_INTERNAL; @@ -270,13 +286,6 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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_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); - } - 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); if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_ADMIN_INFO) < 0) { @@ -352,6 +361,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); @@ -395,23 +406,58 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } 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); 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) { + 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 page to eeprom fail\r\n", 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); + } 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){ + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read control from eeprom fail\r\n", 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); } - 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_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(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); + } + 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){ + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", 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; + } else { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", 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); + } + 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); return ONLP_STATUS_E_INTERNAL; diff --git a/packages/platforms/accton/x86-64/as9817-64/src/x86_64_accton_as9817_64/module/src/sfpi.c b/packages/platforms/accton/x86-64/as9817-64/src/x86_64_accton_as9817_64/module/src/sfpi.c index d1f901ec3..aa842a12a 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 @@ -92,6 +92,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 @@ -234,6 +236,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); @@ -260,6 +263,20 @@ 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to write tx_disable status to port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } + 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); + return ONLP_STATUS_E_INTERNAL; + } 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); @@ -278,17 +295,6 @@ 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_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); - } - - 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); @@ -379,6 +385,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); @@ -430,31 +438,71 @@ 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 + /* 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) { + AIM_LOG_ERROR("Failed to read Status byte, unable to read tx_disable status from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + return ONLP_STATUS_E_UNSUPPORTED; + } 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); 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) { + 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 page to eeprom fail\r\n", 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); + } + return ONLP_STATUS_E_INTERNAL; + } + support_ctrls = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P01H_OFFSET_CONTROL_1); + if(support_ctrls < 0){ + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : read control from eeprom fail\r\n", + 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); + } return ONLP_STATUS_E_INTERNAL; } + if (support_ctrls & QSFP_DD_P01H_TX_DISABLE_SUPPORT) { + if (onlp_sfpi_dev_writeb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_OFFSET_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { - tx_disable = onlp_sfpi_dev_readb(port, PORT_EEPROM_DEVADDR, QSFP_DD_EEPROM_P10H_OFFSET_OUTPUT_DISABLE_TX); - if(tx_disable < 0){ + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + 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); + } + 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){ + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d) : write page to eeprom fail\r\n", + 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; + } else { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported\r\n", 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); } - 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", port); 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..9ad54fbbd 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 @@ -89,6 +89,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 @@ -323,6 +325,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); @@ -353,7 +356,23 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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 ){ + /* 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) { + AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read status byte from eeprom fail\r\n", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); + rv = ONLP_STATUS_E_INTERNAL; + } + else 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); rv = ONLP_STATUS_E_INTERNAL; @@ -366,12 +385,7 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) 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", - 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) { + 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); rv = ONLP_STATUS_E_INTERNAL; @@ -515,6 +529,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); @@ -570,32 +586,61 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) 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) { + AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read status byte from eeprom fail\r\n", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); 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(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_disable status from port(%d): write page to eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read support control from eeprom fail\r\n", 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_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0 ){ + AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", + port); + 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", + port); + rv = ONLP_STATUS_E_INTERNAL; + } + else{ + *value = tx_dis; + rv = ONLP_STATUS_OK; + } + } + } else { + AIM_LOG_ERROR("Getting tx_disable from 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 read tx_disable status from port(%d): write page to eeprom fail\r\n", + 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+ */ 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..b2a58500d 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 @@ -31,6 +31,63 @@ #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 \ @@ -258,16 +315,108 @@ 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) { + AIM_LOG_ERROR("Unable to write tx_disable status to port(%d)\r\n", 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) { + AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read identifier from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): read status byte from eeprom fail\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Setting tx_disable to port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); + rv = ONLP_STATUS_E_INTERNAL; + } + else 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); + 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", 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_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); + 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", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + 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", 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) { + AIM_LOG_ERROR("Unable to write tx_disable status to port(%d): write TX disable to eeprom fail\r\n", 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); + AIM_LOG_ERROR("Unable to set reset to port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -276,22 +425,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) { + AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read identifier from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to write LP mode status to port(%d): read LP mode value from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to write LP mode status to port(%d): write LP mode value to eeprom fail\r\n", 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 +517,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) { + AIM_LOG_ERROR("Unable to read reset status from port(%d)\r\n", 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); + AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -379,13 +558,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); + AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } else { @@ -395,25 +571,139 @@ 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) { + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", 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) { + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d): read identifier from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read status byte from eeprom fail\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else if (status_byte & QSFP_DD_FLAT_MEM) { + AIM_LOG_ERROR("Getting tx_disable from port(%d) is not supported (flat-memory module)\r\n", port); + rv = ONLP_STATUS_E_UNSUPPORTED; + } + else 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); + rv = ONLP_STATUS_E_INTERNAL; + } + else 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_disable status from port(%d): write page to eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): read support control from eeprom fail\r\n", 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_PAGE_SELECT, QSFP_DD_PAGE_LANE_CTRL) < 0) { + AIM_LOG_ERROR("Unable to read tx_disable status from port(%d): write page to eeprom fail\r\n", port); + 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", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + *value = tx_dis; + rv = ONLP_STATUS_OK; + } + } + } else { + AIM_LOG_ERROR("Getting tx_disable from 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 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", 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) { + AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read identifier from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read LP mode value from eeprom fail\r\n", 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) { + AIM_LOG_ERROR("Unable to read LP mode status from port(%d): read LP mode value from eeprom fail\r\n", 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; }