2929#include "x86_64_accton_as7535_28xb_int.h"
3030#include "x86_64_accton_as7535_28xb_log.h"
3131
32+ #define VALIDATE (_port ) \
33+ do { \
34+ if (_port < 0 || _port > 27) { \
35+ return ONLP_STATUS_E_INVALID; \
36+ } \
37+ } while(0)
38+
3239#define VALIDATE_SFP (_port ) \
3340 do { \
3441 if (_port < 4 || _port > 27) \
6269#define SET_RATE_SELECT_BIT (x ,RS_BIT_pos ) (x | (1<<RS_BIT_pos))
6370#define RESET_RATE_SELECT_BIT (x ,RS_BIT_pos ) (x & ~(1<<RS_BIT_pos))
6471
72+ /* QSFP device address of eeprom */
73+ #define XCVR_PORT_EEPROM_DEVADDR 0x50
74+
75+ /* QSFP eeprom offsets*/
76+ #define QSFP_EEPROM_OFFSET_IDENTIFIER 0x0
77+ #define QSFP_EEPROM_OFFSET_TXDIS 0x56
78+ #define QSFP_EEPROM_OFFSET_BANK_SELECT 0x7E
79+ #define QSFP_EEPROM_OFFSET_PAGE_SELECT 0x7F
80+
81+ /* QSFP DD Specific*/
82+ #define QSFP_DD_IDENTIFIER 0x18
83+ #define QSFP_DD_PAGE_ADMIN_INFO 0x0
84+ #define QSFP_DD_PAGE_ADVERTISING 0x1
85+ #define QSFP_DD_PAGE_LANE_CTRL 0x10
86+ #define QSFP_DD_P01H_OFFSET_CONTROL_1 0x9B
87+ #define QSFP_DD_P01H_TX_DISABLE_SUPPORT 0x2
88+ #define QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX 0x82
89+
6590#define NUM_OF_SFP_PORT 28
6691static const int port_bus_index [NUM_OF_SFP_PORT ] = {
6792 23 , 21 , 24 , 22 , 25 , 26 , 27 , 28 , 29 , 30 ,
87112onlp_sfpi_bitmap_get (onlp_sfp_bitmap_t * bmap )
88113{
89114 /*
90- * Ports {0, 54 }
115+ * Ports {0, 27 }
91116 */
92117 int p ;
93118
@@ -107,6 +132,7 @@ onlp_sfpi_is_present(int port)
107132 * Return < 0 if error.
108133 */
109134 int present ;
135+ VALIDATE (port );
110136
111137 if (onlp_file_read_int (& present , MODULE_PRESENT_FORMAT , (port + 1 )) < 0 ) {
112138 AIM_LOG_ERROR ("Unable to read present status from port(%d)\r\n" , port );
@@ -212,6 +238,8 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])
212238 * Return OK if eeprom is read
213239 */
214240 int size = 0 ;
241+
242+ VALIDATE (port );
215243 memset (data , 0 , 256 );
216244
217245 if (onlp_file_read (data , 256 , & size , PORT_EEPROM_FORMAT , PORT_BUS_INDEX (port )) != ONLP_STATUS_OK ) {
@@ -259,49 +287,79 @@ onlp_sfpi_dom_read(int port, uint8_t data[256])
259287int
260288onlp_sfpi_dev_readb (int port , uint8_t devaddr , uint8_t addr )
261289{
262- int bus = PORT_BUS_INDEX (port );
263- return onlp_i2c_readb (bus , devaddr , addr , ONLP_I2C_F_FORCE );
290+ VALIDATE (port );
291+ return onlp_i2c_readb (PORT_BUS_INDEX ( port ) , devaddr , addr , ONLP_I2C_F_FORCE );
264292}
265293
266294int
267295onlp_sfpi_dev_writeb (int port , uint8_t devaddr , uint8_t addr , uint8_t value )
268296{
269- int bus = PORT_BUS_INDEX (port );
270- return onlp_i2c_writeb (bus , devaddr , addr , value , ONLP_I2C_F_FORCE );
297+ VALIDATE (port );
298+ return onlp_i2c_writeb (PORT_BUS_INDEX ( port ) , devaddr , addr , value , ONLP_I2C_F_FORCE );
271299}
272300
273301int
274302onlp_sfpi_dev_readw (int port , uint8_t devaddr , uint8_t addr )
275303{
276- int bus = PORT_BUS_INDEX (port );
277- return onlp_i2c_readw (bus , devaddr , addr , ONLP_I2C_F_FORCE );
304+ VALIDATE (port );
305+ return onlp_i2c_readw (PORT_BUS_INDEX ( port ) , devaddr , addr , ONLP_I2C_F_FORCE );
278306}
279307
280308int
281309onlp_sfpi_dev_writew (int port , uint8_t devaddr , uint8_t addr , uint16_t value )
282310{
283- int bus = PORT_BUS_INDEX (port );
284- return onlp_i2c_writew (bus , devaddr , addr , value , ONLP_I2C_F_FORCE );
311+ VALIDATE (port );
312+ return onlp_i2c_writew (PORT_BUS_INDEX ( port ) , devaddr , addr , value , ONLP_I2C_F_FORCE );
285313}
286314
287315int
288316onlp_sfpi_control_set (int port , onlp_sfp_control_t control , int value )
289317{
290318 int present = 0 ;
319+ int identifier = 0 ;
291320 int mbit_identifier ;
292321 int mbit_value ;
293- switch (control ) {
294- case ONLP_SFP_CONTROL_TX_DISABLE : {
295- VALIDATE_SFP (port );
296322
297- if (onlp_file_write_int (value , MODULE_TXDISABLE_FORMAT , (port + 1 )) < 0 ) {
298- AIM_LOG_ERROR ("Unable to set tx_disable status to port(%d)\r\n" , port );
323+ switch (control ) {
324+ case ONLP_SFP_CONTROL_TX_DISABLE :
325+ case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL : {
326+ VALIDATE (port );
327+ present = onlp_sfpi_is_present (port );
328+ if (present == 1 ) {
329+ if (port >= 0 && port <= 3 ) {
330+ identifier = onlp_sfpi_dev_readb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_IDENTIFIER );
331+
332+ if (identifier == QSFP_DD_IDENTIFIER ) {
333+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_PAGE_SELECT , QSFP_DD_PAGE_ADVERTISING );
334+
335+ if (onlp_sfpi_dev_readb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_DD_P01H_OFFSET_CONTROL_1 ) & QSFP_DD_P01H_TX_DISABLE_SUPPORT ) {
336+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_BANK_SELECT , 0 );
337+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_PAGE_SELECT , QSFP_DD_PAGE_LANE_CTRL );
338+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX , value );
339+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_PAGE_SELECT , QSFP_DD_PAGE_ADMIN_INFO );
340+ return ONLP_STATUS_OK ;
341+ } else {
342+ AIM_LOG_ERROR ("Setting tx disable to port(%d) is not supported\r\n" , port );
343+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_PAGE_SELECT , QSFP_DD_PAGE_ADMIN_INFO );
344+ return ONLP_STATUS_E_UNSUPPORTED ;
345+ }
346+ } else { /* QSFP */
347+ /* txdis valid bit(bit0-bit3), xxxx 1111 */
348+ value = value & 0xf ;
349+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_TXDIS , value );
350+ return ONLP_STATUS_OK ;
351+ }
352+ } else {
353+ if (onlp_file_write_int (value , MODULE_TXDISABLE_FORMAT , (port + 1 )) < 0 ) {
354+ AIM_LOG_ERROR ("Unable to set tx_disable status to port(%d)\r\n" , port );
355+ return ONLP_STATUS_E_INTERNAL ;
356+ }
357+ return ONLP_STATUS_OK ;
358+ }
359+ } else {
360+ AIM_LOG_ERROR ("No transceiver is present in port(%d)\r\n" , port );
299361 return ONLP_STATUS_E_INTERNAL ;
300362 }
301- else {
302- return ONLP_STATUS_OK ;
303- }
304- break ;
305363 }
306364 case ONLP_SFP_CONTROL_RESET : {
307365 VALIDATE_QSFP (port );
369427onlp_sfpi_control_get (int port , onlp_sfp_control_t control , int * value )
370428{
371429 int present = 0 ;
430+ int identifier = 0 ;
431+ int tx_dis = 0 ;
372432 int multirate = 0 ;
373433 int mbit_identifier ;
374434 switch (control ) {
@@ -394,15 +454,35 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
394454 return ONLP_STATUS_OK ;
395455 }
396456
397- case ONLP_SFP_CONTROL_TX_DISABLE : {
398- VALIDATE_SFP (port );
399-
400- if (onlp_file_read_int (value , MODULE_TXDISABLE_FORMAT , (port + 1 )) < 0 ) {
401- AIM_LOG_ERROR ("Unable to read tx_disabled status from port(%d)\r\n" , port );
457+ case ONLP_SFP_CONTROL_TX_DISABLE :
458+ case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL : {
459+ VALIDATE (port );
460+ present = onlp_sfpi_is_present (port );
461+ if (present == 1 ) {
462+ if (port >= 0 && port <= 3 ) {
463+ identifier = onlp_sfpi_dev_readb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_IDENTIFIER );
464+
465+ if (identifier == QSFP_DD_IDENTIFIER ) {
466+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_BANK_SELECT , 0 );
467+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_PAGE_SELECT , QSFP_DD_PAGE_LANE_CTRL );
468+ tx_dis = onlp_sfpi_dev_readb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_DD_P10H_OFFSET_OUTPUT_DISABLE_TX );
469+ onlp_sfpi_dev_writeb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_PAGE_SELECT , QSFP_DD_PAGE_ADMIN_INFO );
470+ } else { /* QSFP */
471+ tx_dis = onlp_sfpi_dev_readb (port , XCVR_PORT_EEPROM_DEVADDR , QSFP_EEPROM_OFFSET_TXDIS );
472+ }
473+ * value = tx_dis ;
474+ return ONLP_STATUS_OK ;
475+ } else { /* SFP */
476+ if (onlp_file_read_int (value , MODULE_TXDISABLE_FORMAT , (port + 1 )) < 0 ) {
477+ AIM_LOG_ERROR ("Unable to read tx_disabled status from port(%d)\r\n" , port );
478+ return ONLP_STATUS_E_INTERNAL ;
479+ }
480+ return ONLP_STATUS_OK ;
481+ }
482+ } else {
483+ AIM_LOG_ERROR ("No transceiver is present in port(%d)\r\n" , port );
402484 return ONLP_STATUS_E_INTERNAL ;
403485 }
404-
405- return ONLP_STATUS_OK ;
406486 }
407487 case ONLP_SFP_CONTROL_RESET : {
408488 VALIDATE_QSFP (port );
0 commit comments