mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #175 from logicog/ZX310S-4T2XH
10GBit Ethernet Switch support (Horaco ZX310S-4T2XH)
This commit is contained in:
@@ -662,6 +662,14 @@ void parse_port(void)
|
|||||||
else if (cmd_compare(3, "full"))
|
else if (cmd_compare(3, "full"))
|
||||||
phy_settings.duplex = PHY_DUPLEX_FULL;
|
phy_settings.duplex = PHY_DUPLEX_FULL;
|
||||||
phy_set_speed();
|
phy_set_speed();
|
||||||
|
} else if (cmd_compare(2, "10g")) {
|
||||||
|
print_string(" 10G\n");
|
||||||
|
phy_settings.speed = PHY_SPEED_10G;
|
||||||
|
phy_set_speed();
|
||||||
|
} else if (cmd_compare(2, "5g")) {
|
||||||
|
print_string(" 5G\n");
|
||||||
|
phy_settings.speed = PHY_SPEED_5G;
|
||||||
|
phy_set_speed();
|
||||||
} else if (cmd_compare(2, "2g5")) {
|
} else if (cmd_compare(2, "2g5")) {
|
||||||
print_string(" 2.5G\n");
|
print_string(" 2.5G\n");
|
||||||
phy_settings.speed = PHY_SPEED_2G5;
|
phy_settings.speed = PHY_SPEED_2G5;
|
||||||
@@ -1063,6 +1071,9 @@ void parse_eee(void)
|
|||||||
__xdata int8_t port = -1;
|
__xdata int8_t port = -1;
|
||||||
__xdata uint8_t speed = EEE_2G5;
|
__xdata uint8_t speed = EEE_2G5;
|
||||||
__xdata uint8_t speed_word = 0;
|
__xdata uint8_t speed_word = 0;
|
||||||
|
|
||||||
|
if (machine.n_10g)
|
||||||
|
speed = EEE_10G;
|
||||||
// Check if word 2 is a speed (contains 'g' or 'm') or a port number
|
// Check if word 2 is a speed (contains 'g' or 'm') or a port number
|
||||||
if (cmd_words_len >= 3) {
|
if (cmd_words_len >= 3) {
|
||||||
uint8_t idx = cmd_words_b[2];
|
uint8_t idx = cmd_words_b[2];
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# ZX310S-4T2XH/
|
||||||
|
|
||||||
|
The following is a documentation for the managed switch marked as `ZX310S-4T2XH`
|
||||||
|
and sold by Horaco.
|
||||||
|
|
||||||
|
The original software is running UART on 57600 baud rate. The solder holes
|
||||||
|
of the UART header are filled in. In order to install a UART header, they
|
||||||
|
need to be cleared first. A 1.2mm drill can be used, alternatively a
|
||||||
|
de-soldering wick.
|
||||||
|
The original firmware uses 57600 baud 8N1
|
||||||
|
|
||||||
|
CPU: RTL8372
|
||||||
|
Flash: 2MByte Winbond W25Q16DV (U3)
|
||||||
|
PHY RTL8261BE
|
||||||
|
|
||||||
|
### Label specifications
|
||||||
|
|
||||||
|
- **Name**:
|
||||||
|
- **Ports**:
|
||||||
|
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||||
|
- 1 x RJ45: 10/100/1000/2500/5000/10000 Mbps
|
||||||
|
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||||
|
- **Power**: 12V DC, 2A barrel connector
|
||||||
|
|
||||||
|
<img src="photos/ZX310S-4T2XH/label.jpg" width="300" />
|
||||||
|
|
||||||
|
### What works
|
||||||
|
The device is fully supported:
|
||||||
|
- All 4 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||||
|
- The 10GBit port works. TODO: Fix EEE, speed selection
|
||||||
|
- The SFP+ port supports 1G, 2.5G and 10G modules
|
||||||
|
- LEDs work with the same indiciations as the OEM firmware
|
||||||
|
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
**Board markings**
|
||||||
|
- Top silkscreen: PCB-SL310S-4T1T1X-V1.0.1-24107
|
||||||
|
|
||||||
|
Top side
|
||||||
|
|
||||||
|
<img src="photos/ZX310S-4T2XH/pcb_top.jpg" width="300" />
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
|
||||||
|
<img src="photos/ZX310S-4T2XH/pcb_bottom.jpg" width="300" />
|
||||||
|
|
||||||
|
### J1, serial console
|
||||||
|
|
||||||
|
| `J1` pin | Signal |
|
||||||
|
| -------- | ----------- |
|
||||||
|
| 1 | TX (Output) |
|
||||||
|
| 2 | RX (Input) |
|
||||||
|
| 3 | GND |
|
||||||
|
| 4 | 3V3 |
|
||||||
|
|
||||||
|
|
||||||
|
## Power supply
|
||||||
|
|
||||||
|
Input power is delivered via barell plug, `12V 2A` adapter was provided.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.3 MiB |
+3
-1
@@ -164,7 +164,9 @@ function update(callback) {
|
|||||||
} else {
|
} else {
|
||||||
psvg.style.opacity = 1.0;
|
psvg.style.opacity = 1.0;
|
||||||
pState[n] = p.link;
|
pState[n] = p.link;
|
||||||
if (p.link == 4 || p.link == 5 || p.link == 6) {
|
if (p.link == 5 || p.link == 7) {
|
||||||
|
leds[0].style.fill = "green"; leds[1].style.fill = "blue";
|
||||||
|
} else if (p.link == 4 || 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 == 1 || p.link == 2 || p.link == 3) {
|
} 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";
|
||||||
|
|||||||
+9
-7
@@ -248,14 +248,16 @@ void send_basic_info(void)
|
|||||||
slen += strtox(outbuf + slen, "\",\"flash_size\":\"");
|
slen += strtox(outbuf + slen, "\",\"flash_size\":\"");
|
||||||
string_to_html(get_flash_size_str());
|
string_to_html(get_flash_size_str());
|
||||||
|
|
||||||
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
if (machine.n_sfp) {
|
||||||
send_sfp_info(0);
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
||||||
char_to_html('"');
|
send_sfp_info(0);
|
||||||
if (machine.n_sfp == 2) {
|
if (machine.n_sfp == 2) {
|
||||||
slen += strtox(outbuf + slen, ",\"sfp_slot_1\":\"");
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_1\":\"");
|
||||||
send_sfp_info(1);
|
send_sfp_info(1);
|
||||||
char_to_html('"');
|
}
|
||||||
}
|
}
|
||||||
|
char_to_html('"');
|
||||||
|
|
||||||
char_to_html('}');
|
char_to_html('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -544,7 +544,6 @@ __code const struct machine machine = {
|
|||||||
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
.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},
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
@@ -571,6 +570,51 @@ __code const struct machine machine = {
|
|||||||
|
|
||||||
void machine_custom_init(void) { }
|
void machine_custom_init(void) { }
|
||||||
|
|
||||||
|
#elif defined MACHINE_ZX310S_4T2XH
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "ZX310S-4T2XH",
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.n_10g = 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 = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
|
.reset_pin = GPIO48_I2C_SCL1,
|
||||||
|
.high_leds = { .mux = LED_28_SYS, .enable = LED_27 | LED_28_SYS | LED_29 },
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, // 65e0
|
||||||
|
0x09, 0x0c, 0x3f, 0x0d, 0x10, // 65e4
|
||||||
|
0x11, 0x0e, 0x14, 0x11, 0x12, // 65e8
|
||||||
|
0x15, 0x15, 0x16, 0x18, 0x19, // 65ec
|
||||||
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c, // 65f0
|
||||||
|
0x1d, 0x20, 0x21 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
/* Ports 1-4: Orange: 2.5GBit, Green: 10/100/1000MBit
|
||||||
|
* Port 5: Blue: 10GBit, Green: 10Mbit-5GBit
|
||||||
|
* SFP-port: Blue: 10GBit, Green 100MBit-5GBit
|
||||||
|
*/
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_DUPLEX,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT | LEDS_5G,
|
||||||
|
LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_COL | LEDS_DUPLEX
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
void machine_custom_init(void) { }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Please select a machine type in machine.h"
|
#error "Please select a machine type in machine.h"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
// #define MACHINE_HI_K0402WS
|
// #define MACHINE_HI_K0402WS
|
||||||
// #define MACHINE_K0501W_V2_0
|
// #define MACHINE_K0501W_V2_0
|
||||||
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
||||||
|
// #define MACHINE_ZX310S_4T2XH
|
||||||
// #define MACHINE_DEFAULT_8C_1SFP
|
// #define MACHINE_DEFAULT_8C_1SFP
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -58,6 +59,7 @@ typedef struct machine {
|
|||||||
// Highest logical port number
|
// Highest logical port number
|
||||||
uint8_t max_port;
|
uint8_t max_port;
|
||||||
uint8_t n_sfp;
|
uint8_t n_sfp;
|
||||||
|
uint8_t n_10g;
|
||||||
uint8_t log_to_phys_port[9];
|
uint8_t log_to_phys_port[9];
|
||||||
uint8_t phys_to_log_port[9]; // Starts at 0 for port 1
|
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
|
uint8_t is_sfp[9]; // 0 for non-SFP ports 1 or 2 for the I2C port number
|
||||||
|
|||||||
@@ -22,16 +22,21 @@
|
|||||||
#define PHY_ANEG_CTRL 0x00
|
#define PHY_ANEG_CTRL 0x00
|
||||||
#define PHY_ANEG_ADV 0x10
|
#define PHY_ANEG_ADV 0x10
|
||||||
#define PHY_ANEG_LP_ABILITY 0x13
|
#define PHY_ANEG_LP_ABILITY 0x13
|
||||||
#define PHY_ANEG_MGBASE_CTRL 0x20
|
#define PHY_ANEG_MGBASE_CTRL 0x20
|
||||||
#define PHY_ANEG_MGBASE_ADV 0x21
|
#define PHY_ANEG_MGBASE_ADV 0x21
|
||||||
#define PHY_EEE_ADV 0x3c
|
#define PHY_EEE_ADV 0x3c
|
||||||
#define PHY_EEE_LP_ABILITY 0x3d
|
#define PHY_EEE_LP_ABILITY 0x3d
|
||||||
#define PHY_EEE_ADV2 0x3e
|
#define PHY_EEE_ADV2 0x3e
|
||||||
#define PHY_EEE_LP_ABILITY2 0x3f
|
#define PHY_EEE_LP_ABILITY2 0x3f
|
||||||
|
|
||||||
// Register bits for EEE capabilities at a given speed
|
// Register bits for EEE capabilities at a given speed
|
||||||
|
// PHY_EEE_ADV2
|
||||||
#define PHY_EEE_BIT_2G5 0x01
|
#define PHY_EEE_BIT_2G5 0x01
|
||||||
|
#define PHY_EEE_BIT_5G 0x02
|
||||||
|
// PHY_EEE_ADV
|
||||||
#define PHY_EEE_BIT_1G 0x04
|
#define PHY_EEE_BIT_1G 0x04
|
||||||
#define PHY_EEE_BIT_100M 0x02
|
#define PHY_EEE_BIT_100M 0x02
|
||||||
|
#define PHY_EEE_BIT_10G 0x08
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMD 31 Registers
|
* MMD 31 Registers
|
||||||
|
|||||||
+45
-28
@@ -19,14 +19,6 @@ extern __xdata struct machine_runtime machine_detected;
|
|||||||
*/
|
*/
|
||||||
void static sds_init(void)
|
void static sds_init(void)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
p001e.000d:9535 R02f8-00009535 R02f4-0000953a P000001.1e00000d:953a
|
|
||||||
p001e.000d:953a p001e.000d:953a R02f8-0000953a R02f4-00009530 P000001.1e00000d:9530
|
|
||||||
|
|
||||||
RTL8373:
|
|
||||||
p001e.000d:0010 R02f8-00000010 R02f4-0000001a P000001.1e00000d:b7fe
|
|
||||||
p001e.000d:0010 p001e.000d:0010 R02f8-00000010 R02f4-00000010 P000001.1e00000d:b7fe
|
|
||||||
*/
|
|
||||||
phy_read(0, PHY_MMD30, 0xd);
|
phy_read(0, PHY_MMD30, 0xd);
|
||||||
uint16_t pval = SFR_DATA_U16;
|
uint16_t pval = SFR_DATA_U16;
|
||||||
|
|
||||||
@@ -55,6 +47,8 @@ void static sds_init(void)
|
|||||||
uint16_t pval;
|
uint16_t pval;
|
||||||
|
|
||||||
print_string(" N-settings");
|
print_string(" N-settings");
|
||||||
|
if (machine.n_10g)
|
||||||
|
print_string(" - 10g");
|
||||||
// Serdes 0 RX PN swap for 64B/66B
|
// Serdes 0 RX PN swap for 64B/66B
|
||||||
sds_read(1, 6, 2);
|
sds_read(1, 6, 2);
|
||||||
pval = SFR_DATA_U16;
|
pval = SFR_DATA_U16;
|
||||||
@@ -70,19 +64,30 @@ void static sds_init(void)
|
|||||||
pval = SFR_DATA_U16;
|
pval = SFR_DATA_U16;
|
||||||
sds_write_v(0, 6, 2, pval | 0x2000);
|
sds_write_v(0, 6, 2, pval | 0x2000);
|
||||||
|
|
||||||
if (machine_detected.isRTL8373) {
|
if (!machine.n_10g) {
|
||||||
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
if (machine_detected.isRTL8373) {
|
||||||
// We assume that RTL8373N always paired with RTL8224N.
|
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
||||||
// This sds register value is 0x0000 at reset.
|
// We assume that RTL8373N always paired with RTL8224N.
|
||||||
// So only write to it.
|
// This sds register value is 0x0000 at reset.
|
||||||
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
// So only write to it.
|
||||||
} else {
|
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
||||||
// Serdes 0 RX PN swap for 8B/10B
|
} else {
|
||||||
sds_read(0, 0, 0);
|
// Serdes 0 RX PN swap for 8B/10B
|
||||||
pval = SFR_DATA_U16;
|
sds_read(0, 0, 0);
|
||||||
sds_write_v(0, 0, 0, pval | 0x200);
|
pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(0, 0, 0, pval | 0x200);
|
||||||
|
}
|
||||||
|
} else if (machine.n_10g == 1) {
|
||||||
|
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
sfr_mask_data(0, 0x0f,0x0c);
|
||||||
|
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
REG_SET(RTL837X_CFG_PHY_TX_POLARITY_SWAP, 0x0000596a);
|
||||||
|
} else if (machine.n_10g == 2) {
|
||||||
|
REG_SET(RTL837X_CFG_PHY_MDI_REVERSE, 0xc);
|
||||||
|
REG_SET(RTL837X_CFG_PHY_TX_POLARITY_SWAP, 0x0000596a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
print_string("\nsds_init done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +114,7 @@ void rtl8373_init(void) __banked
|
|||||||
phy_config_8224();
|
phy_config_8224();
|
||||||
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
|
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
|
||||||
sds_config_mac(2, SDS_SGMII); // For RTL8224
|
sds_config_mac(2, SDS_SGMII); // For RTL8224
|
||||||
sds_config(0, SDS_QXGMII);
|
sds_config(0, SDS_QXGMII); // For RTL8224
|
||||||
|
|
||||||
// SDS 1 setup
|
// SDS 1 setup
|
||||||
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
|
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
|
||||||
@@ -163,7 +168,7 @@ void rtl8373_init(void) __banked
|
|||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
// enable EEE for all ports at 2.5G, but don't reset the PHYs
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
// TODO: patch the PHYs
|
||||||
@@ -188,14 +193,26 @@ void rtl8372_init(void) __banked
|
|||||||
print_string("\nrtl8372_init called\n");
|
print_string("\nrtl8372_init called\n");
|
||||||
|
|
||||||
sds_init();
|
sds_init();
|
||||||
phy_config(8); // PHY configuration: External 8221B?
|
if (machine.n_10g != 2)
|
||||||
phy_config(3); // PHY configuration: all internal PHYs?
|
phy_config(8); // PHY configuration: External 8221B?
|
||||||
|
if (machine.n_10g)
|
||||||
|
phy_config_8261(3, 0);
|
||||||
|
if (machine.n_10g == 2)
|
||||||
|
phy_config_8261(8, 1);
|
||||||
|
else
|
||||||
|
phy_config(3); // PHY configuration: all internal PHYs?
|
||||||
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
|
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
|
||||||
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
|
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
|
||||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
if (machine.n_10g == 1) {
|
||||||
sfr_mask_data(1, 0, 0x03);
|
REG_SET(RTL837X_REG_SDS_MODES, 0x3ed); // Disable SFP for now, set RTL8261BE SDS 0 to 0xd
|
||||||
sfr_mask_data(0, 0, 0xe2);
|
} else if(machine.n_10g == 2) {
|
||||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
REG_SET(RTL837X_REG_SDS_MODES, 0x1ad); // Both 10g ports use SDS_QXGMII
|
||||||
|
} else {
|
||||||
|
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||||
|
sfr_mask_data(1, 0, 0x03);
|
||||||
|
sfr_mask_data(0, 0, 0xe2);
|
||||||
|
reg_write_m(RTL837X_REG_SDS_MODES);
|
||||||
|
}
|
||||||
|
|
||||||
// r0a90:000000f3 R0a90-000000fc
|
// r0a90:000000f3 R0a90-000000fc
|
||||||
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
@@ -229,7 +246,7 @@ void rtl8372_init(void) __banked
|
|||||||
|
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
port_eee_enable_all(EEE_10G | EEE_NORESET);
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
// TODO: patch the PHYs
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ void leds_dump(void) __banked
|
|||||||
print_string("RTL837X_REG_LED1_0_SET2: "); print_reg(RTL837X_REG_LED1_0_SET2); write_char('\n');
|
print_string("RTL837X_REG_LED1_0_SET2: "); print_reg(RTL837X_REG_LED1_0_SET2); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED3_2_SET2: "); print_reg(RTL837X_REG_LED3_2_SET2); write_char('\n');
|
print_string("RTL837X_REG_LED3_2_SET2: "); print_reg(RTL837X_REG_LED3_2_SET2); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED1_0_SET3: "); print_reg(RTL837X_REG_LED1_0_SET3); write_char('\n');
|
print_string("RTL837X_REG_LED1_0_SET3: "); print_reg(RTL837X_REG_LED1_0_SET3); write_char('\n');
|
||||||
|
print_string("RTL837X_REG_LED3_2_SET3: "); print_reg(RTL837X_REG_LED3_2_SET3); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED3_0_SET1: "); print_reg(RTL837X_REG_LED3_0_SET1); write_char('\n');
|
print_string("RTL837X_REG_LED3_0_SET1: "); print_reg(RTL837X_REG_LED3_0_SET1); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED3_0_SET3: "); print_reg(RTL837X_REG_LED3_0_SET3); write_char('\n');
|
print_string("RTL837X_REG_LED3_0_SET3: "); print_reg(RTL837X_REG_LED3_0_SET3); write_char('\n');
|
||||||
print_string("RTL837X_LED_PORT_SET_SEL: "); print_reg(RTL837X_LED_PORT_SET_SEL); write_char('\n');
|
print_string("RTL837X_LED_PORT_SET_SEL: "); print_reg(RTL837X_LED_PORT_SET_SEL); write_char('\n');
|
||||||
|
|||||||
+90
-1
@@ -86,6 +86,76 @@ void rtl8224_phy_enable(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void phy_config_8261(uint8_t phy, uint8_t sds) __banked
|
||||||
|
{
|
||||||
|
print_string("phy_config_8261: phy "); print_byte(phy);
|
||||||
|
print_string(" sds "); print_byte(sds); write_char('\n');
|
||||||
|
phy_write(phy, PHY_MMD30, 0x141, 0x80aa); // P000008.1e000141:80aa P000008.1e000143:8c07 p031e.0143:0c07
|
||||||
|
phy_write(phy, PHY_MMD30, 0x143, 0x8c07);
|
||||||
|
phy_read(phy, PHY_MMD30, 0x143);
|
||||||
|
print_phy_data();
|
||||||
|
phy_write(phy, PHY_MMD30, 0x141, 0x5078); // P000008.1e000141:5078 P000008.1e000143:8c86 p031e.0143:0c86
|
||||||
|
phy_write(phy, PHY_MMD30, 0x143, 0x8c86);
|
||||||
|
phy_read(phy, PHY_MMD30, 0x143);
|
||||||
|
print_phy_data();
|
||||||
|
phy_read(phy, PHY_MMD30, 0x105);
|
||||||
|
print_phy_data(); // p031e.0105:0000
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe1, 0x00); // P000008.1e0000e1:0000
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe3, 0x00); // P000008.1e0000e3:0000
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe4, 0x01); // P000008.1e0000e4:0001
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe0, 0x2f); // P000008.1e0000e0:002f
|
||||||
|
|
||||||
|
// The following are actually bit-ops:
|
||||||
|
phy_write(phy, PHY_MMD31, 0xa442, 0x8418); // p031f.a442:0418 P000008.1f00a442:8418
|
||||||
|
phy_write(phy, PHY_MMD31, 0xa448, 0x07a0); // p031f.a448:07a0 P000008.1f00a448:07a0
|
||||||
|
phy_write(phy, PHY_MMD31, 0xa43a, 0x003f); // p031f.a43a:0030 P000008.1e0000e2:003f
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD31, 0xc800, 0x5a02); // P000008.1f00c800:5a02
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ee, 0x5a02); // p031e.01ee:5a00 P000008.1e0001ee:5a02
|
||||||
|
phy_write(phy, PHY_MMD30, 0x0230, 0x0002); // p031e.0230:0000 P000008.1e000230:0002
|
||||||
|
phy_write(phy, PHY_MMD31, 0xc802, 0x0073); // p031f.c802:0000 P000008.1f00c802:0073
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ef, 0xe004); // p031e.01ef:0004 P000008.1e0001ef:e004
|
||||||
|
delay(20);
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ef, 0x0004); // p031e.01ef:e004 P000008.1e0001ef:0004
|
||||||
|
delay(20);
|
||||||
|
phy_write(phy, PHY_MMD30, 0x0230, 0x01c2); // p031e.0230:01c2 P000008.1e000230:0002
|
||||||
|
|
||||||
|
phy_read(phy, PHY_MMD30, 0x103);
|
||||||
|
print_phy_data(); // p031e.0103:8261
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01c8, 0x0104); // p031e.01c8:0104 P000008.1e0001c8:0104
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01c9, 0x8080); // p031e.01c9:8080 P000008.1e0001c9:8080
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ca, 0x2020); // p031e.01ca:2020 P000008.1e0001ca:2020
|
||||||
|
phy_write(phy, PHY_MMD30, 0x0105, 0x0000); // p031e.0105:0000 P000008.1e000105:0000
|
||||||
|
phy_write(phy, PHY_MMD30, 0x00c2, 0x880d); // p031e.00c2:880d P000008.1e0000c2:880d
|
||||||
|
phy_write(phy, PHY_MMD30, 0x03f1, 0x0072); // p031e.03f1:0072 P000008.1e0003f1:0072
|
||||||
|
phy_write(phy, PHY_MMD30, 0x02a2, 0x0010); // p031e.02a2:0010 P000008.1e0002a2:0010
|
||||||
|
phy_write(phy, PHY_MMD30, 0x00c1, 0x0127); // p031e.00c1:0127 P000008.1e0000c1:0127
|
||||||
|
phy_write(phy, PHY_MMD30, 0x00c1, 0x0167); // p031e.00c1:0127 P000008.1e0000c1:0167
|
||||||
|
|
||||||
|
sds_write_v(sds, 0x21, 0x00, 0x4096); // Q002100:4906
|
||||||
|
sds_write_v(sds, 0x36, 0x05, 0x4000); // Q003605:4000
|
||||||
|
sds_write_v(sds, 0x1f, 0x02, 0x001f); // Q001f02:001f
|
||||||
|
|
||||||
|
phy_read(phy, 0x01, 0x0000);
|
||||||
|
print_phy_data(); // p0301.0000:2040
|
||||||
|
|
||||||
|
phy_write(phy, 0x01, 0x0000, 0x2040); // P000008.01000000:2040
|
||||||
|
delay(20);
|
||||||
|
|
||||||
|
sds_write_v(sds, 0, 0, 0x1603); // Q000000:1603
|
||||||
|
delay(20);
|
||||||
|
sds_write_v(sds, 0, 0, 0x1601); // Q000000:1601
|
||||||
|
delay(20);
|
||||||
|
sds_write_v(sds, 0, 0, 0x1603); //Q000000:1603
|
||||||
|
delay(20);
|
||||||
|
// r6330:00005555 R6330-00005555 r7b20:000003ed R7b20-000003ed
|
||||||
|
print_string("\r\nphy_config_8261 done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void phy_config(uint8_t phy) __banked
|
void phy_config(uint8_t phy) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\nphy_config: ");
|
print_string("\r\nphy_config: ");
|
||||||
@@ -193,6 +263,10 @@ void phy_set_speed(void) __banked
|
|||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
|
||||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
||||||
|
if (machine.n_10g && phy_settings.port == 3)
|
||||||
|
phy_settings.is10g_port = 1;
|
||||||
|
if (machine.n_10g == 2 && phy_settings.port == 8)
|
||||||
|
phy_settings.is10g_port = 1;
|
||||||
if (phy_settings.speed == PHY_OFF) {
|
if (phy_settings.speed == PHY_OFF) {
|
||||||
print_string(" to disabled");
|
print_string(" to disabled");
|
||||||
} else {
|
} else {
|
||||||
@@ -200,6 +274,8 @@ void phy_set_speed(void) __banked
|
|||||||
switch(phy_settings.speed) {
|
switch(phy_settings.speed) {
|
||||||
case PHY_SPEED_AUTO:
|
case PHY_SPEED_AUTO:
|
||||||
print_string("auto");
|
print_string("auto");
|
||||||
|
if (phy_settings.is10g_port)
|
||||||
|
print_string (" (10g)");
|
||||||
break;
|
break;
|
||||||
case PHY_SPEED_10M:
|
case PHY_SPEED_10M:
|
||||||
print_string("10M");
|
print_string("10M");
|
||||||
@@ -246,7 +322,10 @@ void phy_set_speed(void) __banked
|
|||||||
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled
|
if (phy_settings.is10g_port)
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0e00);
|
||||||
|
else
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200);
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
||||||
} else {
|
} else {
|
||||||
// AN Control Register (MMD 7.0x0000)
|
// AN Control Register (MMD 7.0x0000)
|
||||||
@@ -285,6 +364,12 @@ void phy_set_speed(void) __banked
|
|||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||||
|
} else if (phy_settings.speed == PHY_SPEED_5G) {
|
||||||
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0400, 0x0000);
|
||||||
|
} else if (phy_settings.speed == PHY_SPEED_10G) {
|
||||||
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0800, 0x0000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
||||||
@@ -442,6 +527,10 @@ void phy_show(uint8_t port) __banked
|
|||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (v & 0x0080)
|
if (v & 0x0080)
|
||||||
print_string(" 2500BaseN-Full");
|
print_string(" 2500BaseN-Full");
|
||||||
|
if (v & 0x0100)
|
||||||
|
print_string(" 5000BaseN-Full");
|
||||||
|
if (v & 0x1000)
|
||||||
|
print_string(" 10GBaseN-Full");
|
||||||
}
|
}
|
||||||
phy_read(port, PHY_MMD_AN, PHY_ANEG_LP_ABILITY);
|
phy_read(port, PHY_MMD_AN, PHY_ANEG_LP_ABILITY);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct phy_settings {
|
|||||||
uint8_t duplex;
|
uint8_t duplex;
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
uint8_t speed;
|
uint8_t speed;
|
||||||
|
uint8_t is10g_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern __xdata struct phy_settings phy_settings;
|
extern __xdata struct phy_settings phy_settings;
|
||||||
@@ -28,6 +29,7 @@ void phy_reset(uint8_t port) __banked;
|
|||||||
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
||||||
void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked;
|
void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked;
|
||||||
void rtl8224_sds_write(uint16_t sds_cmd, uint16_t val) __banked;
|
void rtl8224_sds_write(uint16_t sds_cmd, uint16_t val) __banked;
|
||||||
|
void phy_config_8261(uint8_t phy, uint8_t sds) __banked;
|
||||||
|
|
||||||
#define RTL8224_SDS_WRITE(sds_id, page, reg, v) uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \
|
#define RTL8224_SDS_WRITE(sds_id, page, reg, v) uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \
|
||||||
_sdscmd |= (page & 0x3F) << 1; \
|
_sdscmd |= (page & 0x3F) << 1; \
|
||||||
|
|||||||
+68
-8
@@ -440,6 +440,9 @@ void port_stats_print(void) __banked
|
|||||||
case 5:
|
case 5:
|
||||||
print_string("2.5G\t");
|
print_string("2.5G\t");
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
print_string("5G\t");
|
||||||
|
break;
|
||||||
case 99:
|
case 99:
|
||||||
print_string("Down\t");
|
print_string("Down\t");
|
||||||
break;
|
break;
|
||||||
@@ -489,20 +492,19 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REG_SET(RTL837X_EEE_CTRL_BASE + (port << 8), EEE_RX_ENABLE | EEE_TX_ENABLE);
|
||||||
print_string("EEE on for "); print_byte(port); print_string(" speed ");
|
print_string("EEE on for "); print_byte(port); print_string(" speed ");
|
||||||
// Enable all speeds up to the specified speed
|
// Enable all speeds up to the specified speed
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_100) {
|
if (speed & EEE_100) {
|
||||||
print_string("100m\n");
|
print_string("100m\n");
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100);
|
|
||||||
// Enable EEE advertisement for 100BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_100M);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_100M);
|
||||||
if (!(speed & EEE_NORESET))
|
if (!(speed & EEE_NORESET))
|
||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_1000) {
|
if (speed & EEE_1000) {
|
||||||
print_string("1g\n");
|
print_string("1g\n");
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000);
|
|
||||||
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, 0);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, 0);
|
||||||
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
@@ -511,9 +513,8 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
|||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_2G5) {
|
if (speed & EEE_2G5) {
|
||||||
print_string("2g5\n");
|
print_string("2g5\n");
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5);
|
|
||||||
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
@@ -522,6 +523,26 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
|||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (speed & EEE_5G) {
|
||||||
|
print_string("5g\n");
|
||||||
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5 | PHY_EEE_BIT_5G);
|
||||||
|
if (!(speed & EEE_NORESET))
|
||||||
|
phy_reset(port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (speed & EEE_10G) {
|
||||||
|
print_string("10g\n");
|
||||||
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_10G | PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5 | PHY_EEE_BIT_5G);
|
||||||
|
if (!(speed & EEE_NORESET))
|
||||||
|
phy_reset(port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,7 +553,7 @@ void port_eee_disable(uint8_t port) __banked
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
print_string("EEE off for "); print_byte(port); write_char('\n');
|
print_string("EEE off for "); print_byte(port); write_char('\n');
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), 0);
|
REG_SET(RTL837X_EEE_CTRL_BASE + (port << 8), 0);
|
||||||
// Disable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Disable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, 0);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, 0);
|
||||||
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
@@ -552,8 +573,24 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
|
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
print_string("Advertising: ");
|
print_string("Advertising: ");
|
||||||
|
|
||||||
|
if (machine.n_10g) {
|
||||||
|
phy_read(port, PHY_MMD_AN, PHY_EEE_ADV);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & PHY_EEE_BIT_10G)
|
||||||
|
print_string(" 10G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
phy_read(port, PHY_MMD_AN, PHY_EEE_ADV2);
|
phy_read(port, PHY_MMD_AN, PHY_EEE_ADV2);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
|
if (machine.n_10g) {
|
||||||
|
if (v & PHY_EEE_BIT_5G)
|
||||||
|
print_string(" 5G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
|
v = SFR_DATA_U16;
|
||||||
if (v & PHY_EEE_BIT_2G5)
|
if (v & PHY_EEE_BIT_2G5)
|
||||||
print_string(" 2.5G");
|
print_string(" 2.5G");
|
||||||
else
|
else
|
||||||
@@ -570,8 +607,22 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
print_string(" ");
|
print_string(" ");
|
||||||
|
|
||||||
print_string(" Link Partner: ");
|
print_string(" Link Partner: ");
|
||||||
|
if (machine.n_10g) {
|
||||||
|
phy_read(port, PHY_MMD_AN, PHY_EEE_LP_ABILITY);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & PHY_EEE_BIT_10G)
|
||||||
|
print_string(" 10G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
phy_read(port, PHY_MMD_AN, PHY_EEE_LP_ABILITY2);
|
phy_read(port, PHY_MMD_AN, PHY_EEE_LP_ABILITY2);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
|
if (machine.n_10g) {
|
||||||
|
if (v & PHY_EEE_BIT_5G)
|
||||||
|
print_string(" 5G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
if (v & PHY_EEE_BIT_2G5)
|
if (v & PHY_EEE_BIT_2G5)
|
||||||
print_string(" 2.5G");
|
print_string(" 2.5G");
|
||||||
else
|
else
|
||||||
@@ -599,7 +650,16 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
void port_eee_enable_all(__xdata uint8_t speed) __banked
|
void port_eee_enable_all(__xdata uint8_t speed) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_eee_enable(i, speed);
|
if (i == 3 && machine.n_10g) {
|
||||||
|
port_eee_enable(i, speed);
|
||||||
|
} else if (i == 8 && machine.n_10g == 2) {
|
||||||
|
port_eee_enable(i, speed);
|
||||||
|
} else {
|
||||||
|
if (speed & EEE_10G)
|
||||||
|
port_eee_enable(i, speed & EEE_NORESET | EEE_2G5);
|
||||||
|
else
|
||||||
|
port_eee_enable(i, speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,16 @@ struct vlan_settings {
|
|||||||
uint16_t tagged;
|
uint16_t tagged;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port EEE settings
|
||||||
|
*/
|
||||||
|
#define EEE_100 0x01
|
||||||
|
#define EEE_1000 0x04
|
||||||
|
#define EEE_2G5 0x10
|
||||||
|
#define EEE_5G 0x20
|
||||||
|
#define EEE_10G 0x40
|
||||||
|
#define EEE_NORESET 0x80
|
||||||
|
|
||||||
extern __xdata struct vlan_settings vlan_settings;
|
extern __xdata struct vlan_settings vlan_settings;
|
||||||
|
|
||||||
uint8_t port_l2_forget(void) __banked;
|
uint8_t port_l2_forget(void) __banked;
|
||||||
|
|||||||
+4
-6
@@ -32,6 +32,7 @@
|
|||||||
#define RTL837X_REG_LED_GLB_IO_EN 0x65DC
|
#define RTL837X_REG_LED_GLB_IO_EN 0x65DC
|
||||||
#define RTL837X_REG_LED3_0_SET3 0x6524
|
#define RTL837X_REG_LED3_0_SET3 0x6524
|
||||||
#define RTL837X_REG_LED3_0_SET1 0x6528
|
#define RTL837X_REG_LED3_0_SET1 0x6528
|
||||||
|
#define RTL837X_REG_LED3_2_SET3 0x652C
|
||||||
#define RTL837X_REG_LED1_0_SET3 0x6530
|
#define RTL837X_REG_LED1_0_SET3 0x6530
|
||||||
#define RTL837X_REG_LED3_2_SET2 0x6534
|
#define RTL837X_REG_LED3_2_SET2 0x6534
|
||||||
#define RTL837X_REG_LED1_0_SET2 0x6538
|
#define RTL837X_REG_LED1_0_SET2 0x6538
|
||||||
@@ -268,14 +269,11 @@
|
|||||||
/*
|
/*
|
||||||
* EEE
|
* EEE
|
||||||
*/
|
*/
|
||||||
#define RTL837X_EEE_STATUS 0x125C
|
#define RTL837X_EEE_CTRL_BASE 0x125C
|
||||||
|
#define EEE_RX_ENABLE 0x01
|
||||||
|
#define EEE_TX_ENABLE 0x02
|
||||||
#define RTL837X_MAC_EEE_ABLTY 0x6404
|
#define RTL837X_MAC_EEE_ABLTY 0x6404
|
||||||
#define RTL8373_PHY_EEE_ABLTY 0x642C
|
#define RTL8373_PHY_EEE_ABLTY 0x642C
|
||||||
#define RTL8373_EEE_CTRL_BASE 0x606c
|
|
||||||
#define EEE_100 0x01
|
|
||||||
#define EEE_1000 0x04
|
|
||||||
#define EEE_2G5 0x10
|
|
||||||
#define EEE_NORESET 0x80
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RANDOM
|
* RANDOM
|
||||||
|
|||||||
+43
-6
@@ -890,13 +890,14 @@ void early_boot_handle_button(void)
|
|||||||
* to connect to an SFP module or a PHY
|
* to connect to an SFP module or a PHY
|
||||||
* Valid modes are SDS_10GR, SDS_QXGMII, SDS_HISGMII, SDS_HSG, SDS_SGMII and SDS_1000BX_FIBER
|
* Valid modes are SDS_10GR, SDS_QXGMII, SDS_HISGMII, SDS_HSG, SDS_SGMII and SDS_1000BX_FIBER
|
||||||
* The SerDes ID may be 0 or 1 for RTL8272 and 0-2 for RTL8373
|
* The SerDes ID may be 0 or 1 for RTL8272 and 0-2 for RTL8373
|
||||||
|
* SDS_QXGMII is used for 10G Fiber, RTL8224 and RTL8261BE
|
||||||
*/
|
*/
|
||||||
void sds_config(uint8_t sds, uint8_t mode)
|
void sds_config(uint8_t sds, uint8_t mode)
|
||||||
{
|
{
|
||||||
print_string("sds_config sds: "); print_byte(sds); print_string(", mode: "); print_byte(mode); write_char('\n');
|
print_string("sds_config sds: "); print_byte(sds); print_string(", mode: "); print_byte(mode); write_char('\n');
|
||||||
sds_config_mac(sds, mode);
|
sds_config_mac(sds, mode);
|
||||||
|
|
||||||
if (mode == SDS_10GR || mode == SDS_QXGMII) // 10G Fiber, 10G connection to RTL8224
|
if (mode == SDS_10GR || mode == SDS_QXGMII)
|
||||||
sds_write_v(sds, 0x21, 0x10, 0x4480); // Q002110:6480
|
sds_write_v(sds, 0x21, 0x10, 0x4480); // Q002110:6480
|
||||||
else
|
else
|
||||||
sds_write_v(sds, 0x21, 0x10, 0x6480); // Q002110:6480
|
sds_write_v(sds, 0x21, 0x10, 0x6480); // Q002110:6480
|
||||||
@@ -932,7 +933,7 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
}
|
}
|
||||||
sds_write_v(sds, 0x36, 0x10, v); // Q003610:0200
|
sds_write_v(sds, 0x36, 0x10, v); // Q003610:0200
|
||||||
|
|
||||||
if (page == 0x2e) { // 10G Fiber
|
if (page == 0x2e) { // 10G Fiber / SDS_QXGMII
|
||||||
sds_write_v(sds, page, 0x04, 0x0080); // Q012e04:0080
|
sds_write_v(sds, page, 0x04, 0x0080); // Q012e04:0080
|
||||||
sds_write_v(sds, page, 0x06, 0x0408); // Q012e06:0408
|
sds_write_v(sds, page, 0x06, 0x0408); // Q012e06:0408
|
||||||
sds_write_v(sds, page, 0x07, 0x020d); // Q012e07:020d
|
sds_write_v(sds, page, 0x07, 0x020d); // Q012e07:020d
|
||||||
@@ -961,6 +962,30 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
sds_write_v(sds, 0x07, 0x0c, 0x9401); // Q00070c:9401
|
sds_write_v(sds, 0x07, 0x0c, 0x9401); // Q00070c:9401
|
||||||
sds_write_v(sds, 0x1f, 0x0b, 0x0003); // Q001f0b:0003
|
sds_write_v(sds, 0x1f, 0x0b, 0x0003); // Q001f0b:0003
|
||||||
sds_write_v(sds, 0x06, 0x03, 0xc45c); // Q000603:c45c
|
sds_write_v(sds, 0x06, 0x03, 0xc45c); // Q000603:c45c
|
||||||
|
|
||||||
|
// RTL8261BE
|
||||||
|
if (machine.n_10g && mode == SDS_QXGMII) {
|
||||||
|
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||||
|
sds_write_v(sds, 0x07, 0x11, 0x054f); // Q000711:054f
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0000); // Q002000:0000
|
||||||
|
sds_write_v(sds, 0x1f, 0x00, 0x000b); // Q001f00:000b
|
||||||
|
sds_write_v(sds, 0x1f, 0x00, 0x0000); // Q001f00:0000
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mode != SDS_QXGMII)
|
if (mode != SDS_QXGMII)
|
||||||
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||||
|
|
||||||
@@ -1365,13 +1390,17 @@ void idle(void)
|
|||||||
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
|
// Handle link change of the RTL8221 PHY, adjust SDS mode, RTL8261BE always uses SDS_QXGMII
|
||||||
if (p5_last != p5) {
|
if (!machine.n_10g && 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);
|
||||||
else if (p5 == 0x2) // 1GBit
|
else if (p5 == 0x2) // 1GBit
|
||||||
sds_config(0, SDS_SGMII);
|
sds_config(0, SDS_SGMII);
|
||||||
}
|
}
|
||||||
|
if (machine.n_10g)
|
||||||
|
sds_config(0, SDS_QXGMII);
|
||||||
|
if (machine.n_10g == 2)
|
||||||
|
sds_config(1, SDS_QXGMII);
|
||||||
} else {
|
} else {
|
||||||
cpy_4(linkbits_last, sfr_data);
|
cpy_4(linkbits_last, sfr_data);
|
||||||
}
|
}
|
||||||
@@ -1660,7 +1689,11 @@ void init_smi(void)
|
|||||||
/* Set the SMI(i.e.I2C) type for PHY polling, 0b01 is 2.5/10G PHY. Disable (0b00) for the SFP-ports
|
/* 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
|
* 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);
|
if (machine.n_10g == 2) {
|
||||||
|
REG_SET(RTL837X_REG_SMI_MAC_TYPE, 0x00015555);
|
||||||
|
} else {
|
||||||
|
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
|
// Configure polling of all PHYs by the MAC to detect link-state changes
|
||||||
if (machine_detected.isRTL8373) {
|
if (machine_detected.isRTL8373) {
|
||||||
@@ -1687,6 +1720,11 @@ void init_smi(void)
|
|||||||
sfr_mask_data(1, 0x80, 0);
|
sfr_mask_data(1, 0x80, 0);
|
||||||
reg_write_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
reg_write_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (machine.n_10g == 2) {
|
||||||
|
// Set address of second external PHY on port 8
|
||||||
|
REG_SET(RTL837X_REG_SMI_PORT6_9_ADDR, 0x000040e6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2041,7 +2079,6 @@ void main(void)
|
|||||||
|
|
||||||
setup_i2c();
|
setup_i2c();
|
||||||
setup_sfp_gpio();
|
setup_sfp_gpio();
|
||||||
|
|
||||||
print_string(greeting);
|
print_string(greeting);
|
||||||
|
|
||||||
print_string("\nClock register: ");
|
print_string("\nClock register: ");
|
||||||
|
|||||||
Reference in New Issue
Block a user