Add SFP quirk for devices that misreport DDM capability

On a QSFPTEK QT-SFP+-T (RTL8261C) 10GBase-T module, the diag type field
(92) comes back as 0x00, but there's actually some statistics available
like temperature. Other metrics may be hard-coded values.

Add a basic struct that allows matching on vendor and/or model, using a
bitfield to allow multiple quirks for a given SFP module. Only
SFP_QUIRK_DDM is implemented.

For modules matching SFP_QUIRK_DDM, attempt an I2C read of the MSB of
module voltage during probe if DDM is "unsupported" - if it's not 0xff,
override the reported options so we can pull the diagnostic data.

To allow simpler comparisons, convert the ASCII fields (vendor,
model, serial) from space-padded to standard NULL-terminated strings.

strcmp() is moved from httpd.c to rtlplayground.c alongside other string
functions and shared between them.

The __reentrant keyword is used for the new functions to avoid using up
additional OSEG space. This allocates the variables on the stack, which
is OK for this particular code path.

The JSON assembly in send_status() is slightly modified to treat the
sfp_module_* data as standard NULL-terminated strings, and a repeated
subtraction was moved into a uint8_t to declutter the code.
This commit is contained in:
Matt Merhar
2026-07-13 01:31:29 -04:00
parent 05d8c36afe
commit 2221f0fa32
5 changed files with 96 additions and 49 deletions
+2 -1
View File
@@ -50,6 +50,7 @@ __xdata char port_names[9][PORT_NAME_SIZE];
extern __xdata uint16_t management_vlan;
extern __xdata uint8_t sfp_speed[2];
extern __xdata uint8_t sfp_pins_last;
extern __xdata uint8_t sfp_options[2];
__xdata uint8_t gpio_last_value[8] = { 0 };
// Temporatly for str to hex convertion value.
@@ -741,7 +742,7 @@ void parse_mtu(void)
void sfp_print_measurements(uint8_t sfp)
{
print_string("Options: "); print_byte(sfp_read_reg(sfp, 92)); write_char('\n');
if (!(sfp_read_reg(sfp, 92) & 0x40))
if (!(sfp_options[sfp] & 0x40))
return;
print_string("Temp: "); print_byte(sfp_read_reg(sfp, 224)); print_byte(sfp_read_reg(sfp, 225)); write_char('\n');
print_string("Vcc: "); print_byte(sfp_read_reg(sfp, 226)); print_byte(sfp_read_reg(sfp, 227)); write_char('\n');