mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Add trunking support and initial L2 setup
This commit is contained in:
+114
-52
@@ -21,12 +21,14 @@ extern __xdata uint8_t nSFPPorts;
|
|||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
extern __xdata uint8_t cpuPort;
|
extern __xdata uint8_t cpuPort;
|
||||||
|
|
||||||
|
extern __xdata uint8_t isRTL8373;
|
||||||
|
|
||||||
__xdata uint32_t l2_head;
|
__xdata uint32_t l2_head;
|
||||||
|
|
||||||
|
|
||||||
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
|
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\nport_mirror_set called \r\n");
|
print_string("\nport_mirror_set called \n");
|
||||||
|
|
||||||
REG_WRITE(RTL837x_MIRROR_CONF, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask);
|
REG_WRITE(RTL837x_MIRROR_CONF, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask);
|
||||||
REG_WRITE(RTL837x_MIRROR_CTRL, 0, 0, 0, (port << 1) | 0x1);
|
REG_WRITE(RTL837x_MIRROR_CTRL, 0, 0, 0, (port << 1) | 0x1);
|
||||||
@@ -35,15 +37,33 @@ void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata u
|
|||||||
|
|
||||||
void port_mirror_del(void) __banked
|
void port_mirror_del(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\nport_mirror_del called \r\n");
|
print_string("\nport_mirror_del called \n");
|
||||||
REG_SET(RTL837x_MIRROR_CTRL, 0);
|
REG_SET(RTL837x_MIRROR_CTRL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void port_ingress_filter(register uint8_t port, uint8_t type) __banked
|
||||||
|
{
|
||||||
|
if (type & 0x1)
|
||||||
|
reg_bit_set(RTL837x_REG_INGRESS, port << 1);
|
||||||
|
else
|
||||||
|
reg_bit_clear(RTL837x_REG_INGRESS, port << 1);
|
||||||
|
if (type & 0x2)
|
||||||
|
reg_bit_set(RTL837x_REG_INGRESS, (port << 1) + 1);
|
||||||
|
else
|
||||||
|
reg_bit_clear(RTL837x_REG_INGRESS, (port << 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
pvid 6 2 2
|
||||||
|
port_pvid_set called
|
||||||
|
R4e28-00001002
|
||||||
|
*/
|
||||||
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked
|
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked
|
||||||
{
|
{
|
||||||
// r4e1c:00001001 R4e1c-000017d0 r6738:00000000 R6738-00000000 (no filtering)
|
// r4e1c:00001001 R4e1c-000017d0 r6738:00000000 R6738-00000000 (no filtering)
|
||||||
print_string("\r\nport_pvid_set called \r\n");
|
print_string("\nport_pvid_set called \n");
|
||||||
uint16_t reg = RTL837x_PVID_BASE_REG + ((port >> 1) << 2);
|
uint16_t reg = RTL837x_PVID_BASE_REG + ((port >> 1) << 2);
|
||||||
|
|
||||||
reg_read_m(reg);
|
reg_read_m(reg);
|
||||||
@@ -57,7 +77,7 @@ void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked
|
|||||||
|
|
||||||
void vlan_delete(uint16_t vlan) __banked
|
void vlan_delete(uint16_t vlan) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\nvlan_delete called \r\n"); print_short(vlan);
|
print_string("\nvlan_delete called \n"); print_short(vlan);
|
||||||
// R5cac-07d30301 r5cac:07d30300
|
// R5cac-07d30301 r5cac:07d30300
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,39 +87,27 @@ void vlan_delete(uint16_t vlan) __banked
|
|||||||
*/
|
*/
|
||||||
void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked
|
void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked
|
||||||
{
|
{
|
||||||
/* First line:
|
// For now, the CPU-port is always a tagged member:
|
||||||
7-9: Untagged: 1-1, Not-Member: 1-0
|
members |= 0x0200; // Set 10th bit
|
||||||
0111111111
|
tagged |= 0x0200;
|
||||||
1111000000
|
print_string("\nvlan_create called\nvlan: "); print_short(vlan);
|
||||||
9 port 0
|
print_string(", members: "); print_short(members);
|
||||||
|
print_string(", tagged: "); print_short(tagged); write_char('\n');
|
||||||
|
|
||||||
1-3: Untagged: 1-1
|
uint16_t a = (~members) ^ tagged ^ members;
|
||||||
0111111111
|
// On RTL8372, port-bits 0-2 must be 0, although they are not members
|
||||||
1000000111
|
if (!isRTL8373) {
|
||||||
|
a &= 0x1f8;
|
||||||
|
tagged &= 0x3f8;
|
||||||
|
}
|
||||||
|
|
||||||
1-3: Tagged: 0-1
|
|
||||||
0111111000
|
|
||||||
1000000111
|
|
||||||
|
|
||||||
7-9: Tagged: 0-1
|
|
||||||
0000111111
|
|
||||||
1111000000
|
|
||||||
In 1-0 -> 1-1 FIRST Bit: XOR, Second bit stays
|
|
||||||
In 1-1 -> 0-1
|
|
||||||
In 0-1 // Not allowed
|
|
||||||
In 0-0 -> 1-0
|
|
||||||
*/
|
|
||||||
// R5cb8-02 07e207 R5cac-07d20303
|
|
||||||
print_string("\r\nvlan_create called: "); print_short(vlan); write_char(' '); print_short(members); write_char(':'); print_short(tagged);
|
|
||||||
|
|
||||||
uint16_t a = members ^ tagged;
|
|
||||||
// Initialize VLAN table with VLAN 1
|
// Initialize VLAN table with VLAN 1
|
||||||
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (tagged >> 8), tagged);
|
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (members >> 8), members);
|
||||||
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & TBL_EXECUTE);
|
} while (sfr_data[3] & TBL_EXECUTE);
|
||||||
print_string("\r\nvlan_create done \r\n");
|
print_string("\nvlan_create done \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,10 +120,14 @@ void vlan_create(register uint16_t vlan, register uint16_t members, register uin
|
|||||||
*/
|
*/
|
||||||
void vlan_setup(void) __banked
|
void vlan_setup(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\nvlan_setup called \r\n");
|
print_string("\nvlan_setup called \n");
|
||||||
|
|
||||||
// Initialize VLAN table with VLAN 1
|
// Initialize VLAN table for VLAN 1, by disabling that entry
|
||||||
|
if (isRTL8373) {
|
||||||
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0007ffff);
|
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0007ffff);
|
||||||
|
} else {
|
||||||
|
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0007e3f8);
|
||||||
|
}
|
||||||
REG_SET(RTL837X_TBL_CTRL, 0x00010303);
|
REG_SET(RTL837X_TBL_CTRL, 0x00010303);
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
@@ -125,9 +137,8 @@ void vlan_setup(void) __banked
|
|||||||
for (uint8_t i = minPort; i <= maxPort + 1; i++) { // Do this also for the CPU port (+1)
|
for (uint8_t i = minPort; i <= maxPort + 1; i++) { // Do this also for the CPU port (+1)
|
||||||
uint16_t reg = RTL837x_PVID_BASE_REG + ((i >> 1) << 2);
|
uint16_t reg = RTL837x_PVID_BASE_REG + ((i >> 1) << 2);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_byte(i); write_char(':'); write_char(' ');
|
print_byte(i); write_char(':'); write_char(' '); print_short(reg); write_char('=');
|
||||||
print_short(reg); write_char(' '); write_char('B'); write_char('>');
|
print_short(reg); write_char(' ');
|
||||||
print_sfr_data();
|
|
||||||
#endif
|
#endif
|
||||||
reg_read_m(reg);
|
reg_read_m(reg);
|
||||||
if (i & 0x1) {
|
if (i & 0x1) {
|
||||||
@@ -143,39 +154,61 @@ void vlan_setup(void) __banked
|
|||||||
// EGRESS filtering for port: removal of additional VLAN tag
|
// EGRESS filtering for port: removal of additional VLAN tag
|
||||||
reg_bit_clear(0x6738, i << 1);
|
reg_bit_clear(0x6738, i << 1);
|
||||||
reg_bit_clear(0x6738, (i << 1) + 1);
|
reg_bit_clear(0x6738, (i << 1) + 1);
|
||||||
if (i != cpuPort)
|
|
||||||
reg_bit_set(0x4e18, i);
|
reg_bit_set(0x4e18, i);
|
||||||
else
|
|
||||||
reg_bit_clear(0x4e18, i);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_string("\r\n");
|
print_string("\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ingress filtering. 2 bits per port: allow tagged (01) / untagged (10) and all (00)
|
||||||
|
REG_SET(RTL837x_REG_INGRESS, 0); // No filtering for all ports
|
||||||
|
|
||||||
// Enable 4k VLAN
|
// Enable 4k VLAN
|
||||||
REG_SET(0x4e14, 4);
|
REG_SET(0x4e14, 4);
|
||||||
REG_SET(0x4e30, 0);
|
REG_SET(0x4e30, 0);
|
||||||
REG_SET(0x4e34, 0);
|
REG_SET(0x4e34, 0);
|
||||||
|
|
||||||
// Enable VLAN 1: Ports 0-9, i.e. including the CPU port are untagged members
|
// Enable VLAN 1: Ports 0-9, i.e. including the CPU port are untagged members
|
||||||
|
if (isRTL8373) {
|
||||||
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0207ffff); // 02: Entry valid, 7ffff: membership
|
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0207ffff); // 02: Entry valid, 7ffff: membership
|
||||||
|
} else {
|
||||||
|
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0207e3f8);
|
||||||
|
}
|
||||||
REG_SET(RTL837X_TBL_CTRL, 0x00010303); // Write VLAN 1
|
REG_SET(RTL837X_TBL_CTRL, 0x00010303); // Write VLAN 1
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & TBL_EXECUTE);
|
} while (sfr_data[3] & TBL_EXECUTE);
|
||||||
|
|
||||||
// Configure trunking
|
// Configure trunking
|
||||||
REG_SET(0x4f4c, 0x0000007e);
|
if (isRTL8373) {
|
||||||
|
REG_SET(0x4f4c, 0x0000007e); // Removes RTL VLAN-Tags
|
||||||
|
REG_SET(0x4f48, 0x0000007e); // Adds 802.1Q VLAN-Tags to tagged ports
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_string("\r\nvlan_setup, REG 0x6738: "); print_reg(0x6738);
|
print_string("\nvlan_setup, REG 0x6738: "); print_reg(0x6738);
|
||||||
print_string("\r\nvlan_setup, REG 0x4e18: "); print_reg(0x4e18);
|
print_string("\nvlan_setup, REG 0x4e18: "); print_reg(0x4e18);
|
||||||
print_string("\r\nvlan_setup, REG 0x4e14: "); print_reg(0x4e14);
|
print_string("\nvlan_setup, REG 0x4e14: "); print_reg(0x4e14);
|
||||||
print_string("\r\nvlan_setup, REG 0x4e30: "); print_reg(0x4e30);
|
print_string("\nvlan_setup, REG 0x4e30: "); print_reg(0x4e30);
|
||||||
print_string("\r\nvlan_setup, REG 0x4e34: "); print_reg(0x4e34);
|
print_string("\nvlan_setup, REG 0x4e34: "); print_reg(0x4e34);
|
||||||
print_string("\r\nvlan_setup, REG 0x4f4c: "); print_reg(0x4f4c);
|
print_string("\nvlan_setup, REG 0x4f48: "); print_reg(0x4f48);
|
||||||
|
print_string("\nvlan_setup, REG 0x4f4c: "); print_reg(0x4f4c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
print_string("\r\nvlan_setup done \r\n");
|
print_string("\nvlan_setup done \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void trunk_set(uint8_t group, uint16_t mask) __banked
|
||||||
|
{
|
||||||
|
if (group == 1) {
|
||||||
|
REG_WRITE(0x4f38, 0, 0, mask >> 8, mask);
|
||||||
|
} else if (group == 2) {
|
||||||
|
REG_WRITE(0x4f3c, 0, 0, mask >> 8, mask);
|
||||||
|
} else {
|
||||||
|
print_string("\nTrunk group must be 1 or 2\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -187,7 +220,7 @@ uint8_t port_l2_forget(void) __banked
|
|||||||
// r53dc:00000000 R53dc-00000000 r53d4:000001ff r53d4:000001ff R53d4-000101ff r53d4:000001ff
|
// r53dc:00000000 R53dc-00000000 r53d4:000001ff r53d4:000001ff R53d4-000101ff r53d4:000001ff
|
||||||
reg_read_m(0x53dc);
|
reg_read_m(0x53dc);
|
||||||
if (sfr_data[0] || sfr_data[1] ||sfr_data[2] ||sfr_data[3]) {
|
if (sfr_data[0] || sfr_data[1] ||sfr_data[2] ||sfr_data[3]) {
|
||||||
print_string("List busy\r\n");
|
print_string("List busy\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
REG_WRITE(0x53dc, sfr_data[0], sfr_data[1], sfr_data[2], sfr_data[3]);
|
REG_WRITE(0x53dc, sfr_data[0], sfr_data[1], sfr_data[2], sfr_data[3]);
|
||||||
@@ -208,7 +241,7 @@ void port_l2_learned(void) __banked
|
|||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & 0x01);
|
} while (sfr_data[3] & 0x01);
|
||||||
print_string("\r\n\tMAC\t\tVLAN\ttype\tport\r\n");
|
print_string("\n\tMAC\t\tVLAN\ttype\tport\n");
|
||||||
__xdata uint16_t entry = 0x0000;
|
__xdata uint16_t entry = 0x0000;
|
||||||
__xdata uint16_t first_entry = 0xffff; // Table does not have that many entries
|
__xdata uint16_t first_entry = 0xffff; // Table does not have that many entries
|
||||||
|
|
||||||
@@ -264,14 +297,43 @@ void port_l2_learned(void) __banked
|
|||||||
write_char(' '); print_sfr_data();
|
write_char(' '); print_sfr_data();
|
||||||
write_char(' '); print_byte(other);
|
write_char(' '); print_byte(other);
|
||||||
#endif
|
#endif
|
||||||
print_string("\r\n");
|
print_string("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic L2 configuration such as time to forget an entry
|
||||||
|
*/
|
||||||
|
void port_l2_setup() __banked
|
||||||
|
{
|
||||||
|
print_string("\nport_l2_setup called\n");
|
||||||
|
REG_SET(0x53dc, 0x00000000);
|
||||||
|
if(isRTL8373) {
|
||||||
|
REG_SET(0x53d4, 0x000101ff);
|
||||||
|
} else {
|
||||||
|
REG_SET(0x53d4, 0x000001f8);
|
||||||
|
}
|
||||||
|
for (uint8_t i = minPort; i <= maxPort; i++) {
|
||||||
|
uint16_t reg = 0x5384 + (i << 2);
|
||||||
|
REG_SET(reg, 0x00001040);
|
||||||
|
|
||||||
|
reg = 0x50c0 + (i << 2);
|
||||||
|
if(isRTL8373) {
|
||||||
|
REG_SET(reg, 0x3ff);
|
||||||
|
} else {
|
||||||
|
REG_SET(reg, 0x3f8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reg_bit_set(0x4f80, 0);
|
||||||
|
|
||||||
|
print_string("\nport_l2_setup done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void port_stats_print(void) __banked
|
void port_stats_print(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\n Port\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\r\n");
|
print_string("\n Port\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\n");
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = minPort; i <= maxPort; i++) {
|
||||||
write_char('1' + i); write_char('\t');
|
write_char('1' + i); write_char('\t');
|
||||||
phy_read(i, 0x1f, 0xa610); // p001f.a610:2058
|
phy_read(i, 0x1f, 0xa610); // p001f.a610:2058
|
||||||
@@ -344,6 +406,6 @@ void port_stats_print(void) __banked
|
|||||||
reg_read_m(RTL837X_STAT_GET);
|
reg_read_m(RTL837X_STAT_GET);
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (sfr_data[3] & 0x1);
|
||||||
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
|
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
|
||||||
print_string("\r\n");
|
print_string("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,7 @@ void vlan_create(uint16_t vlan, uint16_t members, uint16_t tagged) __banked;
|
|||||||
void vlan_delete(uint16_t vlan) __banked;
|
void vlan_delete(uint16_t vlan) __banked;
|
||||||
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
||||||
void port_mirror_del(void) __banked;
|
void port_mirror_del(void) __banked;
|
||||||
|
void port_ingress_filter(register uint8_t port, uint8_t type) __banked;
|
||||||
|
void port_l2_setup() __banked;
|
||||||
|
void trunk_set(uint8_t group, uint16_t mask) __banked;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -98,6 +98,15 @@
|
|||||||
#define RTL837x_L2_TBL_CTRL 0x53d4
|
#define RTL837x_L2_TBL_CTRL 0x53d4
|
||||||
#define RTL837x_PVID_BASE_REG 0x4e1c
|
#define RTL837x_PVID_BASE_REG 0x4e1c
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Egress / ingress filtering
|
||||||
|
*/
|
||||||
|
// 2 bits per port: allow tagged (01) / untagged (10) and all (00)
|
||||||
|
#define RTL837x_REG_INGRESS 0x4e10
|
||||||
|
#define INGR_ALLOW_TAGGED 1
|
||||||
|
#define INGR_ALLOW_UNTAGGED 2
|
||||||
|
#define INGR_ALLOW_ALL 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mirroring
|
* Mirroring
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user