mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #116 from logicog/speed_fixes
Fix Speed Setting using Auton-Neg
This commit is contained in:
+42
-35
@@ -282,17 +282,17 @@ void parse_lag_hash(void)
|
||||
|
||||
void parse_vlan(void)
|
||||
{
|
||||
__xdata uint16_t vlan;
|
||||
__xdata uint16_t members = 0;
|
||||
__xdata uint16_t tagged = 0;
|
||||
if (!atoi_short(&vlan, cmd_words_b[1])) {
|
||||
vlan_settings.vlan = 0;
|
||||
vlan_settings.members = 0;
|
||||
vlan_settings.tagged = 0;
|
||||
if (!atoi_short(&vlan_settings.vlan, cmd_words_b[1])) {
|
||||
if (cmd_words_b[2] > 0 && cmd_buffer[cmd_words_b[2]] == 'd' && cmd_words_b[3] < 0) {
|
||||
vlan_delete(vlan);
|
||||
vlan_delete(vlan_settings.vlan);
|
||||
return;
|
||||
}
|
||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "mgmt")) {
|
||||
management_vlan = vlan;
|
||||
if (!vlan)
|
||||
management_vlan = vlan_settings.vlan;
|
||||
if (!vlan_settings.vlan)
|
||||
print_string("Management VLAN disabled\n");
|
||||
else
|
||||
print_string("Management VLAN set to "); print_short(management_vlan); write_char('\n');
|
||||
@@ -301,9 +301,9 @@ void parse_vlan(void)
|
||||
uint8_t w = 2;
|
||||
if (cmd_words_b[w] > 0 && isletter(cmd_buffer[cmd_words_b[w]])) {
|
||||
register uint8_t i = 0;
|
||||
vlan_names[vlan_ptr++] = hex[(vlan >> 8) & 0xf];
|
||||
vlan_names[vlan_ptr++] = hex[(vlan >> 4) & 0xf] ;
|
||||
vlan_names[vlan_ptr++] = hex[vlan & 0xf];
|
||||
vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 8) & 0xf];
|
||||
vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 4) & 0xf] ;
|
||||
vlan_names[vlan_ptr++] = hex[vlan_settings.vlan & 0xf];
|
||||
while(cmd_buffer[cmd_words_b[w] + i] != ' ') {
|
||||
write_char(cmd_buffer[cmd_words_b[w] + i]);
|
||||
vlan_names[vlan_ptr++] = cmd_buffer[cmd_words_b[w] + i++];
|
||||
@@ -313,25 +313,25 @@ void parse_vlan(void)
|
||||
print_string("<\n");
|
||||
}
|
||||
while (cmd_words_b[w] > 0) {
|
||||
uint8_t port;
|
||||
__xdata uint8_t port;
|
||||
if (isnumber(cmd_buffer[cmd_words_b[w]])) {
|
||||
port = 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';
|
||||
if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
||||
tagged |= ((uint16_t)1) << port;
|
||||
vlan_settings.tagged |= ((uint16_t)1) << port;
|
||||
} else {
|
||||
port = machine.phys_to_log_port[port];
|
||||
if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
||||
tagged |= ((uint16_t)1) << port;
|
||||
vlan_settings.tagged |= ((uint16_t)1) << port;
|
||||
}
|
||||
if (port > machine.max_port)
|
||||
goto err;
|
||||
members |= ((uint16_t)1) << port;
|
||||
vlan_settings.members |= ((uint16_t)1) << port;
|
||||
}
|
||||
w++;
|
||||
}
|
||||
vlan_create(vlan, members, tagged);
|
||||
vlan_create();
|
||||
}
|
||||
if (cmd_words_b[2] > 0 && isletter(cmd_buffer[cmd_words_b[2]])) {
|
||||
print_string("vlan_ptr "); print_short(vlan_ptr); write_char(':');
|
||||
@@ -422,10 +422,10 @@ 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]) {
|
||||
phy_settings.port = cmd_buffer[cmd_words_b[1]] - '1';
|
||||
phy_settings.port = machine.phys_to_log_port[phy_settings.port];
|
||||
print_byte(phy_settings.port);
|
||||
if (machine.is_sfp[phy_settings.port]) {
|
||||
print_string(" is SFP no PHY information available.\n");
|
||||
return;
|
||||
}
|
||||
@@ -433,46 +433,53 @@ void parse_port(void)
|
||||
print_string("\nport <port> [show|on|off|10m|100m|1g|2g5] [half|full]");
|
||||
return;
|
||||
}
|
||||
phy_settings.duplex = PHY_DUPLEX_BOTH;
|
||||
if (cmd_compare(2, "10m")) {
|
||||
print_string(" 10M\n");
|
||||
phy_settings.speed = PHY_SPEED_10M;
|
||||
if (cmd_words_b[3] > 0 && cmd_compare(3, "half"))
|
||||
phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_HALF);
|
||||
phy_settings.duplex = PHY_DUPLEX_HALF;
|
||||
else if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||
phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_FULL);
|
||||
else
|
||||
phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_BOTH);
|
||||
phy_settings.duplex = PHY_DUPLEX_FULL;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "100m")) {
|
||||
print_string(" 100M\n");
|
||||
phy_settings.speed = PHY_SPEED_100M;
|
||||
if (cmd_words_b[3] > 0 && cmd_compare(3, "half"))
|
||||
phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_HALF);
|
||||
phy_settings.duplex = PHY_DUPLEX_HALF;
|
||||
else if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||
phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_FULL);
|
||||
else
|
||||
phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_BOTH);
|
||||
phy_settings.duplex = PHY_DUPLEX_FULL;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "2g5")) {
|
||||
print_string(" 2.5G\n");
|
||||
phy_set_speed(p, PHY_SPEED_2G5, PHY_DUPLEX_BOTH);
|
||||
phy_settings.speed = PHY_SPEED_2G5;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "1g")) {
|
||||
print_string(" 1G\n");
|
||||
phy_set_speed(p, PHY_SPEED_1G, PHY_DUPLEX_BOTH);
|
||||
phy_settings.speed = PHY_SPEED_1G;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "auto")) {
|
||||
print_string(" AUTO\n");
|
||||
phy_set_speed(p, PHY_SPEED_AUTO, PHY_DUPLEX_BOTH);
|
||||
phy_settings.speed = PHY_SPEED_AUTO;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "off")) {
|
||||
print_string(" OFF\n");
|
||||
phy_set_speed(p, PHY_OFF, PHY_DUPLEX_BOTH);
|
||||
phy_settings.speed = PHY_OFF;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "on")) {
|
||||
print_string(" ON\n");
|
||||
phy_set_speed(p, PHY_SPEED_AUTO, PHY_DUPLEX_BOTH);
|
||||
phy_settings.speed = PHY_SPEED_AUTO;
|
||||
phy_set_speed();
|
||||
} else if (cmd_compare(2, "duplex")) {
|
||||
print_string(" DUPLEX\n");
|
||||
if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||
phy_set_duplex(p, PHY_DUPLEX_FULL);
|
||||
phy_settings.speed = PHY_DUPLEX_FULL;
|
||||
else
|
||||
phy_set_duplex(p, PHY_DUPLEX_HALF);
|
||||
phy_settings.speed = PHY_DUPLEX_HALF;
|
||||
phy_set_duplex();
|
||||
}
|
||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "show")) {
|
||||
phy_show(p);
|
||||
phy_show(phy_settings.port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ __code const struct machine machine = {
|
||||
.sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||
.sfp_port[0].pin_los = GPIO10_LED10,
|
||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||
.sfp_port[0].sds = 1,
|
||||
.sfp_port[0].sds = 0,
|
||||
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||
.sfp_port[1].pin_los = GPIO37,
|
||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||
.sfp_port[1].sds = 0,
|
||||
.sfp_port[1].sds = 1,
|
||||
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||
.reset_pin = GPIO46_I2C_SCL0,
|
||||
};
|
||||
|
||||
+97
-50
@@ -24,6 +24,8 @@ extern __code uint16_t bit_mask[16];
|
||||
extern __code const struct machine machine;
|
||||
extern __xdata struct machine_runtime machine_detected;
|
||||
|
||||
__xdata struct phy_settings phy_settings;
|
||||
|
||||
// SDS-settings for RTL8224 first SerDes which is connected to the RTL837x-SOC.
|
||||
// Array contrains register-value, and SDS-CMD, which already encodes (sds_index, page, reg).
|
||||
// This array is used in phy_config_8224().
|
||||
@@ -186,106 +188,151 @@ void phy_config_8224(void) __banked
|
||||
* See e.g. RTL8221B datasheet
|
||||
* duplex: 0: half, 1: full, 2: both
|
||||
*/
|
||||
void phy_set_speed(uint8_t port, uint8_t speed, uint8_t duplex) __banked
|
||||
void phy_set_speed(void) __banked
|
||||
{
|
||||
uint16_t v;
|
||||
phy_read(port, PHY_MMD31, 0xa610);
|
||||
|
||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
||||
if (phy_settings.speed == PHY_OFF) {
|
||||
print_string(" to disabled");
|
||||
} else {
|
||||
print_string(" to speed ");
|
||||
switch(phy_settings.speed) {
|
||||
case PHY_SPEED_AUTO:
|
||||
print_string("auto");
|
||||
break;
|
||||
case PHY_SPEED_10M:
|
||||
print_string("10M");
|
||||
if (phy_settings.duplex)
|
||||
print_string(" full duplex");
|
||||
else
|
||||
print_string(" half duplex");
|
||||
break;
|
||||
case PHY_SPEED_100M:
|
||||
print_string("100M");
|
||||
if (phy_settings.duplex)
|
||||
print_string(" full duplex");
|
||||
else
|
||||
print_string(" half duplex");
|
||||
break;
|
||||
case PHY_SPEED_1G:
|
||||
print_string("1G");
|
||||
break;
|
||||
case PHY_SPEED_2G5:
|
||||
print_string("2G5");
|
||||
break;
|
||||
default:
|
||||
print_string("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_char('\n');
|
||||
|
||||
phy_read(phy_settings.port, PHY_MMD31, 0xa610);
|
||||
v = SFR_DATA_U16;
|
||||
if (speed == PHY_OFF) {
|
||||
phy_write(port, PHY_MMD31, 0xa610, v | 0x0800);
|
||||
if (phy_settings.speed == PHY_OFF) {
|
||||
phy_write(phy_settings.port, PHY_MMD31, 0xa610, v | 0x0800);
|
||||
return;
|
||||
}
|
||||
// Port is on, make sure of it:
|
||||
if (v & 0x0800)
|
||||
phy_write(port, PHY_MMD31, 0xa610, v & 0xf7ff);
|
||||
phy_write(phy_settings.port, PHY_MMD31, 0xa610, v & 0xf7ff);
|
||||
|
||||
if (speed == PHY_SPEED_AUTO) {
|
||||
if (phy_settings.speed == PHY_SPEED_AUTO) {
|
||||
// AN Advertisement Register (MMD 7.0x0010)
|
||||
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x15e1);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x15e1);
|
||||
// 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
|
||||
phy_write(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)
|
||||
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled
|
||||
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
||||
} else {
|
||||
// AN Control Register (MMD 7.0x0000)
|
||||
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
||||
if (speed == PHY_SPEED_10M) {
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||
if (!duplex)
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1421);
|
||||
else if (duplex == 1)
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1441);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
||||
if (phy_settings.speed == PHY_SPEED_10M) {
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||
if (!phy_settings.duplex)
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1421);
|
||||
else if (phy_settings.duplex == 1)
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1441);
|
||||
else
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1461);
|
||||
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||
} else if (speed == PHY_SPEED_100M) {
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||
if (!duplex)
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481);
|
||||
if (duplex == 1)
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1461);
|
||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||
} else if (phy_settings.speed == PHY_SPEED_100M) {
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||
if (!phy_settings.duplex)
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481);
|
||||
if (phy_settings.duplex == 1)
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501);
|
||||
else
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581);
|
||||
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581);
|
||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||
} else {
|
||||
// AN Advertisement Register (MMD 7.0x0010)
|
||||
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001);
|
||||
if (speed == PHY_SPEED_1G) {
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001);
|
||||
if (phy_settings.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, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200);
|
||||
} else if (speed == PHY_SPEED_2G5) {
|
||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200);
|
||||
} else if (phy_settings.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, 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)
|
||||
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||
}
|
||||
}
|
||||
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked
|
||||
void phy_set_duplex(void) __banked
|
||||
{
|
||||
uint16_t v;
|
||||
phy_read(port, PHY_MMD31, PHY_ANEG_CTRL);
|
||||
|
||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
||||
if (phy_settings.duplex)
|
||||
print_string(" to full duplex");
|
||||
else
|
||||
print_string(" to half duplex");
|
||||
write_char('\n');
|
||||
|
||||
phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL);
|
||||
v = SFR_DATA_U16;
|
||||
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
||||
phy_read(port, PHY_MMD31, PHY_MMD31_FEDCR);
|
||||
phy_read(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR);
|
||||
v = SFR_DATA_U16;
|
||||
if (fullduplex)
|
||||
if (phy_settings.duplex)
|
||||
v |= 0x0100;
|
||||
else
|
||||
v &= 0xfeff;
|
||||
phy_write(port, PHY_MMD31, PHY_MMD31_FEDCR, v);
|
||||
phy_write(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR, v);
|
||||
return;
|
||||
}
|
||||
// Disable AN
|
||||
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000);
|
||||
phy_read(port, PHY_MMD_AN, PHY_ANEG_ADV);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x2000);
|
||||
phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV);
|
||||
v = SFR_DATA_U16;
|
||||
if (v & 0x0060) {
|
||||
if (fullduplex)
|
||||
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffbf, 0x0040);
|
||||
if (phy_settings.duplex)
|
||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffbf, 0x0040);
|
||||
else
|
||||
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffdf, 0x0020);
|
||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffdf, 0x0020);
|
||||
}
|
||||
if (v & 0x0180) {
|
||||
if (fullduplex)
|
||||
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xfeff, 0x0100);
|
||||
if (phy_settings.duplex)
|
||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xfeff, 0x0100);
|
||||
else
|
||||
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080);
|
||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080);
|
||||
}
|
||||
// Restart AN
|
||||
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000);
|
||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000);
|
||||
}
|
||||
|
||||
|
||||
@@ -327,7 +374,7 @@ void phy_show(uint8_t port) __banked
|
||||
else
|
||||
print_string(" half duplex");
|
||||
|
||||
phy_read(port, PHY_MMD31, PHY_ANEG_CTRL);
|
||||
phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL);
|
||||
v = SFR_DATA_U16;
|
||||
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
||||
phy_read(port, PHY_MMD_PMAPMD, 0);
|
||||
|
||||
+10
-2
@@ -10,11 +10,19 @@
|
||||
#define PHY_SPEED_AUTO 0x10
|
||||
#define PHY_OFF 0xff
|
||||
|
||||
struct phy_settings {
|
||||
uint8_t duplex;
|
||||
uint8_t port;
|
||||
uint8_t speed;
|
||||
};
|
||||
|
||||
extern __xdata struct phy_settings phy_settings;
|
||||
|
||||
void rtl8224_phy_enable(void) __banked;
|
||||
void phy_config(uint8_t phy) __banked;
|
||||
void phy_config_8224(void) __banked;
|
||||
void phy_set_speed(uint8_t port, uint8_t speed, uint8_t duplex) __banked;
|
||||
void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked;
|
||||
void phy_set_speed(void) __banked;
|
||||
void phy_set_duplex(void) __banked;
|
||||
void phy_show(uint8_t port) __banked;
|
||||
void phy_reset(uint8_t port) __banked;
|
||||
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
||||
|
||||
+17
-11
@@ -28,6 +28,8 @@ extern __xdata struct machine_runtime machine_detected;
|
||||
|
||||
__xdata uint32_t l2_head;
|
||||
|
||||
__xdata struct vlan_settings vlan_settings;
|
||||
|
||||
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");
|
||||
@@ -46,7 +48,7 @@ void port_mirror_del(void) __banked
|
||||
}
|
||||
|
||||
|
||||
void port_ingress_filter(register uint8_t port, uint8_t type) __banked
|
||||
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked
|
||||
{
|
||||
if (type & 0x1)
|
||||
reg_bit_set(RTL837x_REG_INGRESS, port << 1);
|
||||
@@ -121,27 +123,31 @@ __xdata uint16_t vlan_name(register uint16_t vlan) __banked
|
||||
|
||||
|
||||
/*
|
||||
* Create a VLAN
|
||||
* The arguments are passed in global structure vlan_settings
|
||||
* A member that is not tagged, is untagged
|
||||
*/
|
||||
void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked
|
||||
void vlan_create(void) __banked
|
||||
{
|
||||
// For now, the CPU-port is always a tagged member:
|
||||
members |= 0x0200; // Set 10th bit
|
||||
tagged |= 0x0200;
|
||||
print_string("\nvlan_create called\nvlan: "); print_short(vlan);
|
||||
print_string(", members: "); print_short(members);
|
||||
print_string(", tagged: "); print_short(tagged); write_char('\n');
|
||||
vlan_settings.members |= 0x0200; // Set 10th bit
|
||||
vlan_settings.tagged |= 0x0200;
|
||||
|
||||
print_string("\nvlan_create called\nvlan: "); print_short(vlan_settings.vlan);
|
||||
print_string(", members: "); print_short(vlan_settings.members);
|
||||
print_string(", tagged: "); print_short(vlan_settings.tagged); write_char('\n');
|
||||
|
||||
uint16_t a = (~vlan_settings.members) ^ vlan_settings.tagged ^ vlan_settings.members;
|
||||
|
||||
uint16_t a = (~members) ^ tagged ^ members;
|
||||
// On RTL8372, port-bits 0-2 must be 0, although they are not members
|
||||
if (!machine_detected.isRTL8373) {
|
||||
a &= 0x1f8;
|
||||
tagged &= 0x3f8;
|
||||
vlan_settings.tagged &= 0x3f8;
|
||||
}
|
||||
|
||||
// Initialize VLAN table with VLAN 1
|
||||
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (members >> 8), members);
|
||||
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
||||
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (vlan_settings.members >> 8), vlan_settings.members);
|
||||
REG_WRITE(RTL837X_TBL_CTRL, vlan_settings.vlan >> 8, vlan_settings.vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
||||
do {
|
||||
reg_read_m(RTL837X_TBL_CTRL);
|
||||
} while (sfr_data[3] & TBL_EXECUTE);
|
||||
|
||||
+10
-2
@@ -13,6 +13,14 @@
|
||||
reg_read_m(RTL837X_STAT_GET); \
|
||||
} while (sfr_data[3] & 0x1);
|
||||
|
||||
struct vlan_settings {
|
||||
uint16_t vlan;
|
||||
uint16_t members;
|
||||
uint16_t tagged;
|
||||
};
|
||||
|
||||
extern __xdata struct vlan_settings vlan_settings;
|
||||
|
||||
uint8_t port_l2_forget(void) __banked;
|
||||
void port_l2_learned(void) __banked;
|
||||
void port_stats_print(void) __banked;
|
||||
@@ -20,11 +28,11 @@ int8_t vlan_get(register uint16_t vlan) __banked;
|
||||
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
|
||||
void vlan_setup(void) __banked;
|
||||
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
||||
void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked;
|
||||
void vlan_create(void) __banked;
|
||||
void vlan_delete(uint16_t vlan) __banked;
|
||||
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
||||
void port_mirror_del(void) __banked;
|
||||
void port_ingress_filter(register uint8_t port, uint8_t type) __banked;
|
||||
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked;
|
||||
void port_l2_setup(void) __banked;
|
||||
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked;
|
||||
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked;
|
||||
|
||||
Reference in New Issue
Block a user