mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
stp: vendor-style per-port config + status (path cost, p2p, designated info)
Bring the Spanning Tree page in line with a typical managed switch's per-port panel. Configuration gains the full-range path cost (raw 0..200000000, 0 = auto, replacing the old 1000x-scaled byte), a point-to-point admin control (auto/on/off), and the priority is now a 0..240 step-16 dropdown. A new status table shows, per port, the Port State, Role, Designated Bridge / Port ID / Cost (learned from received BPDUs, kept per port and aged via the BPDU age), Operational Edge and Operational Point-to-Point. The designated fields fall back to presenting this switch as the segment's designated bridge when no fresh BPDU has been heard (so a quiet port shows our own bridge-id, as the vendor UIs do). /stp.json carries the packed hex fields plus our own MAC for that fallback. Space: reclaim BANK2 for the above by moving rtl837x_pins to HOME and compacting leds_dump into a register-address table (~800B); bandwidth returns to BANK1. No BANK3 - hardware-verified that PSBANK > 2 crashes this SoC at boot (a bricked unit and an SPI-programmer recovery earlier today); a warning to that effect is now in rtl837x_lldp.c. Hardware-verified: cost 200000000 and p2p off round-trip through the CLI and JSON, the status table populates correctly with STP enabled (all ports Forwarding/Designated, oper-edge and oper-p2p True), LACP 3f/3f and the LAN unaffected. (cherry picked from commit 2ec62072f061dc9e78bc821ba1c297cb6819e206)
This commit is contained in:
+3
-2
@@ -27,10 +27,11 @@ const conf_cmds = [
|
|||||||
/^stp\s+version\s+(rstp|stp)$/,
|
/^stp\s+version\s+(rstp|stp)$/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+(on|off)$/,
|
/^stp\s+port\s+\d{1,2}\s+(on|off)$/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+edge\s+(on|off|auto)$/,
|
/^stp\s+port\s+\d{1,2}\s+edge\s+(on|off|auto)$/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+cost\s+\d{1,3}$/,
|
/^stp\s+port\s+\d{1,2}\s+cost\s+\d{1,9}$/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+prio\s+\d{1,3}$/,
|
/^stp\s+port\s+\d{1,2}\s+prio\s+\d{1,3}$/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+guard\s+(none|bpdu|root)$/,
|
/^stp\s+port\s+\d{1,2}\s+guard\s+(none|bpdu|root)$/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+filter\s+(on|off)$/,
|
/^stp\s+port\s+\d{1,2}\s+filter\s+(on|off)$/,
|
||||||
|
/^stp\s+port\s+\d{1,2}\s+p2p\s+(auto|on|off)$/,
|
||||||
/^igmp\s+(on|off)$/,
|
/^igmp\s+(on|off)$/,
|
||||||
/^mtu\s+\d{1,2}\s+\d+$/,
|
/^mtu\s+\d{1,2}\s+\d+$/,
|
||||||
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
||||||
@@ -55,7 +56,7 @@ const conf_overwrite = [
|
|||||||
/^laghash\b/,
|
/^laghash\b/,
|
||||||
/^isolate\s+\d{1,2}\b/,
|
/^isolate\s+\d{1,2}\b/,
|
||||||
/^stp\s+(prio|hello|maxage|fwd|txhold|version|failsafe)\b/,
|
/^stp\s+(prio|hello|maxage|fwd|txhold|version|failsafe)\b/,
|
||||||
/^stp\s+port\s+\d{1,2}\s+(edge|cost|prio|guard|filter)\b/,
|
/^stp\s+port\s+\d{1,2}\s+(edge|cost|prio|guard|filter|p2p)\b/,
|
||||||
/^igmp\b/,
|
/^igmp\b/,
|
||||||
/^mtu\s+\d{1,2}\b/,
|
/^mtu\s+\d{1,2}\b/,
|
||||||
/^bw\s+(in|out)\s+\d{1,2}\b/,
|
/^bw\s+(in|out)\s+\d{1,2}\b/,
|
||||||
|
|||||||
+8
-2
@@ -29,10 +29,16 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<p style="font-size:small">Changes apply immediately. Edge ports skip the listen period; guard/filter act on received BPDUs.</p>
|
<p style="font-size:small">Changes apply immediately. Edge ports skip the listen period; guard/filter act on received BPDUs.</p>
|
||||||
<h2>Ports</h2>
|
<h2>Port configuration</h2>
|
||||||
<table id="stpPortsTbl">
|
<table id="stpPortsTbl">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Port</th><th>State</th><th>Role</th><th>STP</th><th>Edge</th><th>Cost [k]</th><th>Priority</th><th>Guard</th><th>Filter</th>
|
<th>Port</th><th>State</th><th>Path Cost<br><span style="font-weight:normal;font-size:small">(0 = Auto)</span></th><th>Priority</th><th>Edge Port</th><th>BPDU Filter</th><th>Guard</th><th>Point-to-Point</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h2>Port status</h2>
|
||||||
|
<table id="stpStatTbl">
|
||||||
|
<tr>
|
||||||
|
<th>Port</th><th>Port State</th><th>Role</th><th>Designated Bridge</th><th>Designated Port ID</th><th>Designated Cost</th><th>Oper. Edge</th><th>Oper. P2P</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script src="/stp.js"></script>
|
<script src="/stp.js"></script>
|
||||||
|
|||||||
+45
-27
@@ -1,16 +1,7 @@
|
|||||||
/* Spanning Tree page: full RSTP configuration + live status.
|
|
||||||
*
|
|
||||||
* Every control applies IMMEDIATELY on change (POST /cmd "stp ...") - there is
|
|
||||||
* no per-row Apply. The refresh (2 s) repopulates controls from /stp.json;
|
|
||||||
* a global dirty flag suppresses that between a change and its confirmation
|
|
||||||
* so the refresh never reverts an edit in flight (same lesson as the LAG page).
|
|
||||||
*/
|
|
||||||
|
|
||||||
// STP port states as encoded in the ASIC's MSTP register (2 bits per port)
|
|
||||||
const STP_STATES = ["Disabled", "Blocking", "Learning", "Forwarding"];
|
const STP_STATES = ["Disabled", "Blocking", "Learning", "Forwarding"];
|
||||||
const STP_ROLES = ["-", "Root", "Designated", "Alternate"];
|
const STP_ROLES = ["-", "Root", "Designated", "Alternate"];
|
||||||
|
|
||||||
// stp_pflags bits (keep in sync with rtl837x_stp.h)
|
|
||||||
const PF_ENABLED = 1, PF_ADMEDGE = 2, PF_AUTOEDGE = 4, PF_BPDUGUARD = 8,
|
const PF_ENABLED = 1, PF_ADMEDGE = 2, PF_AUTOEDGE = 4, PF_BPDUGUARD = 8,
|
||||||
PF_ROOTGUARD = 16, PF_FILTER = 32, PF_OPEREDGE = 64, PF_TRIPPED = 128;
|
PF_ROOTGUARD = 16, PF_FILTER = 32, PF_OPEREDGE = 64, PF_TRIPPED = 128;
|
||||||
|
|
||||||
@@ -49,38 +40,59 @@ function num(id, min, max, onch) {
|
|||||||
|
|
||||||
function buildPortsTable(ports) {
|
function buildPortsTable(ports) {
|
||||||
const tbl = document.getElementById("stpPortsTbl");
|
const tbl = document.getElementById("stpPortsTbl");
|
||||||
|
const stat = document.getElementById("stpStatTbl");
|
||||||
for (const p of ports) {
|
for (const p of ports) {
|
||||||
const tr = tbl.insertRow();
|
const tr = tbl.insertRow();
|
||||||
tr.insertCell().textContent = p.p; // Port
|
tr.insertCell().textContent = p.p; // Port
|
||||||
tr.insertCell().id = "st_" + p.p; // State
|
|
||||||
tr.insertCell().id = "role_" + p.p; // Role
|
|
||||||
tr.insertCell().appendChild(sel("en_" + p.p,
|
tr.insertCell().appendChild(sel("en_" + p.p,
|
||||||
[["on","on"],["off","off"]],
|
[["on","Enable"],["off","Disable"]],
|
||||||
e => stpCmd("stp port " + p.p + " " + e.target.value)));
|
e => stpCmd("stp port " + p.p + " " + e.target.value)));
|
||||||
|
const pc = num("cost_" + p.p, 0, 200000000,
|
||||||
|
e => stpCmd("stp port " + p.p + " cost " + e.target.value));
|
||||||
|
pc.style.width = "7em";
|
||||||
|
pc.title = "0 - 200000000 (0 = Auto)";
|
||||||
|
tr.insertCell().appendChild(pc);
|
||||||
|
const pr = sel("prio_" + p.p, [],
|
||||||
|
e => stpCmd("stp port " + p.p + " prio " + e.target.value));
|
||||||
|
for (let v = 0; v <= 240; v += 16) {
|
||||||
|
const o = document.createElement("option");
|
||||||
|
o.value = v; o.textContent = v + (v === 128 ? " (default)" : "");
|
||||||
|
pr.appendChild(o);
|
||||||
|
}
|
||||||
|
tr.insertCell().appendChild(pr);
|
||||||
tr.insertCell().appendChild(sel("edge_" + p.p,
|
tr.insertCell().appendChild(sel("edge_" + p.p,
|
||||||
[["auto","auto"],["on","edge"],["off","off"]],
|
[["auto","Auto"],["on","Enable"],["off","Disable"]],
|
||||||
e => stpCmd("stp port " + p.p + " edge " + e.target.value)));
|
e => stpCmd("stp port " + p.p + " edge " + e.target.value)));
|
||||||
tr.insertCell().appendChild(num("cost_" + p.p, 0, 255,
|
|
||||||
e => stpCmd("stp port " + p.p + " cost " + e.target.value)));
|
|
||||||
tr.insertCell().appendChild(num("prio_" + p.p, 0, 240,
|
|
||||||
e => stpCmd("stp port " + p.p + " prio " + e.target.value)));
|
|
||||||
tr.insertCell().appendChild(sel("guard_" + p.p,
|
|
||||||
[["none","none"],["bpdu","BPDU"],["root","Root"]],
|
|
||||||
e => stpCmd("stp port " + p.p + " guard " + e.target.value)));
|
|
||||||
tr.insertCell().appendChild(sel("filt_" + p.p,
|
tr.insertCell().appendChild(sel("filt_" + p.p,
|
||||||
[["off","off"],["on","on"]],
|
[["off","Disable"],["on","Enable"]],
|
||||||
e => stpCmd("stp port " + p.p + " filter " + e.target.value)));
|
e => stpCmd("stp port " + p.p + " filter " + e.target.value)));
|
||||||
|
tr.insertCell().appendChild(sel("guard_" + p.p,
|
||||||
|
[["none","None"],["bpdu","BPDU"],["root","Root"]],
|
||||||
|
e => stpCmd("stp port " + p.p + " guard " + e.target.value)));
|
||||||
|
tr.insertCell().appendChild(sel("p2p_" + p.p,
|
||||||
|
[["auto","Auto"],["on","Enable"],["off","Disable"]],
|
||||||
|
e => stpCmd("stp port " + p.p + " p2p " + e.target.value)));
|
||||||
|
|
||||||
|
const sr = stat.insertRow();
|
||||||
|
sr.insertCell().textContent = p.p;
|
||||||
|
for (const id of ["st","role","db","dp","dc","oe","op"])
|
||||||
|
sr.insertCell().id = id + "_" + p.p;
|
||||||
}
|
}
|
||||||
stpRows = ports.length;
|
stpRows = ports.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fmtBridgeId(h) {
|
||||||
|
if (!h || h.length < 16) return "";
|
||||||
|
const prio = parseInt(h.slice(0, 4), 16);
|
||||||
|
const mac = h.slice(4).replace(/(..)(?=.)/g, "$1:");
|
||||||
|
return prio + "-" + mac.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
function fetchStp() {
|
function fetchStp() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
const s = JSON.parse(xhttp.responseText);
|
const s = JSON.parse(xhttp.responseText);
|
||||||
// textContent throughout: rootMac comes from received BPDUs
|
|
||||||
// (remote-controlled), never render it as HTML
|
|
||||||
if (!stpRows)
|
if (!stpRows)
|
||||||
buildPortsTable(s.ports);
|
buildPortsTable(s.ports);
|
||||||
document.getElementById("stpStat").textContent = s.fsT
|
document.getElementById("stpStat").textContent = s.fsT
|
||||||
@@ -92,13 +104,19 @@ function fetchStp() {
|
|||||||
+ " via port " + s.rootPort + " — path cost: 0x" + s.cost
|
+ " via port " + s.rootPort + " — path cost: 0x" + s.cost
|
||||||
+ " — topology changes: " + parseInt(s.tc, 16))
|
+ " — topology changes: " + parseInt(s.tc, 16))
|
||||||
: "";
|
: "";
|
||||||
// live status columns always refresh
|
|
||||||
for (const p of s.ports) {
|
for (const p of s.ports) {
|
||||||
const trip = (p.f & PF_TRIPPED) ? " (guard!)" : "";
|
const trip = (p.f & PF_TRIPPED) ? " (guard!)" : "";
|
||||||
document.getElementById("st_" + p.p).textContent =
|
document.getElementById("st_" + p.p).textContent =
|
||||||
s.on ? STP_STATES[p.st] + trip : "-";
|
s.on ? STP_STATES[p.st] + trip : "-";
|
||||||
document.getElementById("role_" + p.p).textContent =
|
document.getElementById("role_" + p.p).textContent =
|
||||||
s.on ? STP_ROLES[p.role] + ((p.f & PF_OPEREDGE) ? " edge" : "") : "-";
|
s.on ? STP_ROLES[p.role] : "-";
|
||||||
|
document.getElementById("db_" + p.p).textContent = s.on ? fmtBridgeId(p.db) : "-";
|
||||||
|
document.getElementById("dp_" + p.p).textContent =
|
||||||
|
s.on ? (parseInt(p.dp.slice(0, 2), 16) + "-" + parseInt(p.dp.slice(2), 16)) : "-";
|
||||||
|
document.getElementById("dc_" + p.p).textContent = s.on ? parseInt(p.dc, 16) : "-";
|
||||||
|
document.getElementById("oe_" + p.p).textContent =
|
||||||
|
s.on ? ((p.f & PF_OPEREDGE) ? "True" : "False") : "-";
|
||||||
|
document.getElementById("op_" + p.p).textContent = s.on ? (p.p2 == 2 ? "False" : "True") : "-";
|
||||||
}
|
}
|
||||||
if (stpDirty) // an edit is in flight - do not revert controls
|
if (stpDirty) // an edit is in flight - do not revert controls
|
||||||
return;
|
return;
|
||||||
@@ -114,8 +132,9 @@ function fetchStp() {
|
|||||||
document.getElementById("en_" + p.p).value = (p.f & PF_ENABLED) ? "on" : "off";
|
document.getElementById("en_" + p.p).value = (p.f & PF_ENABLED) ? "on" : "off";
|
||||||
document.getElementById("edge_" + p.p).value =
|
document.getElementById("edge_" + p.p).value =
|
||||||
(p.f & PF_ADMEDGE) ? "on" : ((p.f & PF_AUTOEDGE) ? "auto" : "off");
|
(p.f & PF_ADMEDGE) ? "on" : ((p.f & PF_AUTOEDGE) ? "auto" : "off");
|
||||||
document.getElementById("cost_" + p.p).value = p.cost;
|
document.getElementById("cost_" + p.p).value = parseInt(p.pc, 16);
|
||||||
document.getElementById("prio_" + p.p).value = p.prio;
|
document.getElementById("prio_" + p.p).value = p.prio;
|
||||||
|
document.getElementById("p2p_" + p.p).value = ["auto","on","off"][p.p2];
|
||||||
document.getElementById("guard_" + p.p).value =
|
document.getElementById("guard_" + p.p).value =
|
||||||
(p.f & PF_BPDUGUARD) ? "bpdu" : ((p.f & PF_ROOTGUARD) ? "root" : "none");
|
(p.f & PF_BPDUGUARD) ? "bpdu" : ((p.f & PF_ROOTGUARD) ? "root" : "none");
|
||||||
document.getElementById("filt_" + p.p).value = (p.f & PF_FILTER) ? "on" : "off";
|
document.getElementById("filt_" + p.p).value = (p.f & PF_FILTER) ? "on" : "off";
|
||||||
@@ -132,7 +151,6 @@ async function stpSub() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
// bridge priority: 0-15 (x4096)
|
|
||||||
const bp = document.getElementById("bPrio");
|
const bp = document.getElementById("bPrio");
|
||||||
for (let i = 0; i < 16; i++) {
|
for (let i = 0; i < 16; i++) {
|
||||||
const o = document.createElement("option");
|
const o = document.createElement("option");
|
||||||
|
|||||||
+52
-5
@@ -535,7 +535,31 @@ void send_lag(void)
|
|||||||
* 0 Dis 1 Blk 2 Lrn 3 Fwd), an approximated role, and the per-port config
|
* 0 Dis 1 Blk 2 Lrn 3 Fwd), an approximated role, and the per-port config
|
||||||
* (enabled, edge admin/auto/oper, cost/1000, prio, guard, filter, tripped). */
|
* (enabled, edge admin/auto/oper, cost/1000, prio, guard, filter, tripped). */
|
||||||
__xdata uint8_t stp_we_root;
|
__xdata uint8_t stp_we_root;
|
||||||
__xdata uint8_t pi_i, pi_j; /* shared loop iterators (DSEG relief) */
|
__xdata uint8_t pi_i, pi_j, pi_j2; /* shared loop iterators (DSEG relief) */
|
||||||
|
|
||||||
|
/* Parameter relays in xdata: keeps these helpers off the IRAM overlay */
|
||||||
|
static __xdata uint32_t pi_u32;
|
||||||
|
static __xdata uint8_t pi_prio, pi_ext;
|
||||||
|
static __xdata uint8_t * __xdata pi_mac;
|
||||||
|
|
||||||
|
static void u32hex_html(void)
|
||||||
|
{
|
||||||
|
/* byte access instead of uint32 shifts: sdcc/mcs51 expands each
|
||||||
|
* 32-bit shift into a large helper sequence. Little-endian layout. */
|
||||||
|
__xdata uint8_t *b = (__xdata uint8_t *)&pi_u32;
|
||||||
|
byte_to_html(b[3]);
|
||||||
|
byte_to_html(b[2]);
|
||||||
|
byte_to_html(b[1]);
|
||||||
|
byte_to_html(b[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bridge_to_html(void)
|
||||||
|
{
|
||||||
|
byte_to_html(pi_prio);
|
||||||
|
byte_to_html(pi_ext);
|
||||||
|
for (pi_j2 = 0; pi_j2 < 6; pi_j2++)
|
||||||
|
byte_to_html(pi_mac[pi_j2]);
|
||||||
|
}
|
||||||
|
|
||||||
void send_stp(void)
|
void send_stp(void)
|
||||||
{
|
{
|
||||||
@@ -566,6 +590,9 @@ void send_stp(void)
|
|||||||
slen += strtox(outbuf + slen, "\",\"rootMac\":\"");
|
slen += strtox(outbuf + slen, "\",\"rootMac\":\"");
|
||||||
for (pi_j = 0; pi_j < 6; pi_j++)
|
for (pi_j = 0; pi_j < 6; pi_j++)
|
||||||
byte_to_html(root_bridge.mac[pi_j]);
|
byte_to_html(root_bridge.mac[pi_j]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"myMac\":\"");
|
||||||
|
for (pi_j = 0; pi_j < 6; pi_j++)
|
||||||
|
byte_to_html(uip_ethaddr.addr[pi_j]);
|
||||||
slen += strtox(outbuf + slen, "\",\"cost\":\"");
|
slen += strtox(outbuf + slen, "\",\"cost\":\"");
|
||||||
byte_to_html(root_bridge_cost >> 24);
|
byte_to_html(root_bridge_cost >> 24);
|
||||||
byte_to_html(root_bridge_cost >> 16);
|
byte_to_html(root_bridge_cost >> 16);
|
||||||
@@ -599,11 +626,31 @@ void send_stp(void)
|
|||||||
itoa_html(3);
|
itoa_html(3);
|
||||||
slen += strtox(outbuf + slen, ",\"f\":");
|
slen += strtox(outbuf + slen, ",\"f\":");
|
||||||
itoa_html(stp_pflags[pi_i]);
|
itoa_html(stp_pflags[pi_i]);
|
||||||
slen += strtox(outbuf + slen, ",\"cost\":");
|
/* path cost (raw hex, full 0..200M range), priority, p2p */
|
||||||
itoa_html(stp_pcost[pi_i] / 1000);
|
slen += strtox(outbuf + slen, ",\"pc\":\"");
|
||||||
slen += strtox(outbuf + slen, ",\"prio\":");
|
pi_u32 = stp_pcost[pi_i]; u32hex_html();
|
||||||
|
slen += strtox(outbuf + slen, "\",\"prio\":");
|
||||||
itoa_html(stp_pprio[pi_i]);
|
itoa_html(stp_pprio[pi_i]);
|
||||||
slen += strtox(outbuf + slen, "},");
|
slen += strtox(outbuf + slen, ",\"p2\":");
|
||||||
|
itoa_html(stp_pp2p[pi_i]);
|
||||||
|
/* designated info: a freshly heard BPDU wins, else we are the
|
||||||
|
* segment's designated bridge and report our own values */
|
||||||
|
stp_we_root = stp_dbridge[pi_i].mac[5] && stp_bpdu_age[pi_i] < (uint16_t)stp_maxage_s * 64;
|
||||||
|
slen += strtox(outbuf + slen, ",\"db\":\"");
|
||||||
|
if (stp_we_root) {
|
||||||
|
pi_prio = stp_dbridge[pi_i].prio; pi_ext = stp_dbridge[pi_i].ext;
|
||||||
|
pi_mac = stp_dbridge[pi_i].mac;
|
||||||
|
} else {
|
||||||
|
pi_prio = stp_prio; pi_ext = 0;
|
||||||
|
pi_mac = uip_ethaddr.addr;
|
||||||
|
}
|
||||||
|
bridge_to_html();
|
||||||
|
slen += strtox(outbuf + slen, "\",\"dp\":\"");
|
||||||
|
byte_to_html(stp_we_root ? (stp_dpid[pi_i] >> 8) : stp_pprio[pi_i]);
|
||||||
|
byte_to_html(stp_we_root ? stp_dpid[pi_i] : (pi_i + 1));
|
||||||
|
slen += strtox(outbuf + slen, "\",\"dc\":\"");
|
||||||
|
pi_u32 = stp_we_root ? stp_dcost[pi_i] : root_bridge_cost; u32hex_html();
|
||||||
|
slen += strtox(outbuf + slen, "\"},");
|
||||||
}
|
}
|
||||||
slen -= 1; // remove comma
|
slen -= 1; // remove comma
|
||||||
slen += strtox(outbuf + slen, "]}");
|
slen += strtox(outbuf + slen, "]}");
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
|
||||||
#pragma constseg BANK2
|
|
||||||
|
|
||||||
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked {
|
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked {
|
||||||
switch (sda_pin) {
|
switch (sda_pin) {
|
||||||
|
|||||||
+27
-2
@@ -74,6 +74,11 @@ extern volatile __xdata uint8_t mgmt_alive; /* set by httpd on any request */
|
|||||||
__xdata uint8_t stp_pflags[10];
|
__xdata uint8_t stp_pflags[10];
|
||||||
__xdata uint32_t stp_pcost[10];
|
__xdata uint32_t stp_pcost[10];
|
||||||
__xdata uint8_t stp_pprio[10];
|
__xdata uint8_t stp_pprio[10];
|
||||||
|
__xdata uint8_t stp_pp2p[10];
|
||||||
|
|
||||||
|
__xdata struct bridge stp_dbridge[10];
|
||||||
|
__xdata uint16_t stp_dpid[10];
|
||||||
|
__xdata uint32_t stp_dcost[10];
|
||||||
|
|
||||||
/* ---- Status / runtime ---- */
|
/* ---- Status / runtime ---- */
|
||||||
__xdata struct bridge root_bridge;
|
__xdata struct bridge root_bridge;
|
||||||
@@ -600,9 +605,29 @@ void stp_parse(void) __banked __reentrant
|
|||||||
else if (!cmd_compare(4, "off"))
|
else if (!cmd_compare(4, "off"))
|
||||||
goto err;
|
goto err;
|
||||||
} else if (cmd_compare(3, "cost")) {
|
} else if (cmd_compare(3, "cost")) {
|
||||||
if (atoi_byte(&stp_scratch, cmd_words_b[4]))
|
/* raw 802.1D value, 0..200000000; 0 = auto (speed-based) */
|
||||||
|
stp_cost_scratch = 0;
|
||||||
|
{
|
||||||
|
__xdata uint8_t *cp = &cmd_buffer[cmd_words_b[4]];
|
||||||
|
if (*cp < '0' || *cp > '9')
|
||||||
|
goto err;
|
||||||
|
while (*cp >= '0' && *cp <= '9') {
|
||||||
|
stp_cost_scratch = stp_cost_scratch * 10 + (*cp - '0');
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stp_cost_scratch > 200000000UL)
|
||||||
|
goto err;
|
||||||
|
stp_pcost[port] = stp_cost_scratch;
|
||||||
|
} else if (cmd_compare(3, "p2p")) {
|
||||||
|
if (cmd_compare(4, "auto"))
|
||||||
|
stp_pp2p[port] = 0;
|
||||||
|
else if (cmd_compare(4, "on"))
|
||||||
|
stp_pp2p[port] = 1;
|
||||||
|
else if (cmd_compare(4, "off"))
|
||||||
|
stp_pp2p[port] = 2;
|
||||||
|
else
|
||||||
goto err;
|
goto err;
|
||||||
stp_pcost[port] = (uint32_t)stp_scratch * 1000;
|
|
||||||
} else if (cmd_compare(3, "prio")) {
|
} else if (cmd_compare(3, "prio")) {
|
||||||
if (atoi_byte(&stp_scratch, cmd_words_b[4]))
|
if (atoi_byte(&stp_scratch, cmd_words_b[4]))
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
+9
-1
@@ -39,7 +39,15 @@ extern __xdata uint8_t stp_failsafe_tripped; /* max BPDUs per port per second (
|
|||||||
|
|
||||||
extern __xdata uint8_t stp_pflags[10];
|
extern __xdata uint8_t stp_pflags[10];
|
||||||
extern __xdata uint32_t stp_pcost[10]; /* path cost; 0 = auto (20000) */
|
extern __xdata uint32_t stp_pcost[10]; /* path cost; 0 = auto (20000) */
|
||||||
extern __xdata uint8_t stp_pprio[10]; /* port priority (default 0x80) */
|
extern __xdata uint8_t stp_pprio[10];
|
||||||
|
extern __xdata uint8_t stp_pp2p[10]; /* admin point-to-point: 0 auto, 1 on, 2 off */
|
||||||
|
|
||||||
|
/* Last-heard designated info per port (from received BPDUs); consult
|
||||||
|
* stp_bpdu_age to decide whether it is still current. */
|
||||||
|
extern __xdata struct bridge stp_dbridge[10];
|
||||||
|
extern __xdata uint16_t stp_dpid[10];
|
||||||
|
extern __xdata uint32_t stp_dcost[10];
|
||||||
|
extern __xdata uint16_t stp_bpdu_age[10]; /* ticks since a BPDU was heard */ /* port priority (default 0x80) */
|
||||||
|
|
||||||
/* ---- Status, exposed read-only for the web UI (send_stp) ---- */
|
/* ---- Status, exposed read-only for the web UI (send_stp) ---- */
|
||||||
extern __xdata struct bridge root_bridge;
|
extern __xdata struct bridge root_bridge;
|
||||||
|
|||||||
Reference in New Issue
Block a user