diff --git a/cmd_parser.c b/cmd_parser.c index 9e2be41..2b13edd 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -777,11 +777,14 @@ void parse_sfp(void) print_string(" - empty\n"); continue; } + sfp_i2c_fail = 0; print_string(" - Rate: "); print_byte(sfp_read_reg(slot, 12)); print_string(" Encoding: "); print_byte(sfp_read_reg(slot, 11)); write_char('\n'); sfp_print_info(slot); sfp_print_measurements(slot); + if (sfp_i2c_fail) + print_string("I2C read failed on this slot\n"); } return; } diff --git a/rtl837x_common.h b/rtl837x_common.h index 66df88a..98202b8 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -150,6 +150,7 @@ void write_char_no_syslog(char c); void write_char(char c); void print_reg(uint16_t reg); uint8_t sfp_read_reg(uint8_t slot, uint8_t reg); +extern __xdata uint8_t sfp_i2c_fail; void reg_bit_set(uint16_t reg_addr, char bit); void reg_bit_clear(uint16_t reg_addr, char bit); uint8_t reg_bit_test(uint16_t reg_addr, char bit); diff --git a/rtlplayground.c b/rtlplayground.c index bdb8ab3..f8cd721 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -139,6 +139,7 @@ __xdata char sfp_module_vendor[2][17]; __xdata char sfp_module_model[2][17]; __xdata char sfp_module_serial[2][17]; __xdata uint8_t sfp_options[2]; +__xdata uint8_t sfp_i2c_fail; /* set by sfp_read_reg() when the controller flags a failed transfer */ __xdata uint8_t sfp_speed[2]; __xdata uint8_t sfp_quirks[2]; __xdata bool button_last; @@ -1061,6 +1062,14 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg) reg_read_m(RTL837X_REG_I2C_CTRL); } while (sfr_data[3] & 0x1); + /* Bit 1 is the controller's own failure indication, which the vendor SDK + * looks at and this did not. Without it an unacknowledged address comes + * back as an ordinary byte and the caller cannot tell it from data. */ + if (sfr_data[3] & 0x2) { + sfp_i2c_fail = 1; + return 0xff; + } + reg_read_m(RTL837X_REG_I2C_OUT); return sfr_data[3]; } @@ -1300,6 +1309,7 @@ void handle_sfp(void) // Read Reg 11: Encoding, see SFF-8472 and SFF-8024 // Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit delay(100); // Delay, because some modules need time to wake up + sfp_i2c_fail = 0; uint8_t rate = sfp_read_reg(sfp, 12); if (sfp_speed[sfp] == SFP_SPEED_100M) rate = 0x1; @@ -1316,6 +1326,8 @@ void handle_sfp(void) sfp_options[sfp] = sfp_read_reg(sfp, 92); sfp_get_info(sfp); sfp_apply_quirks(sfp); + if (sfp_i2c_fail) + print_string("SFP: an I2C read failed, the module data above may be wrong\n"); sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate)); } } else {