Skip to content

Commit e505fa5

Browse files
authored
[Accton][as7535-28xb] Enhance TX_DISABLE control function (#127)
* [Accton][as7535-28xb] Enhance TX_DISABLE control function 1. added qsfp tx-disable in onlp_sfpi_control_set/get function 2. added case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL in onlp_sfpi_control_set/get function 3. fixed some comments Signed-off-by: Alex Lai <alex_lai@accton.com> * [Accton][as7535-28xb] Check sfp presence for consistency Signed-off-by: Alex Lai <alex_lai@accton.com> --------- Signed-off-by: Alex Lai <alex_lai@accton.com>
1 parent c3ab18f commit e505fa5

File tree

1 file changed

+105
-25
lines changed
  • packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src

1 file changed

+105
-25
lines changed

packages/platforms/accton/x86-64/as7535-28xb/onlp/builds/x86_64_accton_as7535_28xb/module/src/sfpi.c

Lines changed: 105 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@
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) \
@@ -62,6 +69,24 @@
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
6691
static const int port_bus_index[NUM_OF_SFP_PORT] = {
6792
23, 21, 24, 22, 25, 26, 27, 28, 29, 30,
@@ -87,7 +112,7 @@ int
87112
onlp_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])
259287
int
260288
onlp_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

266294
int
267295
onlp_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

273301
int
274302
onlp_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

280308
int
281309
onlp_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

287315
int
288316
onlp_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);
@@ -369,6 +427,8 @@ int
369427
onlp_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

Comments
 (0)