mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Merge remote-tracking branch 'origin/main' into feat/session-timeout-config
This commit is contained in:
commit
4a7fd7a098
71 files changed
+3075
-477
No files matched your search
+264
-71
@@ -5,6 +5,8 @@
|
||||
// #define DEBUG
|
||||
// #define REGDBG 1
|
||||
|
||||
#include <8051.h>
|
||||
#include "cmd_parser.h"
|
||||
#include "rtl837x_common.h"
|
||||
#include "rtl837x_port.h"
|
||||
#include "rtl837x_flash.h"
|
||||
@@ -26,15 +28,15 @@
|
||||
#pragma codeseg BANK2
|
||||
#pragma constseg BANK2
|
||||
|
||||
extern __code struct machine machine;
|
||||
extern __code const struct machine machine;
|
||||
extern __xdata bool stp_enabled;
|
||||
extern __code uint8_t log_to_phys_port[9];
|
||||
extern __code const uint8_t log_to_phys_port[9];
|
||||
|
||||
extern volatile __xdata uint32_t ticks;
|
||||
extern volatile __xdata uint8_t sfr_data[4];
|
||||
|
||||
extern __code uint8_t * __code greeting;
|
||||
extern __code uint8_t * __code hex;
|
||||
extern __code const uint8_t * __code const greeting;
|
||||
extern __code const uint8_t * __code const hex;
|
||||
|
||||
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
||||
extern __xdata struct flash_region_t flash_region;
|
||||
@@ -61,7 +63,6 @@ __xdata uint8_t hexvalue[4] = { 0 };
|
||||
|
||||
// Buffer for writing to flash 0x1fd000, copy to 0x1fe000
|
||||
__xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||
__xdata uint8_t cmd_available;
|
||||
|
||||
__xdata char save_cmd;
|
||||
|
||||
@@ -107,7 +108,7 @@ inline uint8_t isnumber(uint8_t l)
|
||||
return (l <= ('9'-'0'));
|
||||
}
|
||||
|
||||
uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd)
|
||||
uint8_t cmd_compare(uint8_t start, __code const uint8_t * cmd)
|
||||
{
|
||||
if (cmd_words_len == 0 || start > (cmd_words_len - 1)) {
|
||||
return 0;
|
||||
@@ -428,6 +429,22 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cmd_error(__code const char *msg)
|
||||
{
|
||||
err_status = ERR_INVALID_ARGUMENT;
|
||||
print_string("Error: ");
|
||||
print_string(msg);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t name_char(uint8_t c)
|
||||
{
|
||||
if (c < 0x20 || c > 0x7e || c == '"' || c == '\\')
|
||||
return '.';
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// Sets the management MAC from a "mac <aa:bb:cc:dd:ee:ff>" command (or prints
|
||||
// the current one with a bare "mac"). Refuses blank/multicast/locally
|
||||
// administered/all-zero-OUI addresses so the running MAC stays reachable, and
|
||||
@@ -443,11 +460,11 @@ void parse_mac_cmd(void)
|
||||
return;
|
||||
}
|
||||
if (cmd_words_len != 2 || !parse_mac(cmd_words_b[1])) {
|
||||
print_string("Error: mac [<aa:bb:cc:dd:ee:ff>]\n");
|
||||
cmd_error("mac [<aa:bb:cc:dd:ee:ff>]\n");
|
||||
return;
|
||||
}
|
||||
if ((mac_parse_result[0] & 0x03) || ((mac_parse_result[0] | mac_parse_result[1] | mac_parse_result[2]) == 0)) {
|
||||
print_string("refusing: must be unicast, globally administered\n");
|
||||
cmd_error("the MAC must be unicast and globally administered\n");
|
||||
return;
|
||||
}
|
||||
if (memcmp(mac_parse_result, uip_ethaddr.addr, 6) == 0) {
|
||||
@@ -525,7 +542,7 @@ void parse_lag(void)
|
||||
port_lag_members_set(group, members);
|
||||
return;
|
||||
err:
|
||||
print_string("Error: lag (show | <1-4> (d | <port>...))\n");
|
||||
cmd_error("lag (show | <1-4> (d | <port>...))\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -567,7 +584,7 @@ void parse_lag_hash(void)
|
||||
port_lag_hash_set(group, hash);
|
||||
return;
|
||||
err:
|
||||
print_string("Error: laghash <1-4> [smac|dmac|sip|dip|sport|dport]\n");
|
||||
cmd_error("laghash <1-4> [smac|dmac|sip|dip|sport|dport]\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -621,7 +638,7 @@ void parse_vlan(void)
|
||||
*vlan_str++ = hex[(vlan_settings.vlan >> 4) & 0xf] ;
|
||||
*vlan_str++ = hex[vlan_settings.vlan & 0xf];
|
||||
while(!cmd_is_space_or_nul(pos)) {
|
||||
uint8_t c = cmd_buffer[pos++];
|
||||
uint8_t c = name_char(cmd_buffer[pos++]);
|
||||
write_char(c);
|
||||
*vlan_str++ = c;
|
||||
}
|
||||
@@ -665,7 +682,7 @@ void parse_vlan(void)
|
||||
}
|
||||
return;
|
||||
err:
|
||||
print_string("Error: vlan (<vlan-id>|show) [port][t]...\n");
|
||||
cmd_error("vlan (<vlan-id>|show) [port][t]...\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -716,7 +733,7 @@ void parse_isolate(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("Error: isolate <port> [show|off] [port]...\n");
|
||||
cmd_error("isolate <port> [show|off] [port]...\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -753,7 +770,7 @@ void parse_ingress(void)
|
||||
// Setting mode for all ports at once
|
||||
for (log_port = machine.min_port; log_port <= machine.max_port; log_port++) {
|
||||
if (!port_ingress_filter(log_port, mode)) {
|
||||
print_string("Error setting ingress filter for port "); print_phys_port(log_port); write_char('\n');
|
||||
cmd_error("cannot set the ingress filter for port "); print_phys_port(log_port); write_char('\n');
|
||||
return;
|
||||
}
|
||||
print_string("All ports ingress filter set to: ");
|
||||
@@ -764,18 +781,18 @@ void parse_ingress(void)
|
||||
idx = cmd_words_b[w];
|
||||
uint8_t ret = cmd_parse_port(idx);
|
||||
if (ret != 1) {
|
||||
print_string("Invalid physical port number\n");
|
||||
cmd_error("Invalid physical port number\n");
|
||||
continue;
|
||||
}
|
||||
log_port = atoi_results_u8;
|
||||
idx += ret;
|
||||
|
||||
if (!vlan_ingress_mode_parse(cmd_buffer[idx++], &mode) || !cmd_is_space_or_nul(idx)) {
|
||||
print_string("Invalid ingress mode for port "); print_phys_port(log_port); print_string(" in ingress command\n");
|
||||
cmd_error("Invalid ingress mode for port "); print_phys_port(log_port); print_string(" in ingress command\n");
|
||||
goto err;
|
||||
}
|
||||
if (!port_ingress_filter(log_port, mode)) {
|
||||
print_string("Error setting ingress filter for port "); print_phys_port(log_port); write_char('\n');
|
||||
cmd_error("cannot set the ingress filter for port "); print_phys_port(log_port); write_char('\n');
|
||||
return;
|
||||
}
|
||||
print_string("Port "); print_phys_port(log_port);
|
||||
@@ -785,7 +802,7 @@ void parse_ingress(void)
|
||||
}
|
||||
return;
|
||||
err:
|
||||
print_string("Error: ingress [p]<u/t/a>...\n");
|
||||
cmd_error("ingress [p]<u/t/a>...\n");
|
||||
}
|
||||
|
||||
void parse_mirror(void)
|
||||
@@ -850,7 +867,7 @@ void parse_mirror(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("Port/command missing: mirror [status/off/<mirroring port> [port][t/r]]...\n");
|
||||
cmd_error("Port/command missing: mirror [status/off/<mirroring port> [port][t/r]]...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -858,7 +875,7 @@ err:
|
||||
void parse_port(void)
|
||||
{
|
||||
if (cmd_words_len < 3) {
|
||||
print_string("\nUsage:" \
|
||||
cmd_error("\nUsage:" \
|
||||
"\nport <port> [show|on|off]" \
|
||||
"\nport <port> [10m|100m|1g|2g5|duplex] [half|full]" \
|
||||
"\nport <port> name [custom port name]\n");
|
||||
@@ -866,7 +883,7 @@ void parse_port(void)
|
||||
}
|
||||
|
||||
if (cmd_parse_port_separator(cmd_words_b[1]) == 0) {
|
||||
print_string("Invalid port number\n");
|
||||
cmd_error("Invalid port number\n");
|
||||
return;
|
||||
}
|
||||
phy_settings.port = atoi_results_u8;
|
||||
@@ -879,11 +896,14 @@ void parse_port(void)
|
||||
print_string_x(port_names[phy_settings.port]);
|
||||
if (!machine.is_sfp[phy_settings.port]) {
|
||||
phy_show(phy_settings.port);
|
||||
} else {
|
||||
write_char('\n');
|
||||
}
|
||||
port_media_show(phy_settings.port);
|
||||
} else if (cmd_compare(2, "name")) {
|
||||
uint8_t i = 0;
|
||||
while ( (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != NUL) ) {
|
||||
port_names[phy_settings.port][i] = cmd_buffer[cmd_words_b[3] + i];
|
||||
while ( cmd_words_len > 3 && (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != NUL) ) {
|
||||
port_names[phy_settings.port][i] = name_char(cmd_buffer[cmd_words_b[3] + i]);
|
||||
i++;
|
||||
}
|
||||
port_names[phy_settings.port][i] = NUL;
|
||||
@@ -944,7 +964,7 @@ void parse_port(void)
|
||||
phy_settings.duplex = PHY_DUPLEX_HALF;
|
||||
phy_set_duplex();
|
||||
} else {
|
||||
print_string("Unknown port command\n");
|
||||
cmd_error("Unknown port command\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,7 +992,7 @@ void parse_mtu(void)
|
||||
print_byte(p);
|
||||
|
||||
if (atoi_short(cmd_words_b[2]) == 0 || atoi_results_short < 64 || atoi_results_short > 0x3fff) {
|
||||
print_string("MTU must be 64..16383\n");
|
||||
cmd_error("MTU must be 64..16383\n");
|
||||
return;
|
||||
}
|
||||
REG_WRITE(RTL8373_REG_MAC_L2_PORT_MAX_LEN + ((uint16_t) p << 8), (atoi_results_short >> 10) & 0xf, (atoi_results_short >> 2) & 0xff,
|
||||
@@ -981,7 +1001,7 @@ void parse_mtu(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("mtu [port] [size]\n");
|
||||
cmd_error("mtu [port] [size]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1038,11 +1058,11 @@ void parse_sfp(void)
|
||||
idx += ret;
|
||||
slot = atoi_results_u8 - 1;
|
||||
if (ret == 0 || !cmd_is_space(idx) || slot > 1) {
|
||||
print_string("Illegal SFP slot number\n");
|
||||
cmd_error("Illegal SFP slot number\n");
|
||||
return;
|
||||
}
|
||||
if (slot >= machine.n_sfp) {
|
||||
print_string("SFP slot not present\n");
|
||||
cmd_error("SFP slot not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1068,7 +1088,7 @@ void parse_sfp(void)
|
||||
handle_sfp();
|
||||
return;
|
||||
err:
|
||||
print_string("\nUsage:\n\tsfp\n\tsfp [1|2] [1g|2g5|10g]\n");
|
||||
cmd_error("\nUsage:\n\tsfp\n\tsfp [1|2] [1g|2g5|10g]\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1100,7 +1120,7 @@ void parse_regget(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: regget <hexvalue>\n\tlike: regget 0BB0 or regget 0c");
|
||||
cmd_error("regget <hexvalue>\n\tlike: regget 0BB0 or regget 0c");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1147,7 +1167,7 @@ void parse_regset(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: regset <hexvalue> <hexvalue>\n\tlike regset 0b abcd1234.");
|
||||
cmd_error("regset <hexvalue> <hexvalue>\n\tlike regset 0b abcd1234.");
|
||||
}
|
||||
|
||||
|
||||
@@ -1190,7 +1210,7 @@ void parse_sdsget(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: sdsget <sds-id> <hex:page> <hex:reg>\n");
|
||||
cmd_error("sdsget <sds-id> <hex:page> <hex:reg>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1246,7 +1266,7 @@ void parse_sdsset(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: sdsset <sds-id> <hex:page> <hex:reg> <hex:val>\n");
|
||||
cmd_error("sdsset <sds-id> <hex:page> <hex:reg> <hex:val>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1295,7 +1315,7 @@ void parse_phyget(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: phyget <phy-id> <dev-id> <hex:reg>\n");
|
||||
cmd_error("phyget <phy-id> <dev-id> <hex:reg>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1355,7 +1375,7 @@ void parse_physet(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: physet <phy-id> <dev-id> <hex:reg> <hex:val>\n");
|
||||
cmd_error("physet <phy-id> <dev-id> <hex:reg> <hex:val>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1390,7 +1410,7 @@ void parse_passwd(void)
|
||||
passwd[j] = NUL;
|
||||
return;
|
||||
}
|
||||
print_string("Missing password\n");
|
||||
cmd_error("Missing password\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1413,8 +1433,8 @@ void parse_eee(void)
|
||||
speed_word = 2;
|
||||
} else if (cmd_is_space_or_nul(idx)) {
|
||||
// Word 2 is a port number
|
||||
if (cmd_parse_port_separator(idx) == 0) {
|
||||
print_string("Speed word invalid, use: [100m|1g|2g5]\n");
|
||||
if (cmd_parse_port_separator(cmd_words_b[2]) == 0) {
|
||||
cmd_error("Speed word invalid, use: [100m|1g|2g5]\n");
|
||||
return;
|
||||
}
|
||||
port = atoi_results_u8;
|
||||
@@ -1433,7 +1453,7 @@ void parse_eee(void)
|
||||
speed = EEE_2G5;
|
||||
else
|
||||
{
|
||||
print_string("Speed word invalid, use: [100m|1g|2g5]\n");
|
||||
cmd_error("Speed word invalid, use: [100m|1g|2g5]\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1453,7 +1473,7 @@ void parse_eee(void)
|
||||
else
|
||||
port_eee_status_all();
|
||||
} else {
|
||||
print_string("eee [on|off|status] [port] [100m|1g|2g5]\n");
|
||||
cmd_error("eee [on|off|status] [port] [100m|1g|2g5]\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1524,7 +1544,7 @@ void parse_bw(void)
|
||||
return;
|
||||
|
||||
err:
|
||||
print_string("usage: bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
||||
cmd_error("bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
||||
}
|
||||
|
||||
void parse_syslog(void)
|
||||
@@ -1562,7 +1582,7 @@ void parse_syslog(void)
|
||||
if (was_enabled)
|
||||
syslog_start();
|
||||
} else {
|
||||
print_string("Invalid IP address\n");
|
||||
cmd_error("Invalid IP address\n");
|
||||
}
|
||||
} else if (cmd_compare(1, "port")) {
|
||||
if (cmd_words_len < 3) { // no additional argument -> print current port
|
||||
@@ -1573,7 +1593,7 @@ void parse_syslog(void)
|
||||
/* atoi_short() returns zero for no digits and for a value past
|
||||
* 65535; port zero is not a port either, so both tests are needed. */
|
||||
if (!atoi_short(cmd_words_b[2]) || !atoi_results_short) {
|
||||
print_string("Invalid port\n");
|
||||
cmd_error("Invalid port\n");
|
||||
return;
|
||||
}
|
||||
/* The port is frozen into the connection by uip_udp_new(), so
|
||||
@@ -1589,9 +1609,9 @@ void parse_syslog(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
print_string("Error: syslog [on|off|ip [ip-address]|port [number]]\n");
|
||||
print_string(" on/off enables or disables syslog, ip sets the syslog server IP address,\n");
|
||||
print_string(" port sets the destination UDP port (default 514)\n");
|
||||
cmd_error("syslog [on|off|ip [ip-address]|port [number]]\n"
|
||||
" on/off enables or disables syslog, ip sets the syslog server IP address,\n"
|
||||
" port sets the destination UDP port (default 514)\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1778,7 +1798,7 @@ void cmd_parser(void) __banked
|
||||
print_string("Setting ip: ");
|
||||
print_ip(ip); write_char('\n');
|
||||
} else {
|
||||
print_string("Invalid IP address\n" \
|
||||
cmd_error("Invalid IP address\n" \
|
||||
"Error: ip [<ip-address>|dhcp]\n" \
|
||||
" The dhcp option enables the dhcp client, calling ip without options prints the current IP\n" \
|
||||
" Calling with a valid IP address will stop any ongoing dhcp client and set the IP address\n");
|
||||
@@ -1794,7 +1814,7 @@ void cmd_parser(void) __banked
|
||||
print_string("Setting gw: ");
|
||||
print_ip(ip); write_char('\n');
|
||||
} else {
|
||||
print_string("Invalid IP address\n" \
|
||||
cmd_error("Invalid IP address\n" \
|
||||
"Error: gw <ip-address>\n");
|
||||
}
|
||||
}
|
||||
@@ -1808,7 +1828,7 @@ void cmd_parser(void) __banked
|
||||
print_string("Setting netmask: ");
|
||||
print_ip(ip); write_char('\n');
|
||||
} else {
|
||||
print_string("Invalid IP address\n");
|
||||
cmd_error("Invalid IP address\n");
|
||||
}
|
||||
}
|
||||
write_char('\n');
|
||||
@@ -1824,8 +1844,9 @@ void cmd_parser(void) __banked
|
||||
igmp_setup();
|
||||
else if (cmd_compare(1, "show"))
|
||||
igmp_show();
|
||||
else
|
||||
print_string("Error: igmp on|off|show\n");
|
||||
else {
|
||||
cmd_error("igmp on|off|show\n");
|
||||
}
|
||||
} else if (cmd_compare(0, "mac")) {
|
||||
parse_mac_cmd();
|
||||
} else if (cmd_compare(0, "hostname")) {
|
||||
@@ -1843,22 +1864,25 @@ void cmd_parser(void) __banked
|
||||
uint8_t c = *hp++;
|
||||
if (c == NUL || c == '\r' || c == '\n')
|
||||
break;
|
||||
if (c < 0x20 || c > 0x7e || c == '"' || c == '\\')
|
||||
c = '.';
|
||||
*dst++ = c;
|
||||
*dst++ = name_char(c);
|
||||
}
|
||||
*dst = NUL;
|
||||
} else {
|
||||
print_string("Error: hostname [name] - the name must not contain spaces\n");
|
||||
cmd_error("hostname [name] - the name must not contain spaces\n");
|
||||
}
|
||||
} else if (cmd_compare(0, "stp")) {
|
||||
stp_parse();
|
||||
#ifdef HEALTH
|
||||
} else if (cmd_compare(0, "health")) {
|
||||
health_show();
|
||||
#endif
|
||||
} else if (cmd_compare(0, "pvid")) {
|
||||
if (cmd_words_len == 3 && cmd_parse_port_separator(cmd_words_b[1]) != 0
|
||||
&& atoi_short(cmd_words_b[2]) && atoi_results_short && atoi_results_short <= 4094)
|
||||
port_pvid_set(atoi_results_u8, atoi_results_short);
|
||||
else
|
||||
print_string("Error: pvid <port> <1-4094>\n");
|
||||
else {
|
||||
cmd_error("pvid <port> <1-4094>\n");
|
||||
}
|
||||
} else if (cmd_compare(0, "vlan")) {
|
||||
parse_vlan();
|
||||
} else if (cmd_compare(0, "isolate")) {
|
||||
@@ -1920,11 +1944,11 @@ void cmd_parser(void) __banked
|
||||
parse_session();
|
||||
}
|
||||
else {
|
||||
print_string("Unknown command\n");
|
||||
cmd_error("Unknown command\n");
|
||||
}
|
||||
|
||||
|
||||
if (save_cmd && cmd_words_len) {
|
||||
if (save_cmd && cmd_words_len && err_status == ERR_OK) {
|
||||
// Find end of the cmd-buffer, looking for the NUL-byte.
|
||||
uint8_t i = cmd_words_b[cmd_words_len - 1];
|
||||
do {
|
||||
@@ -1969,6 +1993,7 @@ void execute_config(void) __banked
|
||||
save_cmd = 0;
|
||||
|
||||
uint8_t cmd_idx = 0;
|
||||
uint8_t skipping = 0;
|
||||
do {
|
||||
flash_region.addr = pos;
|
||||
flash_region.len = FLASH_READ_BURST_SIZE;
|
||||
@@ -1979,20 +2004,23 @@ void execute_config(void) __banked
|
||||
do {
|
||||
if (cmd_idx >= (CMD_BUF_SIZE - 1)) {
|
||||
cmd_buffer[cmd_idx] = NUL;
|
||||
print_string("ERROR: Command too long: ");
|
||||
print_string("ERROR: Command too long, skipped: ");
|
||||
print_string_x(cmd_buffer);
|
||||
write_char('\n');
|
||||
err_status = ERR_CMD_TOO_LONG;
|
||||
goto config_done;
|
||||
cmd_idx = 0;
|
||||
skipping = 1;
|
||||
}
|
||||
c = flash_buf[cfg_idx++];
|
||||
if (c == 0 || c == '\n') {
|
||||
cmd_buffer[cmd_idx] = NUL;
|
||||
if (cmd_idx) {
|
||||
cmd_tokenize();
|
||||
if (err_status != ERR_OK)
|
||||
goto config_done;
|
||||
cmd_parser();
|
||||
if (skipping) {
|
||||
skipping = 0;
|
||||
} else {
|
||||
cmd_buffer[cmd_idx] = NUL;
|
||||
if (cmd_idx) {
|
||||
cmd_tokenize();
|
||||
if (err_status == ERR_OK)
|
||||
cmd_parser();
|
||||
}
|
||||
}
|
||||
if (c == 0)
|
||||
goto config_done;
|
||||
@@ -2000,8 +2028,10 @@ void execute_config(void) __banked
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd_buffer[cmd_idx] = c;
|
||||
cmd_idx++;
|
||||
if (!skipping) {
|
||||
cmd_buffer[cmd_idx] = c;
|
||||
cmd_idx++;
|
||||
}
|
||||
} while (cfg_idx);
|
||||
|
||||
pages_left--;
|
||||
@@ -2018,6 +2048,7 @@ config_done:
|
||||
// If a command is too long or can't be tokenized, remaining commands are not executed
|
||||
// Returns the status via `err_status`-variable.
|
||||
void execute_commands(__xdata uint8_t *p) __banked {
|
||||
__xdata uint8_t failed = ERR_OK;
|
||||
err_status = ERR_OK;
|
||||
uint8_t cmd_idx = 0;
|
||||
while (1) {
|
||||
@@ -2028,9 +2059,13 @@ void execute_commands(__xdata uint8_t *p) __banked {
|
||||
if (err_status != ERR_OK)
|
||||
return;
|
||||
cmd_parser();
|
||||
if (failed == ERR_OK)
|
||||
failed = err_status;
|
||||
}
|
||||
if (*p == 0)
|
||||
if (*p == 0) {
|
||||
err_status = failed;
|
||||
return;
|
||||
}
|
||||
cmd_idx = 0;
|
||||
} else {
|
||||
if (cmd_idx < (CMD_BUF_SIZE - 1)) {
|
||||
@@ -2047,3 +2082,161 @@ void execute_commands(__xdata uint8_t *p) __banked {
|
||||
p++;
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef HEALTH
|
||||
/*
|
||||
* Health instrumentation. The counters live in xdata and are fed from the
|
||||
* main loop through the banked entry points below; the "health" command
|
||||
* prints everything in one go. All figures are raw hex, diffing two dumps
|
||||
* gives the rates. Phase times are in system ticks (SYS_TICK_HZ = 200,
|
||||
* 5 ms each); a phase counts as slow when it spans 2 or more ticks.
|
||||
*/
|
||||
extern __xdata uint16_t len_left; /* httpd: bytes still to send of the current file */
|
||||
extern __xdata uint8_t entry; /* httpd: index of the file being sent */
|
||||
|
||||
static __xdata uint32_t health_loops;
|
||||
__xdata uint16_t health_rx_frames;
|
||||
|
||||
static __xdata uint16_t ph_last_t;
|
||||
static __xdata uint8_t ph_max[HEALTH_PHASES];
|
||||
static __xdata uint16_t ph_slow[HEALTH_PHASES];
|
||||
|
||||
/* The ISR increments ticks between the two byte reads of a 16-bit load, so
|
||||
* read until two loads agree. */
|
||||
static uint16_t ticks_lo(void)
|
||||
{
|
||||
uint16_t a, b;
|
||||
a = (uint16_t)ticks;
|
||||
do {
|
||||
b = a;
|
||||
a = (uint16_t)ticks;
|
||||
} while (a != b);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
void health_loop_start(void) __banked
|
||||
{
|
||||
health_loops++;
|
||||
ph_last_t = ticks_lo();
|
||||
}
|
||||
|
||||
|
||||
void health_phase(uint8_t id) __banked
|
||||
{
|
||||
__xdata uint16_t now = ticks_lo();
|
||||
__xdata uint16_t d = now - ph_last_t;
|
||||
ph_last_t = now;
|
||||
if (d > 0xff)
|
||||
d = 0xff;
|
||||
if ((uint8_t)d > ph_max[id])
|
||||
ph_max[id] = d;
|
||||
if (d >= 2)
|
||||
ph_slow[id]++;
|
||||
}
|
||||
|
||||
|
||||
/* Fill the stack area above the current frame with a pattern; the dump scans
|
||||
* for how much of it survived. The 8051 stack grows upward, so everything
|
||||
* above SP is free at this point. Interrupts are held off so an ISR does not
|
||||
* push into the area mid-paint. */
|
||||
void health_stack_paint(void) __banked
|
||||
{
|
||||
__xdata uint8_t from = SP + 4;
|
||||
__xdata uint8_t ea = EA;
|
||||
EA = 0;
|
||||
for (uint8_t i = 0xff; i >= from; i--)
|
||||
*(__idata uint8_t *)i = 0xa5;
|
||||
EA = ea;
|
||||
}
|
||||
|
||||
|
||||
static void ph_line(__code const char *name, uint8_t id)
|
||||
{
|
||||
print_string(name);
|
||||
print_string(" max ");
|
||||
print_byte(ph_max[id]);
|
||||
print_string(" slow ");
|
||||
print_short(ph_slow[id]);
|
||||
write_char('\n');
|
||||
}
|
||||
|
||||
|
||||
void health_show(void) __banked
|
||||
{
|
||||
__xdata uint8_t i;
|
||||
|
||||
print_string("up ");
|
||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||
print_byte(sfr_data[0]); print_byte(sfr_data[1]);
|
||||
print_byte(sfr_data[2]); print_byte(sfr_data[3]);
|
||||
print_string(" ticks ");
|
||||
print_long(ticks);
|
||||
print_string(" loops ");
|
||||
print_long(health_loops);
|
||||
print_string(" rx ");
|
||||
print_short(health_rx_frames);
|
||||
write_char('\n');
|
||||
|
||||
/* Phase timing: max duration seen (ticks of 5 ms) and slow-pass count */
|
||||
ph_line("link", HEALTH_PH_LINK);
|
||||
ph_line("sfp ", HEALTH_PH_SFP);
|
||||
ph_line("rx ", HEALTH_PH_RX);
|
||||
ph_line("tx ", HEALTH_PH_TX);
|
||||
ph_line("stp ", HEALTH_PH_STP);
|
||||
ph_line("cmd ", HEALTH_PH_CMD);
|
||||
|
||||
/* Stack: current depth plus how much of the painted area is untouched */
|
||||
print_string("sp ");
|
||||
print_byte(SP);
|
||||
print_string(" untouched ");
|
||||
i = 0;
|
||||
while (*(__idata uint8_t *)(0xff - i) == 0xa5 && i < 0x86)
|
||||
i++;
|
||||
print_byte(i);
|
||||
write_char('\n');
|
||||
|
||||
/* The TCP connection slot. One on this configuration; a build with more
|
||||
* has to say which slot each line is, so make that a visible decision. */
|
||||
#if UIP_CONNS != 1
|
||||
#error "health: the tcp dump prints a single slot, extend it for UIP_CONNS > 1"
|
||||
#endif
|
||||
i = 0;
|
||||
{
|
||||
print_string("tcp ");
|
||||
print_string("st ");
|
||||
print_byte(uip_conns[i].tcpstateflags);
|
||||
print_string(" tmr ");
|
||||
print_byte(uip_conns[i].timer);
|
||||
print_string(" rtx ");
|
||||
print_byte(uip_conns[i].nrtx);
|
||||
print_string(" rto ");
|
||||
print_byte(uip_conns[i].rto);
|
||||
print_string(" len ");
|
||||
print_short(uip_conns[i].len);
|
||||
print_string(" mss ");
|
||||
print_short(uip_conns[i].mss);
|
||||
write_char('\n');
|
||||
print_string(" lport ");
|
||||
print_short(HTONS(uip_conns[i].lport));
|
||||
print_string(" rport ");
|
||||
print_short(HTONS(uip_conns[i].rport));
|
||||
print_string(" rip ");
|
||||
print_short(HTONS(uip_conns[i].ripaddr[0]));
|
||||
write_char(' ');
|
||||
print_short(HTONS(uip_conns[i].ripaddr[1]));
|
||||
write_char('\n');
|
||||
}
|
||||
|
||||
/* httpd transfer state and the protocol flags */
|
||||
print_string("httpd left ");
|
||||
print_short(len_left);
|
||||
print_string(" entry ");
|
||||
print_byte(entry);
|
||||
print_string(" stp ");
|
||||
print_byte(stp_enabled);
|
||||
print_string(" mvlan ");
|
||||
print_short(management_vlan);
|
||||
write_char('\n');
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user