mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
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:
4 files changed
+60
No files matched your search
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user