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 uint16_t management_vlan;
|
||||||
extern __xdata uint8_t sfp_speed[2];
|
extern __xdata uint8_t sfp_speed[2];
|
||||||
extern __xdata uint8_t sfp_pins_last;
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
|
extern __xdata uint8_t sfp_options[2];
|
||||||
__xdata uint8_t gpio_last_value[8] = { 0 };
|
__xdata uint8_t gpio_last_value[8] = { 0 };
|
||||||
|
|
||||||
// Temporatly for str to hex convertion value.
|
// Temporatly for str to hex convertion value.
|
||||||
@@ -741,7 +742,7 @@ void parse_mtu(void)
|
|||||||
void sfp_print_measurements(uint8_t sfp)
|
void sfp_print_measurements(uint8_t sfp)
|
||||||
{
|
{
|
||||||
print_string("Options: "); print_byte(sfp_read_reg(sfp, 92)); write_char('\n');
|
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;
|
return;
|
||||||
print_string("Temp: "); print_byte(sfp_read_reg(sfp, 224)); print_byte(sfp_read_reg(sfp, 225)); write_char('\n');
|
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');
|
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)
|
bool is_word(__xdata uint8_t *xdata_str_p, __code uint8_t * __xdata code_str_p)
|
||||||
{
|
{
|
||||||
uint8_t u, c;
|
uint8_t u, c;
|
||||||
|
|||||||
+25
-24
@@ -660,52 +660,53 @@ void send_status(void)
|
|||||||
slen += strtox(outbuf + slen, "\"");
|
slen += strtox(outbuf + slen, "\"");
|
||||||
|
|
||||||
if (machine.is_sfp[i]) {
|
if (machine.is_sfp[i]) {
|
||||||
|
uint8_t sfp = machine.is_sfp[i] - 1;
|
||||||
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
|
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);
|
bool_to_html(1);
|
||||||
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
|
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
|
||||||
byte_to_html(sfp_options[machine.is_sfp[i]-1]);
|
byte_to_html(sfp_options[sfp]);
|
||||||
if (sfp_options[machine.is_sfp[i]-1] & 0x40) {
|
if (sfp_options[sfp] & 0x40) {
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x");
|
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");
|
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");
|
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");
|
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");
|
slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x");
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 232, 2);
|
sfp_send_data(sfp, 232, 2);
|
||||||
if (sfp_options[machine.is_sfp[i]-1] & 0x10) {
|
if (sfp_options[sfp] & 0x10) {
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_temp_cal\":\"0x");
|
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");
|
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");
|
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");
|
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");
|
slen += strtox(outbuf + slen,"\",\"sfp_rxpower_cal\":\"0x");
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 184, 16);
|
sfp_send_data(sfp, 184, 16);
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 200, 4);
|
sfp_send_data(sfp, 200, 4);
|
||||||
}
|
}
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x");
|
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\":\"");
|
slen += strtox(outbuf + slen,"\",\"sfp_vendor\":\"");
|
||||||
for (register uint8_t s = 0; s < 16; s++)
|
for (register uint8_t s = 0; s < 16 && sfp_module_vendor[sfp][s]; s++)
|
||||||
outbuf[slen++] = sfp_module_vendor[machine.is_sfp[i]-1][s];
|
outbuf[slen++] = sfp_module_vendor[sfp][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_model\":\"");
|
slen += strtox(outbuf + slen,"\",\"sfp_model\":\"");
|
||||||
for (register uint8_t s = 0; s < 16; s++)
|
for (register uint8_t s = 0; s < 16 && sfp_module_model[sfp][s]; s++)
|
||||||
outbuf[slen++] = sfp_module_model[machine.is_sfp[i]-1][s];
|
outbuf[slen++] = sfp_module_model[sfp][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
|
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
|
||||||
for (register uint8_t s = 0; s < 16; s++)
|
for (register uint8_t s = 0; s < 16 && sfp_module_serial[sfp][s]; s++)
|
||||||
outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s];
|
outbuf[slen++] = sfp_module_serial[sfp][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
|
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");
|
slen += strtox(outbuf + slen,"null");
|
||||||
} else {
|
} else {
|
||||||
bool_to_html(sfp_pins_last & (0x2 << (((machine.is_sfp[i]-1) << 2))));
|
bool_to_html(sfp_pins_last & (0x2 << (sfp << 2)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool_to_html(0);
|
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 strlen_x(register __xdata const char *s);
|
||||||
uint16_t strtox(register __xdata uint8_t *dst, register __code 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);
|
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);
|
void tcpip_output(void);
|
||||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||||
void get_random_32(void);
|
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 char sfp_module_serial[2][17];
|
||||||
__xdata uint8_t sfp_options[2];
|
__xdata uint8_t sfp_options[2];
|
||||||
__xdata uint8_t sfp_speed[2];
|
__xdata uint8_t sfp_speed[2];
|
||||||
|
__xdata uint8_t sfp_quirks[2];
|
||||||
__xdata bool button_last;
|
__xdata bool button_last;
|
||||||
__xdata uint8_t button_sec_counter_last;
|
__xdata uint8_t button_sec_counter_last;
|
||||||
volatile __bit tx_buf_empty;
|
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 eth_in {
|
||||||
struct uip_eth_addr dst;
|
struct uip_eth_addr dst;
|
||||||
struct uip_eth_addr src;
|
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)
|
void print_short(uint16_t a)
|
||||||
{
|
{
|
||||||
// allocating the registers first improves the sdcc code here
|
// allocating the registers first improves the sdcc code here
|
||||||
@@ -1199,18 +1229,46 @@ void sfp_print_info(uint8_t sfp)
|
|||||||
print_string("\n");
|
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)
|
void sfp_get_info(uint8_t sfp)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 20; i < 36; i++)
|
sfp_read_field(sfp_module_vendor[sfp], sfp, 20, 16);
|
||||||
sfp_module_vendor[sfp][i-20] = sfp_read_reg(sfp, i);
|
sfp_read_field(sfp_module_model[sfp], sfp, 40, 16);
|
||||||
sfp_module_vendor[sfp][16] = '\0';
|
sfp_read_field(sfp_module_serial[sfp], sfp, 68, 16);
|
||||||
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';
|
void sfp_apply_quirks(uint8_t sfp) __reentrant
|
||||||
for (uint8_t i = 68; i < 84; i++)
|
{
|
||||||
sfp_module_serial[sfp][i-68] = sfp_read_reg(sfp, i);
|
sfp_quirks[sfp] = 0;
|
||||||
sfp_module_serial[sfp][16] = '\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");
|
print_string("\n");
|
||||||
sfp_options[sfp] = sfp_read_reg(sfp, 92);
|
sfp_options[sfp] = sfp_read_reg(sfp, 92);
|
||||||
sfp_get_info(sfp);
|
sfp_get_info(sfp);
|
||||||
|
sfp_apply_quirks(sfp);
|
||||||
sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate));
|
sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user