mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #39 from logicog/sfp_work
Put all the device information in one struct `machine`. So all the device information is defined in one place. Also easier to add new devices. Show device name also on website. Fix SFP status information, some devices have a different SFP layout. Reworks GPIO handling Able to set manual port speed, duplex for the RJ45 ports.
This commit is contained in:
@@ -21,7 +21,7 @@ all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin
|
|||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c
|
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c machine.c
|
||||||
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
||||||
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel
|
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel
|
||||||
|
|
||||||
|
|||||||
+70
-59
@@ -15,13 +15,12 @@
|
|||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
|
|
||||||
extern __xdata uint8_t minPort;
|
extern __code struct machine machine;
|
||||||
extern __xdata uint8_t maxPort;
|
|
||||||
extern __xdata uint8_t nSFPPorts;
|
|
||||||
extern __xdata uint8_t isRTL8373;
|
|
||||||
extern __xdata uint16_t mpos;
|
extern __xdata uint16_t mpos;
|
||||||
extern __xdata uint8_t stpEnabled;
|
extern __xdata uint8_t stpEnabled;
|
||||||
extern __code uint8_t log_to_phys_port[9];
|
extern __code uint8_t log_to_phys_port[9];
|
||||||
@@ -63,11 +62,6 @@ __xdata signed char cmd_words_b[N_WORDS];
|
|||||||
__xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
__xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
||||||
__xdata uint16_t cmd_history_ptr;
|
__xdata uint16_t cmd_history_ptr;
|
||||||
|
|
||||||
// Maps the physical port (starting from 0) to the logical port
|
|
||||||
__code uint8_t phys_to_log_port[6] = {
|
|
||||||
4, 5, 6, 7, 3, 8
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline uint8_t isletter(uint8_t l)
|
inline uint8_t isletter(uint8_t l)
|
||||||
{
|
{
|
||||||
@@ -205,10 +199,7 @@ void parse_lag(void)
|
|||||||
print_string(" member ports: ");
|
print_string(" member ports: ");
|
||||||
for (uint8_t j = 0; j < 10; j++) {
|
for (uint8_t j = 0; j < 10; j++) {
|
||||||
if (members & 1) {
|
if (members & 1) {
|
||||||
if (!isRTL8373)
|
write_char('0' + machine.log_to_phys_port[j]);
|
||||||
write_char('0' + log_to_phys_port[j]);
|
|
||||||
else
|
|
||||||
write_char('1' + j);
|
|
||||||
write_char(' ');
|
write_char(' ');
|
||||||
}
|
}
|
||||||
members >>= 1;
|
members >>= 1;
|
||||||
@@ -233,12 +224,11 @@ void parse_lag(void)
|
|||||||
port = cmd_buffer[cmd_words_b[w]] - '1';
|
port = cmd_buffer[cmd_words_b[w]] - '1';
|
||||||
if (isnumber(cmd_buffer[cmd_words_b[w] + 1]))
|
if (isnumber(cmd_buffer[cmd_words_b[w] + 1]))
|
||||||
port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1';
|
port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1';
|
||||||
if (!isRTL8373)
|
port = machine.phys_to_log_port[port];
|
||||||
port = phys_to_log_port[port];
|
|
||||||
} else {
|
} else {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (port > maxPort)
|
if (port > machine.max_port)
|
||||||
goto err;
|
goto err;
|
||||||
members |= ((uint16_t)1) << port;
|
members |= ((uint16_t)1) << port;
|
||||||
w++;
|
w++;
|
||||||
@@ -321,12 +311,11 @@ void parse_vlan(void)
|
|||||||
if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
||||||
tagged |= ((uint16_t)1) << port;
|
tagged |= ((uint16_t)1) << port;
|
||||||
} else {
|
} else {
|
||||||
if (!isRTL8373)
|
port = machine.phys_to_log_port[port];
|
||||||
port = phys_to_log_port[port];
|
|
||||||
if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
||||||
tagged |= ((uint16_t)1) << port;
|
tagged |= ((uint16_t)1) << port;
|
||||||
}
|
}
|
||||||
if (port > maxPort)
|
if (port > machine.max_port)
|
||||||
goto err;
|
goto err;
|
||||||
members |= ((uint16_t)1) << port;
|
members |= ((uint16_t)1) << port;
|
||||||
}
|
}
|
||||||
@@ -359,10 +348,7 @@ void parse_mirror(void)
|
|||||||
print_string("NOT Enabled: ");
|
print_string("NOT Enabled: ");
|
||||||
}
|
}
|
||||||
print_string("Mirroring port: ");
|
print_string("Mirroring port: ");
|
||||||
if (!isRTL8373)
|
write_char('0' + machine.log_to_phys_port[mPort >> 1]);
|
||||||
write_char('0' + log_to_phys_port[mPort >> 1]);
|
|
||||||
else
|
|
||||||
write_char('0' + (mPort >> 1) + 1);
|
|
||||||
reg_read_m(RTL837x_MIRROR_CONF);
|
reg_read_m(RTL837x_MIRROR_CONF);
|
||||||
uint16_t m = sfr_data[0];
|
uint16_t m = sfr_data[0];
|
||||||
m = (m << 8) | sfr_data[1];
|
m = (m << 8) | sfr_data[1];
|
||||||
@@ -387,8 +373,7 @@ void parse_mirror(void)
|
|||||||
mirroring_port = cmd_buffer[cmd_words_b[1]] - '1';
|
mirroring_port = cmd_buffer[cmd_words_b[1]] - '1';
|
||||||
if (isnumber(cmd_buffer[cmd_words_b[1] + 1]))
|
if (isnumber(cmd_buffer[cmd_words_b[1] + 1]))
|
||||||
mirroring_port = (mirroring_port + 1) * 10 + cmd_buffer[cmd_words_b[1] + 1] - '1';
|
mirroring_port = (mirroring_port + 1) * 10 + cmd_buffer[cmd_words_b[1] + 1] - '1';
|
||||||
if (!isRTL8373)
|
mirroring_port = machine.phys_to_log_port[mirroring_port];
|
||||||
mirroring_port = phys_to_log_port[mirroring_port];
|
|
||||||
|
|
||||||
uint8_t w = 2;
|
uint8_t w = 2;
|
||||||
while (cmd_words_b[w] > 0) {
|
while (cmd_words_b[w] > 0) {
|
||||||
@@ -397,8 +382,7 @@ void parse_mirror(void)
|
|||||||
port = cmd_buffer[cmd_words_b[w]] - '1';
|
port = cmd_buffer[cmd_words_b[w]] - '1';
|
||||||
if (isnumber(cmd_buffer[cmd_words_b[w] + 1])) {
|
if (isnumber(cmd_buffer[cmd_words_b[w] + 1])) {
|
||||||
port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1';
|
port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1';
|
||||||
if (!isRTL8373)
|
port = machine.phys_to_log_port[port];
|
||||||
port = phys_to_log_port[port];
|
|
||||||
if (cmd_buffer[cmd_words_b[w] + 2] == 'r')
|
if (cmd_buffer[cmd_words_b[w] + 2] == 'r')
|
||||||
rx_pmask |= ((uint16_t)1) << port;
|
rx_pmask |= ((uint16_t)1) << port;
|
||||||
else if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
else if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
||||||
@@ -408,8 +392,7 @@ void parse_mirror(void)
|
|||||||
tx_pmask |= ((uint16_t)1) << port;
|
tx_pmask |= ((uint16_t)1) << port;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isRTL8373)
|
port = machine.phys_to_log_port[port];
|
||||||
port = phys_to_log_port[port];
|
|
||||||
if (cmd_buffer[cmd_words_b[w] + 1] == 'r')
|
if (cmd_buffer[cmd_words_b[w] + 1] == 'r')
|
||||||
rx_pmask |= ((uint16_t)1) << port;
|
rx_pmask |= ((uint16_t)1) << port;
|
||||||
else if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
else if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
||||||
@@ -426,6 +409,53 @@ void parse_mirror(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_port(void)
|
||||||
|
{
|
||||||
|
print_string("\nPORT ");
|
||||||
|
uint8_t p = cmd_buffer[cmd_words_b[1]] - '1';
|
||||||
|
p = machine.phys_to_log_port[p];
|
||||||
|
print_byte(p);
|
||||||
|
if (machine.is_sfp[p]) {
|
||||||
|
print_string(" is SFP no PHY information available.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "10m")) {
|
||||||
|
print_string(" 10M\n");
|
||||||
|
phy_set_speed(p, PHY_SPEED_10M);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "100m")) {
|
||||||
|
print_string(" 100M\n");
|
||||||
|
phy_set_speed(p, PHY_SPEED_100M);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "2g5")) {
|
||||||
|
print_string(" 2.5G\n");
|
||||||
|
phy_set_speed(p, PHY_SPEED_2G5);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "1g")) {
|
||||||
|
print_string(" 1G\n");
|
||||||
|
phy_set_speed(p, PHY_SPEED_1G);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "auto")) {
|
||||||
|
print_string(" AUTO\n");
|
||||||
|
phy_set_speed(p, PHY_SPEED_AUTO);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "off")) {
|
||||||
|
print_string(" OFF\n");
|
||||||
|
phy_set_speed(p, PHY_OFF);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "duplex")) {
|
||||||
|
print_string(" DUPLEX\n");
|
||||||
|
if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||||
|
phy_set_duplex(p, 1);
|
||||||
|
else
|
||||||
|
phy_set_duplex(p, 0);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "show")) {
|
||||||
|
phy_show(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_regget(void)
|
void parse_regget(void)
|
||||||
{
|
{
|
||||||
uint16_t reg = 0;
|
uint16_t reg = 0;
|
||||||
@@ -627,18 +657,19 @@ void cmd_parser(void) __banked
|
|||||||
print_string("\nRESET\n\n");
|
print_string("\nRESET\n\n");
|
||||||
reset_chip();
|
reset_chip();
|
||||||
} else if (cmd_compare(0, "sfp")) {
|
} else if (cmd_compare(0, "sfp")) {
|
||||||
uint8_t rate = sfp_read_reg(0, 12);
|
print_string("\nSlot 1 - Rate: "); print_byte(sfp_read_reg(0, 12));
|
||||||
print_string("\nRate: "); print_byte(rate);
|
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(0, 11));
|
print_string(" Encoding: "); print_byte(sfp_read_reg(0, 11));
|
||||||
print_string("\n");
|
print_string("\n");
|
||||||
for (uint8_t i = 20; i < 60; i++) {
|
sfp_print_info(0);
|
||||||
uint8_t c = sfp_read_reg(0, i);
|
if (machine.n_sfp == 2) {
|
||||||
if (c)
|
print_string("\nSlot 2 - Rate: "); print_byte(sfp_read_reg(1, 12));
|
||||||
write_char(c);
|
print_string(" Encoding: "); print_byte(sfp_read_reg(1, 11));
|
||||||
|
print_string("\n");
|
||||||
|
sfp_print_info(1);
|
||||||
}
|
}
|
||||||
} else if (cmd_compare(0, "stat")) {
|
} else if (cmd_compare(0, "stat")) {
|
||||||
port_stats_print();
|
port_stats_print();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'r') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'r') {
|
||||||
print_string("\nPRINT SECURITY REGISTERS\n");
|
print_string("\nPRINT SECURITY REGISTERS\n");
|
||||||
// The following will only show something else than 0xff if it was programmed for a managed switch
|
// The following will only show something else than 0xff if it was programmed for a managed switch
|
||||||
flash_region.addr = 0x0001000;
|
flash_region.addr = 0x0001000;
|
||||||
@@ -680,25 +711,7 @@ void cmd_parser(void) __banked
|
|||||||
flash_region.len = 20;
|
flash_region.len = 20;
|
||||||
flash_write_bytes(flash_buf);
|
flash_write_bytes(flash_buf);
|
||||||
} else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
} else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
||||||
print_string("\nPORT ");
|
parse_port();
|
||||||
uint8_t p = cmd_buffer[cmd_words_b[1]] - '1';
|
|
||||||
print_byte(p);
|
|
||||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "2g5")) {
|
|
||||||
print_string(" 2.5G\n");
|
|
||||||
phy_set_mode(p, PHY_SPEED_2G5, 0, 0);
|
|
||||||
}
|
|
||||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "1g")) {
|
|
||||||
print_string(" 1G\n");
|
|
||||||
phy_set_mode(p, PHY_SPEED_1G, 0, 0);
|
|
||||||
}
|
|
||||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "auto")) {
|
|
||||||
print_string(" AUTO\n");
|
|
||||||
phy_set_mode(p, PHY_SPEED_AUTO, 0, 0);
|
|
||||||
}
|
|
||||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "off")) {
|
|
||||||
print_string(" OFF\n");
|
|
||||||
phy_set_mode(p, PHY_OFF, 0, 0);
|
|
||||||
}
|
|
||||||
} else if (cmd_compare(0, "ip")) {
|
} else if (cmd_compare(0, "ip")) {
|
||||||
print_string("Got ip command: ");
|
print_string("Got ip command: ");
|
||||||
if (!parse_ip(cmd_words_b[1]))
|
if (!parse_ip(cmd_words_b[1]))
|
||||||
@@ -742,8 +755,7 @@ void cmd_parser(void) __banked
|
|||||||
__xdata uint16_t pvid;
|
__xdata uint16_t pvid;
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
port = cmd_buffer[cmd_words_b[1]] - '1';
|
port = cmd_buffer[cmd_words_b[1]] - '1';
|
||||||
if (!isRTL8373)
|
port = machine.phys_to_log_port[port];
|
||||||
port = phys_to_log_port[port];
|
|
||||||
if (!atoi_short(&pvid, cmd_words_b[2]))
|
if (!atoi_short(&pvid, cmd_words_b[2]))
|
||||||
port_pvid_set(port, pvid);
|
port_pvid_set(port, pvid);
|
||||||
} else if (cmd_compare(0, "vlan")) {
|
} else if (cmd_compare(0, "vlan")) {
|
||||||
@@ -770,8 +782,7 @@ void cmd_parser(void) __banked
|
|||||||
int8_t port = -1;
|
int8_t port = -1;
|
||||||
if (cmd_words_b[3] > 0) {
|
if (cmd_words_b[3] > 0) {
|
||||||
port = cmd_buffer[cmd_words_b[2]] - '1';
|
port = cmd_buffer[cmd_words_b[2]] - '1';
|
||||||
if (!isRTL8373)
|
port = machine.phys_to_log_port[port];
|
||||||
port = phys_to_log_port[port];
|
|
||||||
}
|
}
|
||||||
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
|
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
|
||||||
if (port >= 0)
|
if (port >= 0)
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ Changes I found with my board vs [Managed version](https://github.com/up-n-atom/
|
|||||||
We need to make a `Best`-BOM variant so we can use all the featues.
|
We need to make a `Best`-BOM variant so we can use all the featues.
|
||||||
|
|
||||||
# Connectors
|
# Connectors
|
||||||
|
|
||||||
|
## J4
|
||||||
|
|
||||||
|
* Location: Left SFP connector `J4`.
|
||||||
|
* Connected to: 10GMAC number 8, second SDS.
|
||||||
|
|
||||||
|`J4` SFP1 PINs | Signal | Component | GPIO | Notes |
|
|`J4` SFP1 PINs | Signal | Component | GPIO | Notes |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
|2| TX_FAULT | B-R262 | --- | |
|
|2| TX_FAULT | B-R262 | --- | |
|
||||||
@@ -45,6 +51,11 @@ Changes I found with my board vs [Managed version](https://github.com/up-n-atom/
|
|||||||
|8| LOS | B-R258, T-R270 | GPIO37 | |
|
|8| LOS | B-R258, T-R270 | GPIO37 | |
|
||||||
|9| TO? | B-R256 | --- | |
|
|9| TO? | B-R256 | --- | |
|
||||||
|
|
||||||
|
## J2
|
||||||
|
|
||||||
|
* Location: Right SFP connector `J2`.
|
||||||
|
* Connected to: 10GMAC number 3, first SDS.
|
||||||
|
|
||||||
|`J2` SFP2 PINs | Signal | Component | GPIO | Notes |
|
|`J2` SFP2 PINs | Signal | Component | GPIO | Notes |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
|2| TX_FAULT | B-R70 | --- | |
|
|2| TX_FAULT | B-R70 | --- | |
|
||||||
|
|||||||
+3
-3
@@ -2,7 +2,7 @@ var txG = new BigInt64Array(10);
|
|||||||
var txB = new BigInt64Array(10);
|
var txB = new BigInt64Array(10);
|
||||||
var rxG = new BigInt64Array(10);
|
var rxG = new BigInt64Array(10);
|
||||||
var rxB = new BigInt64Array(10);
|
var rxB = new BigInt64Array(10);
|
||||||
const linkS = ["Disabled", "No Link", "100M", "1000M", "NO", "NO", "2.5G"];
|
const linkS = ["Disabled", "No Link", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
|
||||||
var pState = new Int8Array(10);
|
var pState = new Int8Array(10);
|
||||||
var pIsSFP = new Int8Array(10);
|
var pIsSFP = new Int8Array(10);
|
||||||
var numPorts = 0;
|
var numPorts = 0;
|
||||||
@@ -40,9 +40,9 @@ function update() {
|
|||||||
} else {
|
} else {
|
||||||
psvg.style.opacity = 1.0;
|
psvg.style.opacity = 1.0;
|
||||||
pState[n] = p.link;
|
pState[n] = p.link;
|
||||||
if (p.link == 5) {
|
if (p.link == 4 || p.link == 5 || p.link == 6) {
|
||||||
leds[0].style.fill = "green"; leds[1].style.fill = "orange";
|
leds[0].style.fill = "green"; leds[1].style.fill = "orange";
|
||||||
} else if (p.link == 2) {
|
} else if (p.link == 1 || p.link == 2 || p.link == 3) {
|
||||||
leds[0].style.fill = "green"; leds[1].style.fill = "green";
|
leds[0].style.fill = "green"; leds[1].style.fill = "green";
|
||||||
} else {
|
} else {
|
||||||
leds[0].style.fill = "black"; leds[1].style.fill = "black";
|
leds[0].style.fill = "black"; leds[1].style.fill = "black";
|
||||||
|
|||||||
+51
-47
@@ -10,11 +10,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../phy.h"
|
#include "../phy.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
#include "../machine.h"
|
||||||
#include "page_impl.h"
|
#include "page_impl.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
|
|
||||||
|
extern __code const struct machine machine;
|
||||||
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
||||||
extern __xdata uint16_t slen;
|
extern __xdata uint16_t slen;
|
||||||
extern __xdata uint16_t cont_len;
|
extern __xdata uint16_t cont_len;
|
||||||
@@ -22,15 +24,8 @@ extern __xdata uint32_t cont_addr;
|
|||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
||||||
extern __code struct uip_eth_addr uip_ethaddr;
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
extern __code uint8_t log_to_phys_port[9];
|
|
||||||
extern __code uint8_t phys_to_log_port[6];
|
|
||||||
|
|
||||||
extern __xdata uint8_t minPort;
|
|
||||||
extern __xdata uint8_t maxPort;
|
|
||||||
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 isRTL8373;
|
|
||||||
extern __xdata uint8_t sfp_pins_last;
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
||||||
|
|
||||||
@@ -139,6 +134,20 @@ void reg_to_html(register uint16_t reg)
|
|||||||
sfr_data_to_html();
|
sfr_data_to_html();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_sfp_info(uint8_t sfp)
|
||||||
|
{
|
||||||
|
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
|
||||||
|
for (uint8_t i = 20; i < 60; i++) {
|
||||||
|
if (i >= 36 && i < 40) // Skip Non-ASCII codes
|
||||||
|
continue;
|
||||||
|
uint8_t c = sfp_read_reg(sfp, i);
|
||||||
|
if (c && c != 0xa0) // a0 is the byte read from a non-existant I2C EEPROM
|
||||||
|
char_to_html(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_basic_info(void)
|
void send_basic_info(void)
|
||||||
{
|
{
|
||||||
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||||
@@ -167,7 +176,17 @@ void send_basic_info(void)
|
|||||||
byte_to_html(uip_ethaddr.addr[5]);
|
byte_to_html(uip_ethaddr.addr[5]);
|
||||||
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, VERSION_SW);
|
slen += strtox(outbuf + slen, VERSION_SW);
|
||||||
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"SWGT024-V2.0\"}");
|
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
||||||
|
slen += strtox(outbuf + slen, machine.machine_name);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
||||||
|
send_sfp_info(0);
|
||||||
|
char_to_html('"');
|
||||||
|
if (machine.n_sfp == 2) {
|
||||||
|
slen += strtox(outbuf + slen, ",\"sfp_slot_1\":\"");
|
||||||
|
send_sfp_info(1);
|
||||||
|
char_to_html('"');
|
||||||
|
}
|
||||||
|
char_to_html('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -198,7 +217,7 @@ void send_counters(char port)
|
|||||||
print_string("sending counters\n");
|
print_string("sending counters\n");
|
||||||
|
|
||||||
port--;
|
port--;
|
||||||
uint8_t i = isRTL8373 ? port - 1: phys_to_log_port[port];
|
uint8_t i = machine.phys_to_log_port[port];
|
||||||
slen += strtox(outbuf + slen, "{\"portNum\":");
|
slen += strtox(outbuf + slen, "{\"portNum\":");
|
||||||
itoa_html(i + 1);
|
itoa_html(i + 1);
|
||||||
for (uint8_t j = 0; j < 0x3f; j++) {
|
for (uint8_t j = 0; j < 0x3f; j++) {
|
||||||
@@ -226,10 +245,7 @@ void send_mirror(void)
|
|||||||
} else {
|
} else {
|
||||||
slen += strtox(outbuf + slen, "{\"enabled\":0,\"mPort\":");
|
slen += strtox(outbuf + slen, "{\"enabled\":0,\"mPort\":");
|
||||||
}
|
}
|
||||||
if (!isRTL8373)
|
itoa_html(machine.log_to_phys_port[mPort >> 1]);
|
||||||
itoa_html(log_to_phys_port[mPort >> 1]);
|
|
||||||
else
|
|
||||||
itoa_html((mPort >> 1) + 1);
|
|
||||||
|
|
||||||
reg_read_m(RTL837x_MIRROR_CONF);
|
reg_read_m(RTL837x_MIRROR_CONF);
|
||||||
uint16_t m = sfr_data[0];
|
uint16_t m = sfr_data[0];
|
||||||
@@ -286,14 +302,11 @@ void send_eee(void)
|
|||||||
uint8_t eee_ablty = sfr_data[3];
|
uint8_t eee_ablty = sfr_data[3];
|
||||||
|
|
||||||
char_to_html('[');
|
char_to_html('[');
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
slen += strtox(outbuf + slen, "{\"portNum\":");
|
slen += strtox(outbuf + slen, "{\"portNum\":");
|
||||||
if (!isRTL8373)
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
itoa_html(log_to_phys_port[i]);
|
|
||||||
else
|
|
||||||
itoa_html(i + 1);
|
|
||||||
|
|
||||||
if (IS_SFP(i)) {
|
if (machine.is_sfp[i]) {
|
||||||
slen += strtox(outbuf + slen, ",\"isSFP\":1");
|
slen += strtox(outbuf + slen, ",\"isSFP\":1");
|
||||||
} else {
|
} else {
|
||||||
slen += strtox(outbuf + slen, ",\"isSFP\":0,\"eee\":\"");
|
slen += strtox(outbuf + slen, ",\"isSFP\":0,\"eee\":\"");
|
||||||
@@ -321,7 +334,7 @@ void send_eee(void)
|
|||||||
bool_to_html(eee_ablty & (1 << i));
|
bool_to_html(eee_ablty & (1 << i));
|
||||||
}
|
}
|
||||||
char_to_html('}');
|
char_to_html('}');
|
||||||
if (i < maxPort)
|
if (i < machine.max_port)
|
||||||
char_to_html(',');
|
char_to_html(',');
|
||||||
else
|
else
|
||||||
char_to_html(']');
|
char_to_html(']');
|
||||||
@@ -335,38 +348,29 @@ void send_status(void)
|
|||||||
print_string("sending status\n");
|
print_string("sending status\n");
|
||||||
char_to_html('[');
|
char_to_html('[');
|
||||||
|
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
slen += strtox(outbuf + slen, "{\"portNum\":");
|
slen += strtox(outbuf + slen, "{\"portNum\":");
|
||||||
if (!isRTL8373)
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
itoa_html(log_to_phys_port[i]);
|
|
||||||
else
|
|
||||||
itoa_html(i + 1);
|
|
||||||
|
|
||||||
if (IS_SFP(i)) {
|
if (machine.is_sfp[i]) {
|
||||||
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
|
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
|
||||||
bool_to_html(!((sfp_pins_last >> (i == maxPort ? 0 : 4)) & 1));
|
bool_to_html(!(sfp_pins_last & (0x1 << ((machine.is_sfp[i] - 1) << 2))));
|
||||||
|
|
||||||
slen += strtox(outbuf + slen, ",\"link\":");
|
|
||||||
uint8_t rate = sfp_read_reg(i == maxPort ? 0 : 1, 12);
|
|
||||||
if (rate == 0xd)
|
|
||||||
char_to_html('2'); // 1000BX
|
|
||||||
else if (rate == 0x1f)
|
|
||||||
char_to_html('5'); // 2G5
|
|
||||||
else if (rate > 0x65 && rate < 0x70)
|
|
||||||
char_to_html('4'); // 10G "4" is not a valid value for port LINK speed
|
|
||||||
else
|
|
||||||
char_to_html('1'); // 100M ???
|
|
||||||
} else {
|
} else {
|
||||||
slen += strtox(outbuf + slen, ",\"isSFP\":0,\"enabled\":");
|
slen += strtox(outbuf + slen, ",\"isSFP\":0,\"enabled\":");
|
||||||
phy_read(i, 0x1f, 0xa610);
|
phy_read(i, 0x1f, 0xa610);
|
||||||
bool_to_html(SFR_DATA_8 == 0x20);
|
bool_to_html(SFR_DATA_8 == 0x20);
|
||||||
|
|
||||||
slen += strtox(outbuf + slen, ",\"link\":");
|
|
||||||
reg_read_m(RTL837X_REG_LINKS);
|
|
||||||
uint8_t b = sfr_data[3 - (i >> 1)];
|
|
||||||
b = (i & 1) ? b >> 4 : b & 0xf;
|
|
||||||
char_to_html('0' + b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slen += strtox(outbuf + slen, ",\"link\":");
|
||||||
|
|
||||||
|
if (i < 8)
|
||||||
|
reg_read_m(RTL837X_REG_LINKS);
|
||||||
|
else
|
||||||
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
|
uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
|
||||||
|
b = (i & 1) ? b >> 4 : b & 0xf;
|
||||||
|
char_to_html('0' + b);
|
||||||
|
|
||||||
STAT_GET(STAT_COUNTER_TX_PKTS, i);
|
STAT_GET(STAT_COUNTER_TX_PKTS, i);
|
||||||
slen += strtox(outbuf + slen, ",\"txG\":\"0x");
|
slen += strtox(outbuf + slen, ",\"txG\":\"0x");
|
||||||
reg_to_html(RTL837X_STAT_V_HIGH);
|
reg_to_html(RTL837X_STAT_V_HIGH);
|
||||||
@@ -385,7 +389,7 @@ void send_status(void)
|
|||||||
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
|
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
|
||||||
reg_to_html(RTL837X_STAT_V_HIGH); // 32bit RX packet errors
|
reg_to_html(RTL837X_STAT_V_HIGH); // 32bit RX packet errors
|
||||||
slen += strtox(outbuf + slen, "\"}");
|
slen += strtox(outbuf + slen, "\"}");
|
||||||
if (i < maxPort)
|
if (i < machine.max_port)
|
||||||
char_to_html(',');
|
char_to_html(',');
|
||||||
else
|
else
|
||||||
char_to_html(']');
|
char_to_html(']');
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
#ifdef MACHINE_KP_9000_6XHML_X2
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "keepLink KP-9000-6XHML-X2",
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = 50,
|
||||||
|
.sfp_port[0].pin_los = 10,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = 1,
|
||||||
|
.sfp_port[1].pin_detect = 30,
|
||||||
|
.sfp_port[1].pin_los = 37,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = 0,
|
||||||
|
.reset_pin = 46,
|
||||||
|
};
|
||||||
|
#elif defined MACHINE_KP_9000_6XH_X
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "keepLink KP-9000-6XH-X",
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = 30,
|
||||||
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = 0,
|
||||||
|
};
|
||||||
|
#elif defined MACHINE_KP_9000_9XH_X_EU
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "keepLink KP-9000-6XH-X-EU",
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = 30,
|
||||||
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = 0,
|
||||||
|
};
|
||||||
|
#elif defined MACHINE_SWGT024_V2_0
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "SWGT024 V2.0",
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 6, 5, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp= {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
// Left SFP port (J4)
|
||||||
|
.sfp_port[0].pin_detect = 30,
|
||||||
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = 0, /* GPIO 39 */
|
||||||
|
// Right SFP port (J2)
|
||||||
|
.sfp_port[1].pin_detect = 50,
|
||||||
|
.sfp_port[1].pin_los = 51,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = 1, /* GPIO 40 */
|
||||||
|
.reset_pin = 36,
|
||||||
|
};
|
||||||
|
#elif defined DEFAULT_8C_1SFP
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "8+1 SFP Port Switch",
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = 30,
|
||||||
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef _MACHINE_H_
|
||||||
|
#define _MACHINE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select your machine type below
|
||||||
|
*/
|
||||||
|
#define MACHINE_KP_9000_6XHML_X2
|
||||||
|
// #define MACHINE_KP_9000_6XH_X
|
||||||
|
// #define MACHINE_KP_9000_9XH_X_EU
|
||||||
|
// #define MACHINE_SWGT024_V2_0
|
||||||
|
// #define MACHINE_HORACO_ZX_SG4T2
|
||||||
|
|
||||||
|
// #define DEFAULT_8C_1SFP
|
||||||
|
|
||||||
|
// #define DEFAULT_5C_1SFP
|
||||||
|
|
||||||
|
struct sfp_port
|
||||||
|
{
|
||||||
|
uint8_t pin_detect; // gpio number 0-63, 0xFF = don't have it?
|
||||||
|
uint8_t pin_los; // gpio number 0-63, 0xFF = don't have it?
|
||||||
|
uint8_t sds;
|
||||||
|
uint8_t i2c;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct machine {
|
||||||
|
char machine_name[30];
|
||||||
|
uint8_t isRTL8373;
|
||||||
|
uint8_t min_port;
|
||||||
|
uint8_t max_port;
|
||||||
|
uint8_t n_sfp;
|
||||||
|
uint8_t log_to_phys_port[9];
|
||||||
|
uint8_t phys_to_log_port[9]; // Starts at 0 for port 1
|
||||||
|
uint8_t is_sfp[9]; // 0 for non-SFP ports 1 or 2 for the I2C port number
|
||||||
|
// sfp_port[0] is the first SFP-port from the left on the device, sfp_port[1] the next if present
|
||||||
|
struct sfp_port sfp_port[2];
|
||||||
|
int8_t reset_pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
/*
|
/*
|
||||||
* Define PHY pages
|
* Define PHY pages
|
||||||
*/
|
*/
|
||||||
|
#define PHY_MMD_PMAPMD 1
|
||||||
#define PHY_MMD_AN 7
|
#define PHY_MMD_AN 7
|
||||||
#define PHY_SDS_CTRL 30
|
#define PHY_SDS_CTRL 30
|
||||||
#define PHY_MMD_CTRL 31
|
#define PHY_MMD_CTRL 31
|
||||||
|
|||||||
+5
-8
@@ -3,14 +3,15 @@
|
|||||||
|
|
||||||
#include "uip/uip-conf.h"
|
#include "uip/uip-conf.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
// This has to be set to the number of SFP+ ports, i.e. 1 or 2
|
|
||||||
#define NSFP 2
|
|
||||||
// SCL and SDA pin numbers for SFP cage 0 and SFP cage 1
|
// SCL and SDA pin numbers for SFP cage 0 and SFP cage 1
|
||||||
#define SCL_PIN 3
|
#define SCL_PIN 3
|
||||||
#define SDA_PIN_0 4
|
#define SDA_PIN_0 4
|
||||||
#define SDA_PIN_1 3
|
#define SDA_PIN_1 3
|
||||||
|
|
||||||
|
#define CPU_PORT 9
|
||||||
|
|
||||||
// Define Port-masks for 9-port devices and 6-port devices
|
// Define Port-masks for 9-port devices and 6-port devices
|
||||||
#define PMASK_9 0x1ff
|
#define PMASK_9 0x1ff
|
||||||
#define PMASK_6 0x1f8
|
#define PMASK_6 0x1f8
|
||||||
@@ -41,12 +42,6 @@
|
|||||||
// This is the standard size of an Ethernet frame header
|
// This is the standard size of an Ethernet frame header
|
||||||
#define ETHER_HEADER_SIZE 14
|
#define ETHER_HEADER_SIZE 14
|
||||||
|
|
||||||
#if NSFP == 1
|
|
||||||
#define IS_SFP(port) (i == maxPort)
|
|
||||||
#else
|
|
||||||
#define IS_SFP(port) (i == maxPort || i == 3)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONFIG_START 0x70000
|
#define CONFIG_START 0x70000
|
||||||
#define CONFIG_LEN 0x1000
|
#define CONFIG_LEN 0x1000
|
||||||
#define CODE0_SIZE 0x4000
|
#define CODE0_SIZE 0x4000
|
||||||
@@ -106,5 +101,7 @@ void print_string_x(__xdata char *p);
|
|||||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||||
void get_random_32(void);
|
void get_random_32(void);
|
||||||
void read_reg_timer(uint32_t * tmr);
|
void read_reg_timer(uint32_t * tmr);
|
||||||
|
void sfp_print_info(uint8_t sfp);
|
||||||
|
bool gpio_pin_test(uint8_t pin);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -283,7 +283,7 @@ void flash_read_bulk(__xdata uint8_t *dst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void flash_read_security()
|
void flash_read_security(void)
|
||||||
{
|
{
|
||||||
while (flash_read_status() & 0x1);
|
while (flash_read_status() & 0x1);
|
||||||
|
|
||||||
|
|||||||
+6
-12
@@ -11,12 +11,9 @@
|
|||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
extern __xdata uint8_t minPort;
|
extern __code struct machine machine;
|
||||||
extern __xdata uint8_t maxPort;
|
|
||||||
extern __xdata uint8_t nSFPPorts;
|
|
||||||
extern __xdata uint8_t cpuPort;
|
|
||||||
extern __xdata uint8_t isRTL8373;
|
|
||||||
|
|
||||||
void igmp_setup(void) __banked
|
void igmp_setup(void) __banked
|
||||||
{
|
{
|
||||||
@@ -24,19 +21,16 @@ void igmp_setup(void) __banked
|
|||||||
|
|
||||||
// For now, forward all unkown MC pkts (2 bits per port. 00: flood via floodmask, 01: drop, 10: trap, 11: to rport)
|
// For now, forward all unkown MC pkts (2 bits per port. 00: flood via floodmask, 01: drop, 10: trap, 11: to rport)
|
||||||
REG_SET(RTL837X_MC_LOOKUPMISS_ACTIONS, 0x00000000); //0x4f78
|
REG_SET(RTL837X_MC_LOOKUPMISS_ACTIONS, 0x00000000); //0x4f78
|
||||||
|
|
||||||
// Define ports where unknown MC addresses are flooded to:
|
// Define ports where unknown MC addresses are flooded to:
|
||||||
if (isRTL8373) {
|
REG_SET(RTL837X_MC_FLOODMASK, machine.isRTL8373 ? PMASK_9 : PMASK_6);
|
||||||
REG_SET(RTL837X_MC_FLOODMASK, PMASK_9); // R5368-000001f8
|
|
||||||
} else {
|
|
||||||
REG_SET(RTL837X_MC_FLOODMASK, PMASK_6);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable lookup of IPv4 MC addresses in table
|
// Enable lookup of IPv4 MC addresses in table
|
||||||
reg_bit_set(RTL837X_L2_CTRL, 3); // 0x5350
|
reg_bit_set(RTL837X_L2_CTRL, 3); // 0x5350
|
||||||
|
|
||||||
// Configure per-port IGMP configuration, bits 0-10 enable MC protocol snooping,
|
// Configure per-port IGMP configuration, bits 0-10 enable MC protocol snooping,
|
||||||
// bits 16-24 configure max MC group used by that port. For now all protocols are flooded (01)
|
// bits 16-24 configure max MC group used by that port. For now all protocols are flooded (01)
|
||||||
for (i = minPort; i <= maxPort; i++)
|
for (i = machine.min_port; i <= machine.max_port; i++)
|
||||||
REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), 0x00ff7c15);
|
REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), 0x00ff7c15);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +46,6 @@ void igmp_enable(void) __banked
|
|||||||
|
|
||||||
// Configure per-port IGMP configuration, bits 0-10 enable MC protocol snooping,
|
// Configure per-port IGMP configuration, bits 0-10 enable MC protocol snooping,
|
||||||
// bits 16-24 configure max MC group used by that port. Trap to CPU (10)
|
// bits 16-24 configure max MC group used by that port. Trap to CPU (10)
|
||||||
for (i = minPort; i <= maxPort; i++)
|
for (i = machine.min_port; i <= machine.max_port; i++)
|
||||||
REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), 0x00ff7c2a); // 0x00ff7000: Handling by ASIC (00)
|
REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), 0x00ff7c2a); // 0x00ff7000: Handling by ASIC (00)
|
||||||
}
|
}
|
||||||
|
|||||||
+175
-21
@@ -119,7 +119,7 @@ void phy_config(uint8_t phy) __banked
|
|||||||
|
|
||||||
// p031f.a442:043c P000008.1f00a442:0430
|
// p031f.a442:043c P000008.1f00a442:0430
|
||||||
// Unknown, but clear bits 2/3
|
// Unknown, but clear bits 2/3
|
||||||
phy_modify(phy, 0x1f, 0xa442, 0x0006, 0x0000);
|
phy_modify(phy, 0x1f, 0xa442, 0x000c, 0x0000);
|
||||||
delay(20);
|
delay(20);
|
||||||
|
|
||||||
// P000100.1e0075b5:e084
|
// P000100.1e0075b5:e084
|
||||||
@@ -182,49 +182,203 @@ void phy_config_8224(void) __banked
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set Speed, duplex and flow control mode of a PHY
|
* Set Speed of a PHY
|
||||||
* See e.g. RTL8221B datasheet
|
* See e.g. RTL8221B datasheet
|
||||||
*/
|
*/
|
||||||
void phy_set_mode(uint8_t port, uint8_t speed, uint8_t flow_control, uint8_t duplex) __banked
|
void phy_set_speed(uint8_t port, uint8_t speed) __banked
|
||||||
{
|
{
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
phy_read(port, 0x1f, 0xa610);
|
phy_read(port, PHY_MMD_CTRL, 0xa610);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (speed == PHY_OFF) {
|
if (speed == PHY_OFF) {
|
||||||
phy_write(port, 0x1f, 0xa610, v | 0x0800);
|
phy_write(port, PHY_MMD_CTRL, 0xa610, v | 0x0800);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Port is on, make sure of it:
|
// Port is on, make sure of it:
|
||||||
if (v & 0x0800)
|
if (v & 0x0800)
|
||||||
phy_write(port, 0x1f, 0xa610, v & 0xf7ff);
|
phy_write(port, PHY_MMD_CTRL, 0xa610, v & 0xf7ff);
|
||||||
|
|
||||||
if (speed == PHY_SPEED_AUTO) {
|
if (speed == PHY_SPEED_AUTO) {
|
||||||
// AN Advertisement Register (MMD 7.0x0010)
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
phy_write(port, PHY_MMD_AN, 0x10, 0x1001); // bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||||
|
phy_write(port, PHY_MMD_AN, 0x10, 0x15e1);
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
phy_write(port, PHY_MMD_AN, 0x20, 0x6081); // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
||||||
|
phy_write(port, PHY_MMD_AN, 0x20, 0x6081);
|
||||||
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
|
phy_modify(port, PHY_MMD_CTRL, 0xa412, 0x0000, 0x0200); // Loop timing enabled
|
||||||
phy_write(port, PHY_MMD_AN, 0x00, 0x3200); // Restart AN
|
phy_write(port, PHY_MMD_AN, 0x00, 0x3200); // Restart AN
|
||||||
} else {
|
} else {
|
||||||
// AN Control Register (MMD 7.0x0000)
|
// AN Control Register (MMD 7.0x0000)
|
||||||
phy_write(port, PHY_MMD_AN, 0x00, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
phy_write(port, PHY_MMD_AN, 0x00, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
||||||
// AN Advertisement Register (MMD 7.0x0010)
|
if (speed == PHY_SPEED_10M) {
|
||||||
phy_write(port, PHY_MMD_AN, 0x10, 0x1001); // bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
phy_write(port, PHY_MMD_AN, 0x20, 0x6001);
|
||||||
if (speed == PHY_SPEED_1G) {
|
phy_write(port, PHY_MMD_AN, 0x10, 0x1461);
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
phy_modify(port, PHY_MMD_CTRL, 0xa412, 0x0200, 0x0000);
|
||||||
phy_write(port, PHY_MMD_AN, 0x20, 0x6001); // bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
} else if (speed == PHY_SPEED_100M) {
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
phy_write(port, PHY_MMD_AN, 0x20, 0x6001);
|
||||||
phy_modify(port, 0x1f, 0xa412, 0x0000, 0x02000);
|
phy_write(port, PHY_MMD_AN, 0x10, 0x1581);
|
||||||
} else if (speed == PHY_SPEED_2G5) {
|
phy_modify(port, PHY_MMD_CTRL, 0xa412, 0x0200, 0x0000);
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
} else {
|
||||||
phy_write(port, PHY_MMD_AN, 0x20, 0x6081); // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||||
phy_modify(port, 0x1f, 0xa412, 0x02000, 0x0000);
|
phy_write(port, PHY_MMD_AN, 0x10, 0x1001);
|
||||||
|
if (speed == PHY_SPEED_1G) {
|
||||||
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
|
// bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
||||||
|
phy_write(port, PHY_MMD_AN, 0x20, 0x6001);
|
||||||
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
|
phy_modify(port, PHY_MMD_CTRL, 0xa412, 0x0000, 0x0200);
|
||||||
|
} else if (speed == PHY_SPEED_2G5) {
|
||||||
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
|
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
||||||
|
phy_write(port, PHY_MMD_AN, 0x20, 0x6081);
|
||||||
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
|
phy_modify(port, PHY_MMD_CTRL, 0xa412, 0x0200, 0x0000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
phy_write(port, PHY_MMD_AN, 0x00, 0x3200); // Enable AN
|
phy_write(port, PHY_MMD_AN, 0x00, 0x3000); // Enable AN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked
|
||||||
|
{
|
||||||
|
uint16_t v;
|
||||||
|
phy_read(port, PHY_MMD_AN, 0x00);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
||||||
|
phy_read(port, PHY_MMD_CTRL, 0xa400);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (fullduplex)
|
||||||
|
v |= 0x0100;
|
||||||
|
else
|
||||||
|
v &= 0xfeff;
|
||||||
|
phy_write(port, PHY_MMD_CTRL, 0xa400, v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Disable AN
|
||||||
|
phy_write(port, PHY_MMD_AN, 0x00, 0x2000);
|
||||||
|
phy_read(port, PHY_MMD_AN, 0x10);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & 0x0060) {
|
||||||
|
if (fullduplex)
|
||||||
|
phy_modify(port, PHY_MMD_AN, 0x10, 0xffbf, 0x0040);
|
||||||
|
else
|
||||||
|
phy_modify(port, PHY_MMD_AN, 0x10, 0xffdf, 0x0020);
|
||||||
|
}
|
||||||
|
if (v & 0x0180) {
|
||||||
|
if (fullduplex)
|
||||||
|
phy_modify(port, PHY_MMD_AN, 0x10, 0xfeff, 0x0100);
|
||||||
|
else
|
||||||
|
phy_modify(port, PHY_MMD_AN, 0x10, 0xff7f, 0x0080);
|
||||||
|
}
|
||||||
|
// Restart AN
|
||||||
|
phy_write(port, PHY_MMD_AN, 0x00, 0x3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void phy_show(uint8_t port) __banked
|
||||||
|
{
|
||||||
|
uint16_t v;
|
||||||
|
|
||||||
|
phy_read(port, PHY_MMD_AN, 0x00);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
||||||
|
phy_read(port, PHY_MMD_PMAPMD, 0);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
print_string("\nForced speed: "); print_short(v); write_char('\n');
|
||||||
|
uint8_t s1 = ((v & 0x40) ? 0x2 : 0x0) | ((v & 0x2000) ? 0x1 : 0x0);
|
||||||
|
uint8_t s2 = (v >> 2) & 0xf;
|
||||||
|
switch(s1) {
|
||||||
|
case 0:
|
||||||
|
print_string("10M\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
print_string("100M\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
print_string("1000M\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
switch (s2) {
|
||||||
|
case 0:
|
||||||
|
print_string("10G\n");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
print_string("2500M\n");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
print_string("5G\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_string("Unknown\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_string("Unknown\n");
|
||||||
|
}
|
||||||
|
phy_read(port, PHY_MMD_CTRL, 0xa400);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
print_string("Duplex: "); print_short(v); print_string(" enabled: ");
|
||||||
|
if (v & 0x100)
|
||||||
|
print_string("yes");
|
||||||
|
else
|
||||||
|
print_string("no");
|
||||||
|
write_char('\n');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
print_string("\nAN enabled, advertising:");
|
||||||
|
phy_read(port, PHY_MMD_AN, 0x10);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & 0x0040)
|
||||||
|
print_string(" 10Base-Half");
|
||||||
|
if (v & 0x0040)
|
||||||
|
print_string(" 10Base-Full");
|
||||||
|
if (v & 0x0080)
|
||||||
|
print_string(" 100Base-Half");
|
||||||
|
if (v & 0x0100)
|
||||||
|
print_string(" 100Base-Full");
|
||||||
|
phy_read(port, PHY_MMD_CTRL, 0xa412);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & 0x0200)
|
||||||
|
print_string(" 1000Base-Full");
|
||||||
|
phy_read(port, PHY_MMD_AN, 0x10);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & 0x0080)
|
||||||
|
print_string(" 2500BaseN-Full");
|
||||||
|
|
||||||
|
}
|
||||||
|
phy_read(port, PHY_MMD_AN, 0x13);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
print_string("\nLink Partner advertises:");
|
||||||
|
if (v & 0x0020)
|
||||||
|
print_string(" 10Base-Half");
|
||||||
|
if (v & 0x0040)
|
||||||
|
print_string(" 10Base-Full");
|
||||||
|
if (v & 0x0080)
|
||||||
|
print_string(" 100Base-Half");
|
||||||
|
if (v & 0x0100)
|
||||||
|
print_string(" 100Base-Full");
|
||||||
|
phy_read(port, PHY_MMD_CTRL, 0xa414);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & 0x0400)
|
||||||
|
print_string(" 1000Base-Half");
|
||||||
|
if (v & 0x0800)
|
||||||
|
print_string(" 1000Base-Full");
|
||||||
|
phy_read(port, PHY_MMD_AN, 33);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & 0x0020)
|
||||||
|
print_string(" 2500Base-Full");
|
||||||
|
if (v & 0x0040)
|
||||||
|
print_string(" 5000Base-Full");
|
||||||
|
if (v & 0x0800)
|
||||||
|
print_string(" 10GBase-Full");
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void phy_reset(uint8_t port) __banked
|
void phy_reset(uint8_t port) __banked
|
||||||
{
|
{
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
|||||||
+10
-4
@@ -1,15 +1,21 @@
|
|||||||
#ifndef _RTL837X_PHY_H_
|
#ifndef _RTL837X_PHY_H_
|
||||||
#define _RTL837X_PHY_H_
|
#define _RTL837X_PHY_H_
|
||||||
|
|
||||||
#define PHY_SPEED_AUTO 0x1
|
#define PHY_SPEED_10M 0x2
|
||||||
#define PHY_SPEED_1G 0x2
|
#define PHY_SPEED_100M 0x3
|
||||||
#define PHY_SPEED_2G5 0x3
|
#define PHY_SPEED_1G 0x4
|
||||||
|
#define PHY_SPEED_2G5 0x5
|
||||||
|
#define PHY_SPEED_5G 0x6
|
||||||
|
#define PHY_SPEED_10G 0x7
|
||||||
|
#define PHY_SPEED_AUTO 0x10
|
||||||
#define PHY_OFF 0xff
|
#define PHY_OFF 0xff
|
||||||
|
|
||||||
void rtl8224_phy_enable(void) __banked;
|
void rtl8224_phy_enable(void) __banked;
|
||||||
void phy_config(uint8_t phy) __banked;
|
void phy_config(uint8_t phy) __banked;
|
||||||
void phy_config_8224(void) __banked;
|
void phy_config_8224(void) __banked;
|
||||||
void phy_set_mode(uint8_t port, uint8_t speed, uint8_t flow_control, uint8_t duplex) __banked;
|
void phy_set_speed(uint8_t port, uint8_t speed) __banked;
|
||||||
|
void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked;
|
||||||
|
void phy_show(uint8_t port) __banked;
|
||||||
void phy_reset(uint8_t port) __banked;
|
void phy_reset(uint8_t port) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+67
-98
@@ -13,40 +13,20 @@
|
|||||||
#include "rtl837x_port.h"
|
#include "rtl837x_port.h"
|
||||||
#include "rtl837x_phy.h"
|
#include "rtl837x_phy.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
|
|
||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
extern __code uint16_t bit_mask[16];
|
extern __code uint16_t bit_mask[16];
|
||||||
extern __xdata uint8_t minPort;
|
extern __code struct machine machine;
|
||||||
extern __xdata uint8_t maxPort;
|
|
||||||
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 uint16_t vlan_ptr;
|
extern __xdata uint16_t vlan_ptr;
|
||||||
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
||||||
|
|
||||||
extern __xdata uint8_t isRTL8373;
|
|
||||||
|
|
||||||
__xdata uint32_t l2_head;
|
__xdata uint32_t l2_head;
|
||||||
|
|
||||||
// The mapping of logical to physical ports on the RTL8372
|
|
||||||
// Port 6 is always an SFP+ port. Port 5 may be RTL8221 or SFP+
|
|
||||||
__code uint8_t log_to_phys_port[9] = {
|
|
||||||
0, 0, 0, 5, 1, 2, 3, 4, 6
|
|
||||||
};
|
|
||||||
|
|
||||||
#if NSFP == 2
|
|
||||||
__code uint8_t is_sfp[9] = {
|
|
||||||
0, 0, 0, 1, 0, 0, 0, 0, 1
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
__code uint8_t is_sfp[9] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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("\nport_mirror_set called \n");
|
print_string("\nport_mirror_set called \n");
|
||||||
@@ -153,7 +133,7 @@ void vlan_create(register uint16_t vlan, register uint16_t members, register uin
|
|||||||
|
|
||||||
uint16_t a = (~members) ^ tagged ^ members;
|
uint16_t a = (~members) ^ tagged ^ members;
|
||||||
// On RTL8372, port-bits 0-2 must be 0, although they are not members
|
// On RTL8372, port-bits 0-2 must be 0, although they are not members
|
||||||
if (!isRTL8373) {
|
if (!machine.isRTL8373) {
|
||||||
a &= 0x1f8;
|
a &= 0x1f8;
|
||||||
tagged &= 0x3f8;
|
tagged &= 0x3f8;
|
||||||
}
|
}
|
||||||
@@ -184,18 +164,15 @@ void vlan_setup(void) __banked
|
|||||||
vlan_names[0] = 0;
|
vlan_names[0] = 0;
|
||||||
|
|
||||||
// Initialize VLAN table for VLAN 1, by disabling that entry
|
// Initialize VLAN table for VLAN 1, by disabling that entry
|
||||||
if (isRTL8373) {
|
REG_SET(RTL837x_TBL_DATA_IN_A, machine.isRTL8373? 0x0007ffff : 0x0007e3f8);
|
||||||
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);
|
||||||
} while (sfr_data[3] & TBL_EXECUTE);
|
} while (sfr_data[3] & TBL_EXECUTE);
|
||||||
|
|
||||||
// Set PVID 1 for every port. TODO: Skip unused ports!
|
// 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 (+1)
|
for (uint8_t i = machine.min_port; i <= machine.max_port + 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_short(reg); write_char('=');
|
print_byte(i); write_char(':'); write_char(' '); print_short(reg); write_char('=');
|
||||||
@@ -231,11 +208,8 @@ void vlan_setup(void) __banked
|
|||||||
REG_SET(RTL837X_VLAN_L2_LRN_DIS_1, 0);
|
REG_SET(RTL837X_VLAN_L2_LRN_DIS_1, 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, machine.isRTL8373? 0x0207ffff : 0x0207e3f8); // 02: Entry valid, 7...: 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);
|
||||||
@@ -266,11 +240,7 @@ uint8_t port_l2_forget(void) __banked
|
|||||||
REG_SET(RTL837x_L2_TBL_FLUSH_CNF, 0x0);
|
REG_SET(RTL837x_L2_TBL_FLUSH_CNF, 0x0);
|
||||||
|
|
||||||
// Flush L2 table for all ports by setting the ports and the flush-exec bit (bit 16)
|
// Flush L2 table for all ports by setting the ports and the flush-exec bit (bit 16)
|
||||||
if (isRTL8373) {
|
REG_SET(RTL837x_L2_TBL_FLUSH_CTRL, L2_TBL_FLUSH_EXEC | (machine.isRTL8373 ? PMASK_9 : PMASK_6));
|
||||||
REG_SET(RTL837x_L2_TBL_FLUSH_CTRL, L2_TBL_FLUSH_EXEC | PMASK_9);
|
|
||||||
} else {
|
|
||||||
REG_SET(RTL837x_L2_TBL_FLUSH_CTRL, L2_TBL_FLUSH_EXEC | PMASK_6);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for flush completed
|
// Wait for flush completed
|
||||||
do {
|
do {
|
||||||
@@ -358,18 +328,14 @@ void port_l2_setup(void) __banked
|
|||||||
|
|
||||||
port_l2_forget();
|
port_l2_forget();
|
||||||
|
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
// Limit the number of automatically learned MAC-Entries per port to 0x1040
|
// Limit the number of automatically learned MAC-Entries per port to 0x1040
|
||||||
uint16_t reg = RTL837X_L2_LRN_PORT_CONSTRAINT + (i << 2);
|
uint16_t reg = RTL837X_L2_LRN_PORT_CONSTRAINT + (i << 2);
|
||||||
REG_SET(reg, 0x00001040);
|
REG_SET(reg, 0x00001040);
|
||||||
|
|
||||||
// All ports may communicate with each other and CPU-Port
|
// All ports may communicate with each other and CPU-Port
|
||||||
reg = RTL837X_PORT_ISOLATION_BASE + (i << 2);
|
reg = RTL837X_PORT_ISOLATION_BASE + (i << 2);
|
||||||
if(isRTL8373) {
|
REG_SET(reg, PMASK_CPU | (machine.isRTL8373? PMASK_9 : PMASK_6));
|
||||||
REG_SET(reg, PMASK_9 | PMASK_CPU);
|
|
||||||
} else {
|
|
||||||
REG_SET(reg, PMASK_6 | PMASK_CPU);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// When maximim entries learned, then simply flood the packet
|
// When maximim entries learned, then simply flood the packet
|
||||||
reg_bit_set(RTL837X_L2_LRN_PORT_CONSTRT_ACT, 0);
|
reg_bit_set(RTL837X_L2_LRN_PORT_CONSTRT_ACT, 0);
|
||||||
@@ -381,55 +347,58 @@ void port_l2_setup(void) __banked
|
|||||||
void port_stats_print(void) __banked
|
void port_stats_print(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\n Port\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\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 = machine.min_port; i <= machine.max_port; i++) {
|
||||||
write_char('1' + i); write_char('\t');
|
write_char('0' + machine.log_to_phys_port[i]); write_char('\t');
|
||||||
phy_read(i, 0x1f, 0xa610); // p001f.a610:2058
|
|
||||||
if (i <= maxPort - nSFPPorts) {
|
if (!machine.is_sfp[i]) {
|
||||||
|
phy_read(i, 0x1f, 0xa610);
|
||||||
if (SFR_DATA_8 == 0x20)
|
if (SFR_DATA_8 == 0x20)
|
||||||
print_string("On\t");
|
print_string("On\t");
|
||||||
else
|
else
|
||||||
print_string("Off\t");
|
print_string("Off\t");
|
||||||
|
} else { // An SFP Module
|
||||||
|
if (i != 3) {
|
||||||
|
reg_read_m(RTL837X_REG_GPIO_00_31_INPUT);
|
||||||
|
if (!(sfr_data[0] & 0x40)) {
|
||||||
|
print_string("SFP OK\t");
|
||||||
|
} else {
|
||||||
|
print_string("NO SFP\t");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reg_read_m(RTL837X_REG_GPIO_32_63_INPUT);
|
||||||
|
if (!(sfr_data[1] & 0x04)) {
|
||||||
|
print_string("SFP OK\t");
|
||||||
|
} else {
|
||||||
|
print_string("NO SFP\t");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < 8)
|
||||||
reg_read_m(RTL837X_REG_LINKS);
|
reg_read_m(RTL837X_REG_LINKS);
|
||||||
uint8_t b = sfr_data[3 - (i >> 1)];
|
else
|
||||||
b = (i & 1) ? b >> 4 : b & 0xf;
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
switch (b) {
|
uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
|
||||||
case 0:
|
b = (i & 1) ? b >> 4 : b & 0xf;
|
||||||
print_string("Down\t");
|
switch (b) {
|
||||||
break;
|
case 0:
|
||||||
case 1:
|
print_string("Down\t");
|
||||||
print_string("100M\t");
|
break;
|
||||||
break;
|
case 1:
|
||||||
case 2:
|
print_string("100M\t");
|
||||||
print_string("1000M\t");
|
break;
|
||||||
break;
|
case 2:
|
||||||
case 5:
|
print_string("1000M\t");
|
||||||
print_string("2.5G\t");
|
break;
|
||||||
break;
|
case 4:
|
||||||
default:
|
print_string("10G\t");
|
||||||
print_string("Up\t");
|
break;
|
||||||
break;
|
case 5:
|
||||||
}
|
print_string("2.5G\t");
|
||||||
} else { // An SFP Module TODO: This is for 1 module devices
|
break;
|
||||||
reg_read_m(RTL837X_REG_GPIO_00_31_INPUT);
|
default:
|
||||||
if (!(sfr_data[0] & 0x40)) {
|
print_string("Up\t");
|
||||||
print_string("SFP OK\t");
|
break;
|
||||||
} else {
|
|
||||||
print_string("NO SFP\t");
|
|
||||||
}
|
|
||||||
reg_read_m(RTL837X_REG_GPIO_32_63_INPUT);
|
|
||||||
if (sfr_data[3] & 0x20) {
|
|
||||||
print_string("Down\t");
|
|
||||||
} else {
|
|
||||||
uint8_t rate = sfp_read_reg(0, 12);
|
|
||||||
if (rate == 0xd)
|
|
||||||
print_string("1000BX\t");
|
|
||||||
else if (rate == 0x1f)
|
|
||||||
print_string("2500G\t");
|
|
||||||
else if (rate > 0x65 && rate < 0x70)
|
|
||||||
print_string("10G\t");
|
|
||||||
else
|
|
||||||
print_string("Up\t");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
STAT_GET(0x2f, i);
|
STAT_GET(0x2f, i);
|
||||||
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
|
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
|
||||||
@@ -449,14 +418,14 @@ void port_stats_print(void) __banked
|
|||||||
|
|
||||||
void port_isolate(register uint8_t port, __xdata uint16_t pmask)
|
void port_isolate(register uint8_t port, __xdata uint16_t pmask)
|
||||||
{
|
{
|
||||||
if (port <= maxPort)
|
if (port <= machine.max_port)
|
||||||
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
|
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t port_isolation_get(register uint8_t port)
|
uint16_t port_isolation_get(register uint8_t port)
|
||||||
{
|
{
|
||||||
if (port > maxPort)
|
if (port > machine.max_port)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
reg_read_m(RTL837X_PORT_ISOLATION_BASE + (port << 2));
|
reg_read_m(RTL837X_PORT_ISOLATION_BASE + (port << 2));
|
||||||
@@ -466,7 +435,7 @@ uint16_t port_isolation_get(register uint8_t port)
|
|||||||
|
|
||||||
void port_eee_enable(uint8_t port) __banked
|
void port_eee_enable(uint8_t port) __banked
|
||||||
{
|
{
|
||||||
if (is_sfp[port])
|
if (machine.is_sfp[port])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5);
|
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5);
|
||||||
@@ -480,7 +449,7 @@ void port_eee_enable(uint8_t port) __banked
|
|||||||
|
|
||||||
void port_eee_disable(uint8_t port) __banked
|
void port_eee_disable(uint8_t port) __banked
|
||||||
{
|
{
|
||||||
if (is_sfp[port])
|
if (machine.is_sfp[port])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
print_string("EEE off for "); print_byte(port); write_char('\n');
|
print_string("EEE off for "); print_byte(port); write_char('\n');
|
||||||
@@ -495,9 +464,9 @@ void port_eee_disable(uint8_t port) __banked
|
|||||||
|
|
||||||
void port_eee_status(uint8_t port) __banked
|
void port_eee_status(uint8_t port) __banked
|
||||||
{
|
{
|
||||||
print_string("Port: "); write_char('0' + log_to_phys_port[port]);
|
print_string("Port: "); write_char('0' + machine.log_to_phys_port[port]);
|
||||||
print_string(": ");
|
print_string(": ");
|
||||||
if (is_sfp[port]) {
|
if (machine.is_sfp[port]) {
|
||||||
print_string("SFP\n");
|
print_string("SFP\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -550,7 +519,7 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
|
|
||||||
void port_eee_enable_all(void) __banked
|
void port_eee_enable_all(void) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_eee_enable(i);
|
port_eee_enable(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,7 +527,7 @@ void port_eee_enable_all(void) __banked
|
|||||||
|
|
||||||
void port_eee_disable_all(void) __banked
|
void port_eee_disable_all(void) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_eee_disable(i);
|
port_eee_disable(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -566,7 +535,7 @@ void port_eee_disable_all(void) __banked
|
|||||||
|
|
||||||
void port_eee_status_all(void) __banked
|
void port_eee_status_all(void) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_eee_status(i);
|
port_eee_status(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-6
@@ -1,18 +1,30 @@
|
|||||||
#ifndef _RTL837X_REGS_H_
|
#ifndef _RTL837X_REGS_H_
|
||||||
#define _RTL837X_REGS_H_
|
#define _RTL837X_REGS_H_
|
||||||
|
|
||||||
#define RTL837X_REG_HW_CONF 0x6040
|
#define RTL837X_REG_CHIP_INFO 0x000c
|
||||||
|
#define RTL837X_REG_RESET 0x0024
|
||||||
|
#define RESET_SOC_BIT 0
|
||||||
|
#define RESET_NIC_BIT 2
|
||||||
|
|
||||||
|
#define RTL837X_REG_HW_CONF 0x6040
|
||||||
// Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer
|
// Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer
|
||||||
|
|
||||||
#define RTL837X_REG_LED_MODE 0x6520
|
#define RTL837X_REG_LED_MODE 0x6520
|
||||||
// Defines the LED Mode for steering the Port LEDS and the System LED
|
// Defines the LED Mode for steering the Port LEDS and the System LED
|
||||||
// BIT 17 set: LED solid on
|
// BIT 17 set: LED solid on
|
||||||
// Bytes 0/1 hold the LED mode, e.g. serial, RTL8231?
|
// Bytes 0/1 hold the LED mode, e.g. serial, RTL8231?
|
||||||
// Blink rate is defined by setAsicRegBits(0x6520,0xe00000,rate);
|
// Blink rate is defined by setAsicRegBits(0x6520,0xe00000,rate);
|
||||||
|
#define RTL837X_REG_LED_GLB_IO_EN 0x65DC
|
||||||
|
#define RTL837X_REG_LED3_0_SET1 0x6528
|
||||||
|
#define RTL837X_REG_LED3_2_SET0 0x6544
|
||||||
|
#define RTL837X_REG_LED1_0_SET0 0x6548
|
||||||
|
|
||||||
#define RTL837X_REG_SMI_CTRL 0x6454
|
// SMI control
|
||||||
#define RTL837X_REG_RESET 0x0024
|
#define RTL837X_REG_SMI_PORT0_5_ADDR 0x644C
|
||||||
// Writing 0x01 into this register causes a reset of the entire SoC
|
#define RTL837X_REG_SMI_PORT6_9_ADDR 0x6450
|
||||||
|
#define RTL837X_REG_SMI_CTRL 0x6454
|
||||||
|
#define RTL837X_REG_SMI_MAC_TYPE 0x6330
|
||||||
|
#define RTL837X_REG_SMI_PORT_POLLING 0x6334
|
||||||
|
|
||||||
#define RTL837X_REG_SEC_COUNTER 0x06f4
|
#define RTL837X_REG_SEC_COUNTER 0x06f4
|
||||||
#define RTL837X_REG_SEC_COUNTER2 0x06f8
|
#define RTL837X_REG_SEC_COUNTER2 0x06f8
|
||||||
@@ -31,7 +43,8 @@
|
|||||||
#define SDS_10GR 0x1a
|
#define SDS_10GR 0x1a
|
||||||
#define SDS_OFF 0x1f
|
#define SDS_OFF 0x1f
|
||||||
|
|
||||||
#define RTL837X_REG_LINKS 0x63f0
|
#define RTL837X_REG_LINKS 0x63f0
|
||||||
|
#define RTL837X_REG_LINKS_89 0x63f4
|
||||||
/* Each nibble encodes the link state of a port.
|
/* Each nibble encodes the link state of a port.
|
||||||
Port 0 appears to be the CPU port
|
Port 0 appears to be the CPU port
|
||||||
The RTL8372 serves ports 4-7, port 3 is the RTL8221
|
The RTL8372 serves ports 4-7, port 3 is the RTL8221
|
||||||
@@ -46,6 +59,7 @@
|
|||||||
|
|
||||||
#define RTL837X_PIN_MUX_0 0x7f8c
|
#define RTL837X_PIN_MUX_0 0x7f8c
|
||||||
#define RTL837X_PIN_MUX_1 0x7f90
|
#define RTL837X_PIN_MUX_1 0x7f90
|
||||||
|
#define RTL837X_PIN_MUX_2 0x7f94
|
||||||
|
|
||||||
// Output Registers
|
// Output Registers
|
||||||
#define RTL837X_REG_GPIO_00_31_OUTPUT 0x3c
|
#define RTL837X_REG_GPIO_00_31_OUTPUT 0x3c
|
||||||
@@ -177,6 +191,9 @@
|
|||||||
#define RTL837X_RMA0_CONF 0x4ecc
|
#define RTL837X_RMA0_CONF 0x4ecc
|
||||||
#define RTL837X_RMA_CONF 0x4f1c
|
#define RTL837X_RMA_CONF 0x4f1c
|
||||||
#define RTL837X_MSTP_STATES 0x5310
|
#define RTL837X_MSTP_STATES 0x5310
|
||||||
|
#define RTL837X_REG_LED_RLDP_1 0x65F8
|
||||||
|
#define RTL837X_REG_LED_RLDP_2 0x65FC
|
||||||
|
#define RTL837X_REG_LED_RLDP_3 0x65FC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EEE
|
* EEE
|
||||||
|
|||||||
+5
-8
@@ -12,12 +12,9 @@
|
|||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
extern __xdata uint8_t minPort;
|
extern __code struct machine machine;
|
||||||
extern __xdata uint8_t maxPort;
|
|
||||||
extern __xdata uint8_t nSFPPorts;
|
|
||||||
extern __xdata uint8_t cpuPort;
|
|
||||||
extern __xdata uint8_t isRTL8373;
|
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
extern __code struct uip_eth_addr uip_ethaddr;
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
@@ -203,7 +200,7 @@ void stp_cnf_send(uint8_t port)
|
|||||||
|
|
||||||
void stp_timers(void) __banked
|
void stp_timers(void) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_hello[i]--;
|
port_hello[i]--;
|
||||||
if (!port_hello[i]) {
|
if (!port_hello[i]) {
|
||||||
port_hello[i] = TIME_HELLO;
|
port_hello[i] = TIME_HELLO;
|
||||||
@@ -219,7 +216,7 @@ void stp_setup(void) __banked
|
|||||||
{
|
{
|
||||||
print_string("Enabling STP: ");
|
print_string("Enabling STP: ");
|
||||||
sfr_data[0] = sfr_data[1] = sfr_data[2] = sfr_data[3] = 0;
|
sfr_data[0] = sfr_data[1] = sfr_data[2] = sfr_data[3] = 0;
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
// Set STP port state to blocking
|
// Set STP port state to blocking
|
||||||
// States are: 00 disable, 01 blocking, 10 learning, 11 forwarding
|
// States are: 00 disable, 01 blocking, 10 learning, 11 forwarding
|
||||||
uint8_t bit_mask = 0b01 << ( (i << 1) & 0x7);
|
uint8_t bit_mask = 0b01 << ( (i << 1) & 0x7);
|
||||||
@@ -241,7 +238,7 @@ void stp_setup(void) __banked
|
|||||||
void stp_off(void) __banked
|
void stp_off(void) __banked
|
||||||
{
|
{
|
||||||
sfr_data[0] = sfr_data[1] = sfr_data[2] = sfr_data[3] = 0;
|
sfr_data[0] = sfr_data[1] = sfr_data[2] = sfr_data[3] = 0;
|
||||||
for (uint8_t i = minPort; i <= maxPort; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
// Set STP port state to forwarding
|
// Set STP port state to forwarding
|
||||||
// States are: 00 disable, 01 blocking, 10 learning, 11 forwarding
|
// States are: 00 disable, 01 blocking, 10 learning, 11 forwarding
|
||||||
uint8_t bit_mask = 0b11 << ( (i << 1) & 0x7);
|
uint8_t bit_mask = 0b11 << ( (i << 1) & 0x7);
|
||||||
|
|||||||
+170
-207
@@ -15,6 +15,9 @@
|
|||||||
#include "uip/uipopt.h"
|
#include "uip/uipopt.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "uip/uip_arp.h"
|
#include "uip/uip_arp.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
extern __code const struct machine machine;
|
||||||
|
|
||||||
extern __xdata uint16_t crc_value;
|
extern __xdata uint16_t crc_value;
|
||||||
__xdata uint8_t crc_testbytes[10];
|
__xdata uint8_t crc_testbytes[10];
|
||||||
@@ -56,8 +59,6 @@ __code struct uip_eth_addr uip_ethaddr = {{ 0x1c, 0x2a, 0xa3, 0x23, 0x00, 0x02 }
|
|||||||
__code uint8_t gatewayIP[] = { 192, 168, 2, 22};
|
__code uint8_t gatewayIP[] = { 192, 168, 2, 22};
|
||||||
__code uint8_t netmask[] = { 255, 255, 255, 0};
|
__code uint8_t netmask[] = { 255, 255, 255, 0};
|
||||||
|
|
||||||
__xdata uint8_t isRTL8373;
|
|
||||||
|
|
||||||
volatile __xdata uint32_t ticks;
|
volatile __xdata uint32_t ticks;
|
||||||
volatile __xdata uint8_t sec_counter;
|
volatile __xdata uint8_t sec_counter;
|
||||||
volatile __xdata uint16_t sleep_ticks;
|
volatile __xdata uint16_t sleep_ticks;
|
||||||
@@ -87,10 +88,6 @@ __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
|||||||
__xdata uint16_t rx_packet_vlan;
|
__xdata uint16_t rx_packet_vlan;
|
||||||
__xdata uint8_t tx_seq;
|
__xdata uint8_t tx_seq;
|
||||||
|
|
||||||
__xdata uint8_t minPort;
|
|
||||||
__xdata uint8_t maxPort;
|
|
||||||
__xdata uint8_t nSFPPorts;
|
|
||||||
__xdata uint8_t cpuPort;
|
|
||||||
__xdata uint8_t stpEnabled;
|
__xdata uint8_t stpEnabled;
|
||||||
|
|
||||||
__code uint16_t bit_mask[16] = {
|
__code uint16_t bit_mask[16] = {
|
||||||
@@ -101,6 +98,7 @@ __code uint16_t bit_mask[16] = {
|
|||||||
|
|
||||||
__xdata uint8_t was_offline;
|
__xdata uint8_t was_offline;
|
||||||
__xdata uint8_t linkbits_last[4];
|
__xdata uint8_t linkbits_last[4];
|
||||||
|
__xdata uint8_t linkbits_last_p89;
|
||||||
__xdata uint8_t sfp_pins_last;
|
__xdata uint8_t sfp_pins_last;
|
||||||
|
|
||||||
|
|
||||||
@@ -632,7 +630,7 @@ void sds_config_mac(uint8_t sds, uint8_t mode)
|
|||||||
case 2:
|
case 2:
|
||||||
sfr_mask_data(1, 0xfc, 0x02 << 2);
|
sfr_mask_data(1, 0xfc, 0x02 << 2);
|
||||||
}
|
}
|
||||||
if (isRTL8373) // Set 3rd SERDES Mode to 0x2 for RTL8224
|
if (machine.isRTL8373) // Set 3rd SERDES Mode to 0x2 for RTL8224
|
||||||
sfr_mask_data(1, 0xfc, 0x02 << 2);
|
sfr_mask_data(1, 0xfc, 0x02 << 2);
|
||||||
else
|
else
|
||||||
sfr_data[2] &= 0x03;
|
sfr_data[2] &= 0x03;
|
||||||
@@ -676,9 +674,6 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
|
|
||||||
uint8_t page = 0;
|
uint8_t page = 0;
|
||||||
uint16_t v = 0;
|
uint16_t v = 0;
|
||||||
print_string("\nTrying to set SDS mode to 0x");
|
|
||||||
print_byte(mode);
|
|
||||||
print_string("\n");
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SDS_SGMII:
|
case SDS_SGMII:
|
||||||
@@ -749,7 +744,7 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
*/
|
*/
|
||||||
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
||||||
{
|
{
|
||||||
if (slot == 0) {
|
if (machine.sfp_port[slot].i2c == 0) {
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
sfr_mask_data(1, 0xfc, SCL_PIN << 5 | SDA_PIN_0 << 2);
|
sfr_mask_data(1, 0xfc, SCL_PIN << 5 | SDA_PIN_0 << 2);
|
||||||
reg_write_m(RTL837X_REG_I2C_CTRL);
|
reg_write_m(RTL837X_REG_I2C_CTRL);
|
||||||
@@ -906,7 +901,10 @@ static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
|
|||||||
|
|
||||||
void sfp_print_info(uint8_t sfp)
|
void sfp_print_info(uint8_t sfp)
|
||||||
{
|
{
|
||||||
|
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
|
||||||
for (uint8_t i = 20; i < 60; i++) {
|
for (uint8_t i = 20; i < 60; i++) {
|
||||||
|
if (i >= 36 && i < 40) // Skip Non-ASCII codes
|
||||||
|
continue;
|
||||||
uint8_t c = sfp_read_reg(sfp, i);
|
uint8_t c = sfp_read_reg(sfp, i);
|
||||||
if (c)
|
if (c)
|
||||||
write_char(c);
|
write_char(c);
|
||||||
@@ -915,55 +913,48 @@ void sfp_print_info(uint8_t sfp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool gpio_pin_test(uint8_t pin)
|
||||||
|
{
|
||||||
|
reg_read_m(RTL837X_REG_GPIO_00_31_INPUT + (pin > 31 ? 4 : 0));
|
||||||
|
return sfr_data[3-((pin >> 3) & 3)] & (1 << (pin & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void handle_sfp(void)
|
void handle_sfp(void)
|
||||||
{
|
{
|
||||||
reg_read_m(RTL837X_REG_GPIO_00_31_INPUT);
|
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||||
if ((sfp_pins_last & 0x1) && (!(sfr_data[0] & 0x40))) {
|
if (!gpio_pin_test(machine.sfp_port[sfp].pin_detect)) {
|
||||||
sfp_pins_last &= ~0x01;
|
if (sfp_pins_last & (0x1 << (sfp << 2))) {
|
||||||
print_string("\n<MODULE INSERTED> ");
|
sfp_pins_last &= ~(0x01 << (sfp << 2));
|
||||||
// Read Reg 11: Encoding, see SFF-8472 and SFF-8024
|
print_string("\n<MODULE INSERTED> Slot: "); write_char('1' + sfp);
|
||||||
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
// Read Reg 11: Encoding, see SFF-8472 and SFF-8024
|
||||||
delay(100); // Delay, because some modules need time to wake up
|
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
||||||
uint8_t rate = sfp_read_reg(0, 12);
|
delay(100); // Delay, because some modules need time to wake up
|
||||||
print_string("Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
uint8_t rate = sfp_read_reg(sfp, 12);
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(0, 11));
|
print_string(" Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
||||||
print_string("\n");
|
print_string(" Encoding: "); print_byte(sfp_read_reg(sfp, 11));
|
||||||
print_string("\n");
|
print_string(" Module: "); sfp_print_info(sfp);
|
||||||
sfp_print_info(0);
|
print_string("\n");
|
||||||
sds_config(1, sfp_rate_to_sds_config(rate));
|
sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate));
|
||||||
}
|
}
|
||||||
if ((!(sfp_pins_last & 0x1)) && (sfr_data[0] & 0x40)) {
|
} else {
|
||||||
sfp_pins_last |= 0x01;
|
if (!(sfp_pins_last & (0x1 << (sfp << 2)))) {
|
||||||
print_string("\n<MODULE REMOVED>\n");
|
sfp_pins_last |= 0x01 << (sfp << 2);
|
||||||
}
|
print_string("\n<MODULE REMOVED> Slot: "); write_char('1' + sfp); write_char('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_GPIO_32_63_INPUT);
|
if (!gpio_pin_test(machine.sfp_port[sfp].pin_los)) {
|
||||||
if ((sfp_pins_last & 0x2) && (!(sfr_data[3] & 0x20))) {
|
if (sfp_pins_last & (0x2 << (sfp << 2))) { // 0x2 0x08
|
||||||
sfp_pins_last &= ~0x02;
|
sfp_pins_last &= ~(0x02 << (sfp << 2));
|
||||||
print_string("\n<SFP-RX OK>\n");
|
print_string("\n<SFP-RX OK> Slot: "); write_char('1' + sfp); write_char('\n');
|
||||||
}
|
}
|
||||||
if ((!(sfp_pins_last & 0x2)) && (sfr_data[3] & 0x20)) {
|
} else {
|
||||||
sfp_pins_last |= 0x02;
|
if (!(sfp_pins_last & 0x2 << (sfp << 2))) {
|
||||||
print_string("\n<SFP-RX LOS>\n");
|
sfp_pins_last |= 0x02 << (sfp << 2);
|
||||||
}
|
print_string("\n<SFP-RX LOS> Slot: "); write_char('1' + sfp); write_char('\n');
|
||||||
|
}
|
||||||
reg_read_m(RTL837X_REG_GPIO_32_63_INPUT);
|
}
|
||||||
if ((sfp_pins_last & 0x10) && (!(sfr_data[1] & 0x04))) {
|
|
||||||
sfp_pins_last &= ~0x10;
|
|
||||||
print_string("\n<MODULE 2 INSERTED> ");
|
|
||||||
// Read Reg 11: Encoding, see SFF-8472 and SFF-8024
|
|
||||||
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
|
||||||
delay(100); // Delay, because some modules need time to wake up
|
|
||||||
uint8_t rate = sfp_read_reg(1, 12);
|
|
||||||
print_string("Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(1, 11));
|
|
||||||
print_string("\n");
|
|
||||||
sfp_print_info(1);
|
|
||||||
sds_config(0, sfp_rate_to_sds_config(rate));
|
|
||||||
}
|
|
||||||
if ((!(sfp_pins_last & 0x10)) && (sfr_data[1] & 0x04)) {
|
|
||||||
sfp_pins_last |= 0x10;
|
|
||||||
print_string("\n<MODULE 2 REMOVED>\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,17 +997,25 @@ void idle(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for Link changes
|
||||||
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
|
__xdata uint8_t linkbits_p89 = sfr_data[3];
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_LINKS);
|
reg_read_m(RTL837X_REG_LINKS);
|
||||||
if (!isRTL8373 && cmp_4(sfr_data, linkbits_last)) {
|
if (cmp_4(sfr_data, linkbits_last) || (linkbits_p89 != linkbits_last_p89)) {
|
||||||
print_string("\n<new link: ");
|
print_string("\n<new link: ");
|
||||||
print_long_x(sfr_data);
|
print_byte(linkbits_p89); print_byte(sfr_data[0]); print_byte(sfr_data[1]);
|
||||||
|
print_byte(sfr_data[2]); print_byte(sfr_data[3]);
|
||||||
print_string(", was ");
|
print_string(", was ");
|
||||||
print_long_x(linkbits_last);
|
print_byte(linkbits_last_p89); print_byte(linkbits_last[0]); print_byte(linkbits_last[1]);
|
||||||
|
print_byte(linkbits_last[2]); print_byte(linkbits_last[3]);
|
||||||
print_string(">\n");
|
print_string(">\n");
|
||||||
if (nSFPPorts != 2) {
|
linkbits_last_p89 = linkbits_p89;
|
||||||
|
if (!machine.isRTL8373 && machine.n_sfp != 2) {
|
||||||
uint8_t p5 = sfr_data[2] >> 4;
|
uint8_t p5 = sfr_data[2] >> 4;
|
||||||
uint8_t p5_last = linkbits_last[2] >> 4;
|
uint8_t p5_last = linkbits_last[2] >> 4;
|
||||||
cpy_4(linkbits_last, sfr_data);
|
cpy_4(linkbits_last, sfr_data);
|
||||||
|
// Handle link change of the RTL8221 PHY, adjust SDS mode
|
||||||
if (p5_last != p5) {
|
if (p5_last != p5) {
|
||||||
if (p5 == 0x5) // 2.5GBit Mode
|
if (p5 == 0x5) // 2.5GBit Mode
|
||||||
sds_config(0, SDS_HISGMII);
|
sds_config(0, SDS_HISGMII);
|
||||||
@@ -1029,7 +1028,6 @@ void idle(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for changes with SFP modules
|
// Check for changes with SFP modules
|
||||||
|
|
||||||
handle_sfp();
|
handle_sfp();
|
||||||
|
|
||||||
/* Button pressed on KL-8xhm-x2:
|
/* Button pressed on KL-8xhm-x2:
|
||||||
@@ -1217,12 +1215,13 @@ void phy_modify(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t mask, uin
|
|||||||
// Modify the reed data.
|
// Modify the reed data.
|
||||||
// TODO: Check if we directly can modify SFR register directly.
|
// TODO: Check if we directly can modify SFR register directly.
|
||||||
uint16_t data = SFR_DATA_U16 & ~(mask);
|
uint16_t data = SFR_DATA_U16 & ~(mask);
|
||||||
data |= ~(set);
|
data |= set;
|
||||||
|
|
||||||
uint16_t phy_mask = bit_mask[phy_id];
|
uint16_t phy_mask = bit_mask[phy_id];
|
||||||
|
|
||||||
// Write it back
|
// Write it back
|
||||||
SFR_SMI_REG_U16 = data;
|
SFR_SMI_REG_U16 = reg;
|
||||||
|
SFR_DATA_U16 = data;
|
||||||
SFR_SMI_PHYMASK = phy_mask; // SFR_C5
|
SFR_SMI_PHYMASK = phy_mask; // SFR_C5
|
||||||
SFR_SMI_DEV = smi_phy | (phy_mask >> 8);
|
SFR_SMI_DEV = smi_phy | (phy_mask >> 8);
|
||||||
SFR_EXEC_GO = SFR_EXEC_WRITE_SMI;
|
SFR_EXEC_GO = SFR_EXEC_WRITE_SMI;
|
||||||
@@ -1323,46 +1322,35 @@ void led_config_9xh(void)
|
|||||||
reg_bit_set(0x65d8, 0x1d);
|
reg_bit_set(0x65d8, 0x1d);
|
||||||
|
|
||||||
// r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0
|
// r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0
|
||||||
reg_read_m(0x6520);
|
reg_read_m(RTL837X_REG_LED_MODE);
|
||||||
sfr_mask_data(1, 0x1f, 0x6);
|
sfr_mask_data(1, 0x1f, 0x6);
|
||||||
sfr_mask_data(0, 0xe0, 0xa0);
|
sfr_mask_data(0, 0xe0, 0xa0);
|
||||||
reg_write_m(0x6520);
|
reg_write_m(RTL837X_REG_LED_MODE);
|
||||||
|
|
||||||
// r65f8:00000018 R65f8-0000001b
|
// Disable RLDP (Realtek Loop Detection Protocol) LEDs on loop detection
|
||||||
reg_read_m(0x65f8);
|
reg_read_m(RTL837X_REG_LED_RLDP_1);
|
||||||
sfr_mask_data(0, 0, 0x3);
|
sfr_mask_data(0, 0, 0x3);
|
||||||
reg_write_m(0x65f8);
|
reg_write_m(RTL837X_REG_LED_RLDP_1);
|
||||||
|
// Configure LED group for RLDP per port
|
||||||
|
REG_SET(RTL837X_REG_LED_RLDP_2, 0xffffffff); // Ports 0-7
|
||||||
|
REG_SET(RTL837X_REG_LED_RLDP_3, 0x0000000f); // Port 8
|
||||||
|
|
||||||
// R65fc-ffffffff
|
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 29);
|
||||||
REG_SET(0x65fc, 0xffffffff);
|
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27);
|
||||||
|
|
||||||
// Set bits 0-3 of 0x6600 to 0xf
|
// GPIO 27 is LED
|
||||||
// r6600:00000000 R6600-0000000f
|
reg_bit_set(RTL837X_PIN_MUX_0, 27);
|
||||||
reg_read_m(0x6600);
|
|
||||||
sfr_mask_data(0, 0, 0x0f);
|
|
||||||
reg_write_m(0x6600);
|
|
||||||
|
|
||||||
// Set bit 0x1d of 0x65dc, clear bit 1b: r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
// Configure LED_SET_0, ledid 0/1
|
||||||
reg_bit_set(0x65dc, 0x1d);
|
REG_SET(RTL837X_REG_LED1_0_SET0, 0x0041017f);
|
||||||
reg_bit_clear(0x65dc, 0x1b);
|
|
||||||
|
|
||||||
// r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000
|
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 0x1b);
|
|
||||||
|
|
||||||
// R6548-0041017f
|
|
||||||
REG_SET(0x6548, 0x0041017f);
|
|
||||||
|
|
||||||
// Configure LED_SET_0 ledid 2
|
// Configure LED_SET_0 ledid 2
|
||||||
// r6544:01411000 R6544-01410044
|
REG_SET(RTL837X_REG_LED3_2_SET0, 0x01410044);
|
||||||
reg_read_m(0x6544);
|
|
||||||
sfr_data[2] = 0x00;
|
|
||||||
sfr_data[3] = 0x44;
|
|
||||||
reg_write_m(0x6544);
|
|
||||||
|
|
||||||
// r6528:00000000 R6528-0000000f
|
// r6528:00000000 R6528-0000000f
|
||||||
reg_read_m(0x6528);
|
reg_read_m(RTL837X_REG_LED3_0_SET1);
|
||||||
sfr_mask_data(0, 0x0f, 0x0f);
|
sfr_mask_data(0, 0x0f, 0x0f);
|
||||||
reg_write_m(0x6528);
|
reg_write_m(RTL837X_REG_LED3_0_SET1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1377,109 +1365,62 @@ void led_config(void)
|
|||||||
sfr_data[3] = 0xb0;
|
sfr_data[3] = 0xb0;
|
||||||
reg_write_m(RTL837X_REG_LED_MODE);
|
reg_write_m(RTL837X_REG_LED_MODE);
|
||||||
|
|
||||||
// Clear bits 0,1 of 0x65f8
|
// Disable RLDP (Realtek Loop Detection Protocol) LEDs on loop detection
|
||||||
// r65f8:00000018 R65f8-00000018
|
reg_read_m(RTL837X_REG_LED_RLDP_1);
|
||||||
reg_read_m(0x65f8);
|
|
||||||
sfr_mask_data(0, 0x03, 0);
|
sfr_mask_data(0, 0x03, 0);
|
||||||
reg_write_m(0x65f8);
|
reg_write_m(RTL837X_REG_LED_RLDP_1);
|
||||||
|
// Configure LED group for RLDP per port
|
||||||
|
REG_SET(RTL837X_REG_LED_RLDP_2, 0xffffffff); // Ports 0-7
|
||||||
|
REG_SET(RTL837X_REG_LED_RLDP_3, 0x0000000f); // Port 8
|
||||||
|
|
||||||
// Set 0x65fc to 0xfffff000
|
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 29);
|
||||||
// R65fc-fffff000
|
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27);
|
||||||
REG_SET(0x65fc, 0xfffff000);
|
|
||||||
|
|
||||||
// Set bits 0-3 of 0x6600 to 0xf
|
// Configure GPIO for LEDs 27-29
|
||||||
// r6600:00000000 R6600-0000000f
|
if (machine.n_sfp == 2) {
|
||||||
reg_read_m(0x6600);
|
reg_bit_set(RTL837X_PIN_MUX_0, 27);
|
||||||
sfr_mask_data(0, 0, 0x0f);
|
reg_bit_clear(RTL837X_PIN_MUX_0, 28);
|
||||||
reg_write_m(0x6600);
|
reg_bit_set(RTL837X_PIN_MUX_0, 29);
|
||||||
|
|
||||||
// Set bit 0x1d of 0x65dc, clear bit 1b: r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
|
||||||
reg_bit_set(0x65dc, 0x1d);
|
|
||||||
reg_bit_clear(0x65dc, 0x1b);
|
|
||||||
|
|
||||||
// Set bits 1b/1d of 0x7f8c: r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000
|
|
||||||
if (nSFPPorts == 2) {
|
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 0x1b); // R7f8c-28000000
|
|
||||||
reg_bit_clear(RTL837X_PIN_MUX_0, 0x1c); // R7f8c-28000000
|
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 0x1d); // R7f8c-28000000
|
|
||||||
} else {
|
} else {
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 0x1d);
|
reg_bit_set(RTL837X_PIN_MUX_0, 27);
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 0x1c);
|
reg_bit_set(RTL837X_PIN_MUX_0, 28);
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 0x1b);
|
reg_bit_set(RTL837X_PIN_MUX_0, 29);
|
||||||
}
|
}
|
||||||
// LED setup
|
// LED setup
|
||||||
// r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0 r65f8:00000018 R65f8-00000018 R65fc-fffff000 r6600:00000000 R6600-0000000f r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
// r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0 r65f8:00000018 R65f8-00000018 R65fc-fffff000 r6600:00000000 R6600-0000000f r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
||||||
// r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000 R6548-00410175 r6544:01411000 R6544-01410044 r6528:00000000 R6528-00000011 r6450:000020e6 R6450-000000e6 r644c:0a418820 R644c-0a400820
|
// r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000 R6548-00410175 r6544:01411000 R6544-01410044 r6528:00000000 R6528-00000011
|
||||||
|
|
||||||
// Configure LED_SET_0, ledid 0/1
|
// Configure LED_SET_0, ledid 0/1
|
||||||
// R6548-00410175
|
REG_SET(RTL837X_REG_LED1_0_SET0, 0x00410175);
|
||||||
REG_SET(0x6548, 0x00410175);
|
|
||||||
|
|
||||||
// Configure LED_SET_0 ledid 2
|
// Configure led-sets 2 and 3
|
||||||
// 6544:01411000 R6544-01410044
|
REG_SET(RTL837X_REG_LED3_2_SET0, 0x01410044);
|
||||||
reg_read_m(0x6544);
|
|
||||||
sfr_data[2] = 0x00;
|
|
||||||
sfr_data[3] = 0x44;
|
|
||||||
reg_write_m(0x6544);
|
|
||||||
|
|
||||||
// Further configure LED_SET_0
|
// Further configure LED_SET_0
|
||||||
// r6528:00000000 R6528-00000011
|
// r6528:00000000 R6528-00000011
|
||||||
reg_read_m(0x6528);
|
reg_read_m(RTL837X_REG_LED3_0_SET1);
|
||||||
sfr_data[3] = 0x11;
|
sfr_data[3] = 0x11;
|
||||||
reg_write_m(0x6528);
|
reg_write_m(RTL837X_REG_LED3_0_SET1);
|
||||||
|
|
||||||
reg_read_m(0x6450);
|
|
||||||
sfr_mask_data(1, 0x7c, 0);
|
|
||||||
reg_write_m(0x6450);
|
|
||||||
|
|
||||||
// SDS bits f-13 set to 0: r644c:0a418820 R644c-0a400820
|
|
||||||
reg_read_m(0x644c);
|
|
||||||
sfr_mask_data(2, 0x0f, 0);
|
|
||||||
sfr_mask_data(1, 0x80, 0);
|
|
||||||
reg_write_m(0x644c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rtl8373_revision(void)
|
void rtl8373_revision(void)
|
||||||
{
|
{
|
||||||
// r000c:00300000 R000c-003a0000 r000c:203a6818 r000c:203a6818 R000c-20306818
|
reg_read_m(RTL837X_REG_CHIP_INFO);
|
||||||
|
|
||||||
reg_read_m(0x000c);
|
|
||||||
sfr_mask_data(2, 0x0a, 0x0a); // Enable reading version
|
sfr_mask_data(2, 0x0a, 0x0a); // Enable reading version
|
||||||
reg_write_m(0x000c);
|
reg_write_m(RTL837X_REG_CHIP_INFO);
|
||||||
delay(50);
|
delay(50);
|
||||||
|
|
||||||
reg_read_m(0x000c);
|
reg_read_m(RTL837X_REG_CHIP_INFO);
|
||||||
print_string("CPU revision: "); print_byte(sfr_data[2]); print_byte(sfr_data[2]); write_char('\n');
|
print_string("CPU revision: "); print_byte(sfr_data[2]); print_byte(sfr_data[2]); write_char('\n');
|
||||||
sfr_mask_data(2, 0x0a, 0x00); // Enable reading version
|
sfr_mask_data(2, 0x0a, 0x00); // Enable reading version
|
||||||
reg_write_m(0x000c);
|
reg_write_m(RTL837X_REG_CHIP_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rtl8373_init(void)
|
void rtl8373_init(void)
|
||||||
{
|
{
|
||||||
print_string("\nrtl8373_init called\n");
|
print_string("\nrtl8373_init called\n");
|
||||||
minPort = 0;
|
|
||||||
maxPort = 8;
|
|
||||||
cpuPort = 9;
|
|
||||||
nSFPPorts = 1;
|
|
||||||
|
|
||||||
// r6330:00015555 R6330-00005555 r6330:00005555 R6330-00005555
|
|
||||||
REG_SET(0x6330, 0x00005555);
|
|
||||||
|
|
||||||
// r6334:00000000 R6334-000001f8 RTL8373: r6334:00000000 R6334-000000ff
|
|
||||||
reg_read_m(0x6334); // Also in sdsMode_set
|
|
||||||
sfr_mask_data(0, 0, 0xff);
|
|
||||||
reg_write_m(0x6334);
|
|
||||||
|
|
||||||
// Enable MDC
|
|
||||||
// r6454:00000000 R6454-00007000 RTL837X_REG_SMI_CTRL
|
|
||||||
reg_read_m(RTL837X_REG_SMI_CTRL);
|
|
||||||
sfr_mask_data(1, 0, 0x70); // Set bits 0xc-0xe to enable MDC for SMI0-SMI2
|
|
||||||
reg_write_m(RTL837X_REG_SMI_CTRL);
|
|
||||||
delay(50);
|
|
||||||
|
|
||||||
rtl8373_revision();
|
|
||||||
|
|
||||||
led_config_9xh();
|
led_config_9xh();
|
||||||
sds_init();
|
sds_init();
|
||||||
@@ -1534,10 +1475,12 @@ void rtl8373_init(void)
|
|||||||
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
|
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
|
||||||
reg_bit_set(0xb7c, 5);
|
reg_bit_set(0xb7c, 5);
|
||||||
|
|
||||||
|
// R7124-00001050 R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050
|
||||||
// R7124-00001050 R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050 R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050
|
// R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050
|
||||||
REG_SET(0x7124, 0x1050); REG_SET(0x7128, 0x1050); REG_SET(0x712c, 0x1050); REG_SET(0x7130, 0x1050); REG_SET(0x7134, 0x1050); REG_SET(0x7138, 0x1050); REG_SET(0x713c, 0x1050);
|
REG_SET(0x7124, 0x1050); REG_SET(0x7128, 0x1050); REG_SET(0x712c, 0x1050);
|
||||||
REG_SET(0x7140, 0x1050); REG_SET(0x7144, 0x1050); REG_SET(0x7148, 0x1050);
|
REG_SET(0x7130, 0x1050); REG_SET(0x7134, 0x1050); REG_SET(0x7138, 0x1050);
|
||||||
|
REG_SET(0x713c, 0x1050); REG_SET(0x7140, 0x1050); REG_SET(0x7144, 0x1050);
|
||||||
|
REG_SET(0x7148, 0x1050);
|
||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
@@ -1554,7 +1497,6 @@ void rtl8373_init(void)
|
|||||||
sfr_mask_data(2, 0x10, 0x1f);
|
sfr_mask_data(2, 0x10, 0x1f);
|
||||||
reg_write_m(0x632c);
|
reg_write_m(0x632c);
|
||||||
|
|
||||||
REG_SET(0x7f94, 0);
|
|
||||||
print_string("\nrtl8373_init done\n");
|
print_string("\nrtl8373_init done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1562,36 +1504,9 @@ void rtl8373_init(void)
|
|||||||
void rtl8372_init(void)
|
void rtl8372_init(void)
|
||||||
{
|
{
|
||||||
print_string("\nrtl8372_init called\n");
|
print_string("\nrtl8372_init called\n");
|
||||||
minPort = 3;
|
|
||||||
maxPort = 8;
|
|
||||||
cpuPort = 9;
|
|
||||||
nSFPPorts = NSFP;
|
|
||||||
|
|
||||||
// r6330:00015555 R6330-00005555 r6330:00005555 R6330-00005555
|
|
||||||
REG_SET(0x6330, 0x00005555);
|
|
||||||
if (nSFPPorts == 2) {
|
|
||||||
print_string("Configuring 2nd SFP+ port\n");
|
|
||||||
REG_SET(0x6330, 0x00005515);
|
|
||||||
}
|
|
||||||
|
|
||||||
// r6334:00000000 R6334-000001f8 RTL8373: r6334:00000000 R6334-000000ff
|
|
||||||
reg_read_m(0x6334); // Also in sdsMode_set
|
|
||||||
if (nSFPPorts == 2) {
|
|
||||||
sfr_mask_data(0, 0, 0xf0);
|
|
||||||
} else {
|
|
||||||
sfr_mask_data(1, 0, 0x01); // Set bits 3-8, On RTL8373+8224 set bits 0-7
|
|
||||||
sfr_mask_data(0, 0, 0xf8);
|
|
||||||
}
|
|
||||||
reg_write_m(0x6334);
|
|
||||||
|
|
||||||
// Enable MDC
|
|
||||||
// r6454:00000000 R6454-00007000 RTL837X_REG_SMI_CTRL
|
|
||||||
reg_read_m(RTL837X_REG_SMI_CTRL);
|
|
||||||
sfr_mask_data(1, 0, 0x70); // Set bits 0xc-0xe to enable MDC for SMI0-SMI2
|
|
||||||
reg_write_m(RTL837X_REG_SMI_CTRL);
|
|
||||||
delay(50);
|
|
||||||
|
|
||||||
led_config();
|
led_config();
|
||||||
|
|
||||||
sds_init();
|
sds_init();
|
||||||
phy_config(8); // PHY configuration: External 8221B?
|
phy_config(8); // PHY configuration: External 8221B?
|
||||||
phy_config(3); // PHY configuration: all internal PHYs?
|
phy_config(3); // PHY configuration: all internal PHYs?
|
||||||
@@ -1621,7 +1536,7 @@ void rtl8372_init(void)
|
|||||||
// [...]
|
// [...]
|
||||||
///
|
///
|
||||||
uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set
|
uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set
|
||||||
for (char i = minPort; i <= maxPort; i++) {
|
for (char i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
|
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
|
||||||
REG_SET(reg, 0xe77);
|
REG_SET(reg, 0xe77);
|
||||||
reg += 0x100;
|
reg += 0x100;
|
||||||
@@ -1648,6 +1563,50 @@ void rtl8372_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The SoC manages Link-State for steering the LEDs and can set PHY-settings
|
||||||
|
* automatically through Realtek's SMI (Simple Managagement) Interface, a
|
||||||
|
* proprietary version of MDIO which for example allows for more PHYs on the same
|
||||||
|
* bus.
|
||||||
|
* Configure polling via SMI and the interface setup during boot.
|
||||||
|
*/
|
||||||
|
void init_smi(void)
|
||||||
|
{
|
||||||
|
print_string("\ninit_switch called\n");
|
||||||
|
|
||||||
|
/* Set the SMI(i.e.I2C) type for PHY polling, 0b01 is 2.5/10G PHY. Disable (0b00) for the SFP-ports
|
||||||
|
* which are at port 8 and additionally at port 3 for a dual SFP device
|
||||||
|
*/
|
||||||
|
REG_SET(RTL837X_REG_SMI_MAC_TYPE, machine.n_sfp == 2 ? 0x00005515 : 0x00005555);
|
||||||
|
|
||||||
|
// Configure polling of all PHYs by the MAC to detect link-state changes
|
||||||
|
if (machine.isRTL8373) {
|
||||||
|
REG_SET(RTL837X_REG_SMI_PORT_POLLING, 0xff);
|
||||||
|
} else {
|
||||||
|
REG_SET(RTL837X_REG_SMI_PORT_POLLING, machine.n_sfp == 2 ? 0xf0 : 0x1f8);
|
||||||
|
}
|
||||||
|
// Enable MDC
|
||||||
|
reg_read_m(RTL837X_REG_SMI_CTRL);
|
||||||
|
sfr_mask_data(1, 0, 0x70); // Set bits 12-14 to enable MDC for SMI0-SMI2
|
||||||
|
reg_write_m(RTL837X_REG_SMI_CTRL);
|
||||||
|
delay(50);
|
||||||
|
|
||||||
|
if (!machine.isRTL8373) {
|
||||||
|
// Change I2C addresses for SMI of the non-existent PHYs
|
||||||
|
// r6450:000020e6 R6450-000000e6
|
||||||
|
reg_read_m(RTL837X_REG_SMI_PORT6_9_ADDR);
|
||||||
|
sfr_mask_data(1, 0x7c, 0);
|
||||||
|
reg_write_m(RTL837X_REG_SMI_PORT6_9_ADDR);
|
||||||
|
|
||||||
|
// r644c:0a418820 R644c-0a400820
|
||||||
|
reg_read_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
||||||
|
sfr_mask_data(2, 0x0f, 0);
|
||||||
|
sfr_mask_data(1, 0x80, 0);
|
||||||
|
reg_write_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set up serial port 0 using Timer 2 with an external trigger
|
/* Set up serial port 0 using Timer 2 with an external trigger
|
||||||
* as baud generator.
|
* as baud generator.
|
||||||
* The external clock generator uses a crystal at 25MHz.
|
* The external clock generator uses a crystal at 25MHz.
|
||||||
@@ -1720,17 +1679,19 @@ void bootloader(void)
|
|||||||
// Set default for SFP pins so we can start up a module already inserted
|
// Set default for SFP pins so we can start up a module already inserted
|
||||||
sfp_pins_last = 0x33; // signal LOS and no module inserted (for both slots, even if only 1 present)
|
sfp_pins_last = 0x33; // signal LOS and no module inserted (for both slots, even if only 1 present)
|
||||||
// We have not detected any link
|
// We have not detected any link
|
||||||
linkbits_last[0] = linkbits_last[1] = linkbits_last[2] = linkbits_last[3] = 0;
|
linkbits_last[0] = linkbits_last[1] = linkbits_last[2] = linkbits_last[3] = linkbits_last_p89 = 0;
|
||||||
|
|
||||||
print_string("Detecting CPU: ");
|
print_string("Detecting CPU: ");
|
||||||
isRTL8373 = 0;
|
|
||||||
reg_read_m(0x4);
|
reg_read_m(0x4);
|
||||||
if (sfr_data[1] == 0x73) { // Register was 0x83730000
|
if (sfr_data[1] == 0x73) { // Register was 0x83730000
|
||||||
print_string("RTL8373\n");
|
print_string("RTL8373\n");
|
||||||
isRTL8373 = 1;
|
if (!machine.isRTL8373)
|
||||||
|
print_string("INCORRECT MACHINE!");
|
||||||
rtl8224_enable(); // Power on the RTL8224
|
rtl8224_enable(); // Power on the RTL8224
|
||||||
} else {
|
} else {
|
||||||
print_string("RTL8372\n");
|
print_string("RTL8372\n");
|
||||||
|
if (machine.isRTL8373)
|
||||||
|
print_string("INCORRECT MACHINE!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print SW version
|
// Print SW version
|
||||||
@@ -1741,18 +1702,20 @@ void bootloader(void)
|
|||||||
flash_init(0);
|
flash_init(0);
|
||||||
|
|
||||||
// Reset NIC
|
// Reset NIC
|
||||||
reg_bit_set(0x24, 2);
|
reg_bit_set(RTL837X_REG_RESET, RESET_NIC_BIT);
|
||||||
do {
|
do {
|
||||||
reg_read(0x24);
|
reg_read(RTL837X_REG_RESET);
|
||||||
} while (SFR_DATA_0 & 0x4);
|
} while (SFR_DATA_0 & (1 << RESET_NIC_BIT));
|
||||||
print_string("NIC reset\n");
|
print_string("NIC reset\n");
|
||||||
|
|
||||||
uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]);
|
uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]);
|
||||||
uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]);
|
uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]);
|
||||||
uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]);
|
uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]);
|
||||||
|
|
||||||
REG_SET(0x7f94, 0x0);
|
REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL
|
||||||
if (isRTL8373)
|
init_smi();
|
||||||
|
rtl8373_revision();
|
||||||
|
if (machine.isRTL8373)
|
||||||
rtl8373_init();
|
rtl8373_init();
|
||||||
else
|
else
|
||||||
rtl8372_init();
|
rtl8372_init();
|
||||||
|
|||||||
Reference in New Issue
Block a user