mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Add basic VLAN configuration
This commit is contained in:
@@ -19,4 +19,7 @@ void sleep(uint16_t t);
|
|||||||
void write_char(char c);
|
void write_char(char c);
|
||||||
void print_reg(uint16_t reg);
|
void print_reg(uint16_t reg);
|
||||||
uint8_t sfp_read_reg(uint8_t reg);
|
uint8_t sfp_read_reg(uint8_t reg);
|
||||||
|
void reg_bit_set(uint16_t reg_addr, char bit);
|
||||||
|
void reg_bit_clear(uint16_t reg_addr, char bit);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+155
-2
@@ -3,6 +3,8 @@
|
|||||||
* This code is in the Public Domain
|
* This code is in the Public Domain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// #define REGDBG
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
@@ -16,6 +18,158 @@ extern __xdata uint8_t maxPort;
|
|||||||
extern __xdata uint8_t nSFPPorts;
|
extern __xdata uint8_t nSFPPorts;
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
|
__xdata uint32_t l2_head;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table access registers of the RTL837x
|
||||||
|
* See e.g. RTL8366/RTL8369 datasheet for explanation
|
||||||
|
*/
|
||||||
|
#define RTL837X_TBL_CTRL 0x5cac
|
||||||
|
/* Bytes in control register: EE EE TT CC: EE: Entry, TT: Table type, CC: Command
|
||||||
|
* CC: BIT 0: 01: Execute. Bit 1: 1: WRITE, 0: READ
|
||||||
|
* TT: 04: L2-table, 03: VLAN-table
|
||||||
|
*/
|
||||||
|
#define TBL_L2_UNICAST 0x04
|
||||||
|
|
||||||
|
#define RTL837x_TBL_DATA_0 0x5cb0
|
||||||
|
#define RTL837x_L2_LIST_DATA_A 0x5ccc
|
||||||
|
#define RTL837x_L2_LIST_DATA_B 0x5cd0
|
||||||
|
#define RTL837x_L2_LIST_DATA_C 0x5cd4
|
||||||
|
#define RTL837x_TBL_DATA_IN_A 0x5cb8
|
||||||
|
|
||||||
|
#define RTL837x_PVID_BASE_REG 0x4e1c
|
||||||
|
|
||||||
|
void vlan_setup(void) __banked
|
||||||
|
{
|
||||||
|
print_string("\r\nvlan_setup called \r\n");
|
||||||
|
|
||||||
|
// Initialize VLAN table with VLAN 1
|
||||||
|
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0007ffff);
|
||||||
|
REG_SET(RTL837X_TBL_CTRL, 0x00010303);
|
||||||
|
do {
|
||||||
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
|
} while (sfr_data[3] & 0x01);
|
||||||
|
|
||||||
|
// Set PVID 1 for every port. TODO: Skip unused ports!
|
||||||
|
for (uint8_t i = minPort; i <= maxPort + 1; i++) { // Do this also for the CPU port
|
||||||
|
print_byte(i); write_char(':'); write_char(' ');
|
||||||
|
uint16_t reg = RTL837x_PVID_BASE_REG + ((i >> 1) << 2);
|
||||||
|
print_short(reg); write_char(' '); write_char('B'); write_char('>');
|
||||||
|
print_sfr_data();
|
||||||
|
reg_read_m(reg);
|
||||||
|
if (i & 0x1) {
|
||||||
|
REG_WRITE(reg, sfr_data[0], 0, sfr_data[2] & 0x0f | 0x10, sfr_data[3]);
|
||||||
|
} else {
|
||||||
|
REG_WRITE(reg, sfr_data[0], sfr_data[1], sfr_data[2] & 0xf0, 0x01);
|
||||||
|
}
|
||||||
|
write_char(' '); write_char('A'); write_char('>'); print_sfr_data();
|
||||||
|
|
||||||
|
reg_bit_clear(0x6738, i << 1);
|
||||||
|
reg_bit_clear(0x6738, i << 1 + 1);
|
||||||
|
reg_bit_set(0x4e18, i);
|
||||||
|
print_string("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable 4k VLAN
|
||||||
|
REG_SET(0x4e14, 4);
|
||||||
|
REG_SET(0x4e30, 0);
|
||||||
|
REG_SET(0x4e34, 0);
|
||||||
|
|
||||||
|
// Enable VLAN 1
|
||||||
|
REG_SET(RTL837x_TBL_DATA_IN_A, 0x0207ffff);
|
||||||
|
REG_SET(RTL837X_TBL_CTRL, 0x00010303);
|
||||||
|
do {
|
||||||
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
|
} while (sfr_data[3] & 0x01);
|
||||||
|
|
||||||
|
print_string("\r\nvlan_setup done \r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forget all dynamic L2 learned entries
|
||||||
|
*/
|
||||||
|
uint8_t port_l2_forget(void) __banked
|
||||||
|
{
|
||||||
|
// r53dc:00000000 R53dc-00000000 r53d4:000001ff r53d4:000001ff R53d4-000101ff r53d4:000001ff
|
||||||
|
reg_read_m(0x53dc);
|
||||||
|
if (sfr_data[0] || sfr_data[1] ||sfr_data[2] ||sfr_data[3]) {
|
||||||
|
print_string("List busy\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
REG_WRITE(0x53dc, sfr_data[0], sfr_data[1], sfr_data[2], sfr_data[3]);
|
||||||
|
|
||||||
|
reg_read_m(0x53d4);
|
||||||
|
REG_WRITE(0x53d4, 0x00, 0x01, sfr_data[2], sfr_data[3]);
|
||||||
|
do {
|
||||||
|
reg_read_m(0x53d4);
|
||||||
|
} while (sfr_data[1] & 0x1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void port_l2_learned(void) __banked
|
||||||
|
{
|
||||||
|
// Whait for any table action to be finished
|
||||||
|
do {
|
||||||
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
|
} while (sfr_data[3] & 0x01);
|
||||||
|
print_string("\r\n\tMAC\t\tVLAN\ttype\tport\r\n");
|
||||||
|
uint16_t entry = 0x0000;
|
||||||
|
uint16_t first_entry = 0xffff; // Table does not have that many entries
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint8_t port = 0;
|
||||||
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
|
REG_WRITE(RTL837x_TBL_DATA_0, sfr_data[0], sfr_data[1],sfr_data[2] | 0xc0, sfr_data[3]);
|
||||||
|
|
||||||
|
REG_WRITE(RTL837X_TBL_CTRL, entry >> 8, entry, TBL_L2_UNICAST, 0x1);
|
||||||
|
do {
|
||||||
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
|
} while (sfr_data[3] & 0x1);
|
||||||
|
|
||||||
|
// MAC
|
||||||
|
reg_read_m(RTL837x_L2_LIST_DATA_B);
|
||||||
|
print_byte(sfr_data[2]); write_char(':');
|
||||||
|
print_byte(sfr_data[3]); write_char(':');
|
||||||
|
port = (sfr_data[0] >> 6) & 0x3;
|
||||||
|
reg_read_m(RTL837x_L2_LIST_DATA_A);
|
||||||
|
print_byte(sfr_data[0]); write_char(':');
|
||||||
|
print_byte(sfr_data[1]); write_char(':');
|
||||||
|
print_byte(sfr_data[2]); write_char(':');
|
||||||
|
print_byte(sfr_data[3]); write_char('\t');
|
||||||
|
|
||||||
|
// VLAN
|
||||||
|
reg_read_m(RTL837x_L2_LIST_DATA_B);
|
||||||
|
print_short( ((uint16_t) (sfr_data[0] & 0x0f)) | sfr_data[1]); // VLAN
|
||||||
|
|
||||||
|
// type
|
||||||
|
reg_read_m(RTL837x_L2_LIST_DATA_C);
|
||||||
|
if (sfr_data[2] & 0x1)
|
||||||
|
print_string("\tstatic\t");
|
||||||
|
else
|
||||||
|
print_string("\tlearned\t");
|
||||||
|
|
||||||
|
port |= (sfr_data[3] & 0x3) << 2;
|
||||||
|
if (port < 9)
|
||||||
|
write_char('1' + port);
|
||||||
|
else
|
||||||
|
print_string("10");
|
||||||
|
|
||||||
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
|
entry = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3] + 1;
|
||||||
|
if (first_entry == 0xffff) {
|
||||||
|
first_entry = entry;
|
||||||
|
} else {
|
||||||
|
if (first_entry == entry)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
print_string("\r\n");
|
||||||
|
}
|
||||||
|
print_string("\r\nport_l2_learned done \r\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("\r\n Port\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\r\n");
|
||||||
@@ -69,8 +223,7 @@ void port_stats_print(void) __banked
|
|||||||
print_string("Up\t");
|
print_string("Up\t");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// R0f60-000005e1 r0f60:000005e0 r0f64:00000000 r0f68:000000ba r1250:0fffffff R0f60-00000601 r0f60:00000600 r0f64:00000000 r0f68:00000000
|
|
||||||
// R0f60-000005c1 r0f60:000005c0 r0f64:00000000 r0f68:000016dd R0f60-00000601 r0f60:00000600 r0f64:00000000 r0f68:00000000
|
|
||||||
REG_WRITE(RTL837X_STAT_GET, 0x00, 0x00, 0x05, 0xe0 | (i << 1) | 1);
|
REG_WRITE(RTL837X_STAT_GET, 0x00, 0x00, 0x05, 0xe0 | (i << 1) | 1);
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_STAT_GET);
|
reg_read_m(RTL837X_STAT_GET);
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#ifndef _RTL837X_PORT_H_
|
#ifndef _RTL837X_PORT_H_
|
||||||
#define _RTL837X_PORT_H_
|
#define _RTL837X_PORT_H_
|
||||||
|
|
||||||
|
uint8_t port_l2_forget(void) __banked;
|
||||||
|
void port_l2_learned(void) __banked;
|
||||||
void port_stats_print(void) __banked;
|
void port_stats_print(void) __banked;
|
||||||
|
void vlan_setup(void) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1594,6 +1594,8 @@ void bootloader(void)
|
|||||||
rtl8372_init();
|
rtl8372_init();
|
||||||
REG_SET(0x7f94, 0x0); // BUG: Only for testing, otherwise: clear bits 0-3
|
REG_SET(0x7f94, 0x0); // BUG: Only for testing, otherwise: clear bits 0-3
|
||||||
nic_setup();
|
nic_setup();
|
||||||
|
vlan_setup();
|
||||||
|
|
||||||
was_offline = 1;
|
was_offline = 1;
|
||||||
|
|
||||||
setup_i2c();
|
setup_i2c();
|
||||||
@@ -1729,6 +1731,9 @@ void bootloader(void)
|
|||||||
phy_set_mode(p, PHY_OFF, 0, 0);
|
phy_set_mode(p, PHY_OFF, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cmd_compare(0, "l2")) {
|
||||||
|
port_l2_learned();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print_string("\r\n> ");
|
print_string("\r\n> ");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user