Merge pull request #343 from bloqaudio/feat/mgmt-static-l2

port: pin the management MAC to the CPU port with a static L2 entry
This commit is contained in:
René van Dorst authored and GitHub committed 2026-09-03 18:25:11 +00:00
commit f6348765b4
4 files changed
+60

No files matched your search

+3
View File
@@ -48,6 +48,7 @@ __xdata uint16_t vlan_ptr;
__xdata char port_names[9][PORT_NAME_SIZE];
extern __xdata uint16_t management_vlan;
extern __xdata struct uip_eth_addr uip_ethaddr;
extern __xdata uint8_t sfp_speed[2];
extern __xdata uint8_t sfp_pins_last;
extern __xdata uint8_t sfp_options[2];
@@ -476,7 +477,9 @@ void parse_vlan(void)
vlan_settings.vlan = atoi_results_short;
if (cmd_compare(2, "mgmt")) {
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, true);
management_vlan = vlan_settings.vlan;
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
if (!vlan_settings.vlan)
print_string("Management VLAN disabled\n");
else
+54
View File
@@ -911,3 +911,57 @@ bool port_ingress_vlan_filter_get(uint8_t port) __banked
return reg_bit_test(RTL837X_VLAN_PORT_IGR_FLTR, port);
}
// C1 bit 0: static (no aging); age at C3[4:2] must be non-zero or the
// entry is invisible to lookup
static void l2_mgmt_entry_fill(__xdata uint8_t *mac, __xdata uint16_t vlan)
{
REG_WRITE(RTL837x_TBL_DATA_IN_A, mac[2], mac[3], mac[4], mac[5]);
REG_WRITE(RTL837x_TBL_DATA_IN_B, 0x20 | ((CPU_PORT & 0x3) << 6) | (vlan >> 8),
vlan & 0xff, mac[0], mac[1]);
REG_WRITE(RTL837x_TBL_DATA_IN_C, 0x00, 0x01, 0x00, (7 << 2) | (CPU_PORT >> 2));
}
static void l2_mgmt_tbl_prepare(void)
{
reg_read_m(RTL837x_TBL_DATA_0);
sfr_data[2] &= 0x3f;
sfr_data[1] &= 0xf8;
reg_write_m(RTL837x_TBL_DATA_0);
}
static void wait_table_ready(void)
{
do {
reg_read(RTL837X_TBL_CTRL);
} while (SFR_DATA_0 & TBL_EXECUTE);
}
/** Pin the management MAC to the CPU port; remove_entry deletes it */
void port_l2_static_mgmt(__xdata uint8_t *mac, __xdata uint16_t vlan, __xdata bool remove_entry) __banked
{
wait_table_ready();
// vlan 0 = management VLAN disabled: untagged management resolves in
// VLAN 1; clients in other VLANs keep their learned entry and age as before
if (!vlan)
vlan = 1;
l2_mgmt_entry_fill(mac, vlan);
l2_mgmt_tbl_prepare();
if (remove_entry) {
// a search miss returns index 0, not a slot
REG_WRITE(RTL837X_TBL_CTRL, 0x00, 0x00, TBL_L2_UNICAST, TBL_EXECUTE);
wait_table_ready();
reg_read_m(RTL837x_TBL_DATA_0);
if (!(sfr_data[2] & 0x10))
return;
sfr_data[1] |= 0x04; // CLEAR-entry
reg_write_m(RTL837x_TBL_DATA_0);
__xdata uint16_t idx = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3];
REG_WRITE(RTL837X_TBL_CTRL, idx >> 8, idx & 0xff, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
} else {
// method-0 write: the hardware hashes the key and places the entry
REG_WRITE(RTL837X_TBL_CTRL, 0x00, 0x00, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
}
wait_table_ready();
}
+1
View File
@@ -81,5 +81,6 @@ bool port_ingress_vlan_filter_get(uint8_t port) __banked;
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked;
void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked;
uint16_t port_isolation_get(uint8_t port) __banked;
void port_l2_static_mgmt(__xdata uint8_t *mac, __xdata uint16_t vlan, __xdata bool remove_entry) __banked;
#endif
+2
View File
@@ -2306,6 +2306,8 @@ void main(void)
early_boot_handle_button();
execute_config();
// After the config so the entry lands in the final management VLAN
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
/* After the config: a name from it wins, otherwise derive one. */
set_hostname_default();
print_cmd_prompt();