mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #280 from tofurky/ddm_broken_module
Add SFP quirk for devices that misreport DDM capability
This commit is contained in:
+2
-1
@@ -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');
|
||||
|
||||
@@ -101,21 +101,6 @@ uint8_t find_entry(__xdata uint8_t *e)
|
||||
}
|
||||
|
||||
|
||||
char strcmp(__xdata uint8_t *c, __code uint8_t * __xdata d)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
while (d[i] && (d[i] == c[i]))
|
||||
i++;
|
||||
|
||||
if (c[i] < d[i])
|
||||
return -1;
|
||||
else if (c[i] > d[i])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool is_word(__xdata uint8_t *xdata_str_p, __code uint8_t * __xdata code_str_p)
|
||||
{
|
||||
uint8_t u, c;
|
||||
|
||||
+25
-24
@@ -660,52 +660,53 @@ void send_status(void)
|
||||
slen += strtox(outbuf + slen, "\"");
|
||||
|
||||
if (machine.is_sfp[i]) {
|
||||
uint8_t sfp = machine.is_sfp[i] - 1;
|
||||
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
|
||||
if (!(sfp_pins_last & (0x1 << ((machine.is_sfp[i] - 1) << 2)))) {
|
||||
if (!(sfp_pins_last & (0x1 << (sfp << 2)))) {
|
||||
bool_to_html(1);
|
||||
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
|
||||
byte_to_html(sfp_options[machine.is_sfp[i]-1]);
|
||||
if (sfp_options[machine.is_sfp[i]-1] & 0x40) {
|
||||
byte_to_html(sfp_options[sfp]);
|
||||
if (sfp_options[sfp] & 0x40) {
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 224, 2);
|
||||
sfp_send_data(sfp, 224, 2);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_vcc\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 226, 2);
|
||||
sfp_send_data(sfp, 226, 2);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_txbias\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 228, 2);
|
||||
sfp_send_data(sfp, 228, 2);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_txpower\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 230, 2);
|
||||
sfp_send_data(sfp, 230, 2);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 232, 2);
|
||||
if (sfp_options[machine.is_sfp[i]-1] & 0x10) {
|
||||
sfp_send_data(sfp, 232, 2);
|
||||
if (sfp_options[sfp] & 0x10) {
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_temp_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 212, 4);
|
||||
sfp_send_data(sfp, 212, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_vcc_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 216, 4);
|
||||
sfp_send_data(sfp, 216, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_txbias_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 204, 4);
|
||||
sfp_send_data(sfp, 204, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_txpower_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 208, 4);
|
||||
sfp_send_data(sfp, 208, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_rxpower_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 184, 16);
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 200, 4);
|
||||
sfp_send_data(sfp, 184, 16);
|
||||
sfp_send_data(sfp, 200, 4);
|
||||
}
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 238, 1);
|
||||
sfp_send_data(sfp, 238, 1);
|
||||
}
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_vendor\":\"");
|
||||
for (register uint8_t s = 0; s < 16; s++)
|
||||
outbuf[slen++] = sfp_module_vendor[machine.is_sfp[i]-1][s];
|
||||
for (register uint8_t s = 0; s < 16 && sfp_module_vendor[sfp][s]; s++)
|
||||
outbuf[slen++] = sfp_module_vendor[sfp][s];
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_model\":\"");
|
||||
for (register uint8_t s = 0; s < 16; s++)
|
||||
outbuf[slen++] = sfp_module_model[machine.is_sfp[i]-1][s];
|
||||
for (register uint8_t s = 0; s < 16 && sfp_module_model[sfp][s]; s++)
|
||||
outbuf[slen++] = sfp_module_model[sfp][s];
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
|
||||
for (register uint8_t s = 0; s < 16; s++)
|
||||
outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s];
|
||||
for (register uint8_t s = 0; s < 16 && sfp_module_serial[sfp][s]; s++)
|
||||
outbuf[slen++] = sfp_module_serial[sfp][s];
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
|
||||
if (machine.sfp_port[machine.is_sfp[i]-1].pin_los == GPIO_NA) {
|
||||
if (machine.sfp_port[sfp].pin_los == GPIO_NA) {
|
||||
slen += strtox(outbuf + slen,"null");
|
||||
} else {
|
||||
bool_to_html(sfp_pins_last & (0x2 << (((machine.is_sfp[i]-1) << 2))));
|
||||
bool_to_html(sfp_pins_last & (0x2 << (sfp << 2)));
|
||||
}
|
||||
} else {
|
||||
bool_to_html(0);
|
||||
|
||||
@@ -158,6 +158,7 @@ uint16_t strlen(register __code const char *s);
|
||||
uint16_t strlen_x(register __xdata const char *s);
|
||||
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
||||
uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
||||
char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b);
|
||||
void tcpip_output(void);
|
||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||
void get_random_32(void);
|
||||
|
||||
+68
-9
@@ -138,10 +138,25 @@ __xdata char sfp_module_model[2][17];
|
||||
__xdata char sfp_module_serial[2][17];
|
||||
__xdata uint8_t sfp_options[2];
|
||||
__xdata uint8_t sfp_speed[2];
|
||||
__xdata uint8_t sfp_quirks[2];
|
||||
__xdata bool button_last;
|
||||
__xdata uint8_t button_sec_counter_last;
|
||||
volatile __bit tx_buf_empty;
|
||||
|
||||
__code enum sfp_quirk {
|
||||
SFP_QUIRK_DDM = (1 << 0),
|
||||
};
|
||||
|
||||
struct sfp_quirk_entry {
|
||||
__code char *vendor; // Set vendor or model to 0 to act as wildcard
|
||||
__code char *model;
|
||||
uint8_t quirks;
|
||||
};
|
||||
|
||||
static __code struct sfp_quirk_entry sfp_quirk_table[] = {
|
||||
{ "QSFPTEK", "QT-SFP+-T", SFP_QUIRK_DDM },
|
||||
};
|
||||
|
||||
struct eth_in {
|
||||
struct uip_eth_addr dst;
|
||||
struct uip_eth_addr src;
|
||||
@@ -327,6 +342,21 @@ uint16_t strlen_x(register __xdata const char *s)
|
||||
}
|
||||
|
||||
|
||||
char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
while (b[i] && (b[i] == a[i]))
|
||||
i++;
|
||||
|
||||
if (a[i] < b[i])
|
||||
return -1;
|
||||
else if (a[i] > b[i])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_short(uint16_t a)
|
||||
{
|
||||
// allocating the registers first improves the sdcc code here
|
||||
@@ -1199,18 +1229,46 @@ void sfp_print_info(uint8_t sfp)
|
||||
print_string("\n");
|
||||
}
|
||||
|
||||
// Normalize strings from EEPROM by removing any trailing spaces; this allows simpler comparisons
|
||||
void sfp_read_field(__xdata char *dst, uint8_t sfp, uint8_t start, uint8_t length) __reentrant
|
||||
{
|
||||
dst[length] = '\0';
|
||||
|
||||
for (uint8_t i = 0; i < length; i++)
|
||||
dst[i] = sfp_read_reg(sfp, start + i);
|
||||
|
||||
while (length > 0 && dst[--length] == ' ')
|
||||
dst[length] = '\0';
|
||||
}
|
||||
|
||||
void sfp_get_info(uint8_t sfp)
|
||||
{
|
||||
for (uint8_t i = 20; i < 36; i++)
|
||||
sfp_module_vendor[sfp][i-20] = sfp_read_reg(sfp, i);
|
||||
sfp_module_vendor[sfp][16] = '\0';
|
||||
for (uint8_t i = 40; i < 56; i++)
|
||||
sfp_module_model[sfp][i-40] = sfp_read_reg(sfp, i);
|
||||
sfp_module_model[sfp][16] = '\0';
|
||||
for (uint8_t i = 68; i < 84; i++)
|
||||
sfp_module_serial[sfp][i-68] = sfp_read_reg(sfp, i);
|
||||
sfp_module_serial[sfp][16] = '\0';
|
||||
sfp_read_field(sfp_module_vendor[sfp], sfp, 20, 16);
|
||||
sfp_read_field(sfp_module_model[sfp], sfp, 40, 16);
|
||||
sfp_read_field(sfp_module_serial[sfp], sfp, 68, 16);
|
||||
}
|
||||
|
||||
void sfp_apply_quirks(uint8_t sfp) __reentrant
|
||||
{
|
||||
sfp_quirks[sfp] = 0;
|
||||
|
||||
for (uint8_t i = 0; i < sizeof(sfp_quirk_table) / sizeof(*sfp_quirk_table); i++) {
|
||||
if (!sfp_quirk_table[i].vendor || !strcmp(sfp_module_vendor[sfp], sfp_quirk_table[i].vendor)) {
|
||||
if (!sfp_quirk_table[i].model || !strcmp(sfp_module_model[sfp], sfp_quirk_table[i].model)) {
|
||||
sfp_quirks[sfp] |= sfp_quirk_table[i].quirks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sfp_quirks[sfp] & SFP_QUIRK_DDM) {
|
||||
if (!(sfp_options[sfp] & 0x40)) {
|
||||
// The module reports that DDM is not implemented, but try a dummy read to confirm
|
||||
// 0xff would mean a failed I2C read or an impossible (per spec) voltage greater than 6.5V
|
||||
if (sfp_read_reg(sfp, 226) != 0xff) {
|
||||
sfp_options[sfp] |= 0x40;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1255,6 +1313,7 @@ void handle_sfp(void)
|
||||
print_string("\n");
|
||||
sfp_options[sfp] = sfp_read_reg(sfp, 92);
|
||||
sfp_get_info(sfp);
|
||||
sfp_apply_quirks(sfp);
|
||||
sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate));
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user