diff options
author | Birger Koblitz <git@birger-koblitz.de> | 2021-05-01 08:22:36 +0200 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2021-05-07 07:05:16 +0200 |
commit | 515d9c85f22241b4ec08dbb3d63f6469ef412384 (patch) | |
tree | 3c30cdec35f7cad0739eea782aa33028995ab48f /target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c | |
parent | 637deabb4a50812c978ef3b768609720b8856a9b (diff) | |
download | upstream-515d9c85f22241b4ec08dbb3d63f6469ef412384.tar.gz upstream-515d9c85f22241b4ec08dbb3d63f6469ef412384.tar.bz2 upstream-515d9c85f22241b4ec08dbb3d63f6469ef412384.zip |
realtek: improve EEE support for RTL8380/8390/9300
Clean up and fix bugs in the EEE support for RTL8380/90
Adds EEE support for RTL9300
Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
Diffstat (limited to 'target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c')
-rw-r--r-- | target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c index 5106bd2e9d..b9fdd2c955 100644 --- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c @@ -456,6 +456,83 @@ static void rtl839x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port priv->r->exec_tbl0_cmd(cmd); } +/* + * Enables or disables the EEE/EEEP capability of a port + */ +void rtl839x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable) +{ + u32 v; + + // This works only for Ethernet ports, and on the RTL839X, ports above 47 are SFP + if (port >= 48) + return; + + enable = true; + pr_debug("In %s: setting port %d to %d\n", __func__, port, enable); + v = enable ? 0xf : 0x0; + + // Set EEE for 100, 500, 1000MBit and 10GBit + sw_w32_mask(0xf << 8, v << 8, rtl839x_mac_force_mode_ctrl(port)); + + // Set TX/RX EEE state + v = enable ? 0x3 : 0x0; + sw_w32(v, RTL839X_EEE_CTRL(port)); + + priv->ports[port].eee_enabled = enable; +} + +/* + * Get EEE own capabilities and negotiation result + */ +int rtl839x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port) +{ + u64 link, a; + + if (port >= 48) + return 0; + + link = rtl839x_get_port_reg_le(RTL839X_MAC_LINK_STS); + if (!(link & BIT_ULL(port))) + return 0; + + if (sw_r32(rtl839x_mac_force_mode_ctrl(port)) & BIT(8)) + e->advertised |= ADVERTISED_100baseT_Full; + + if (sw_r32(rtl839x_mac_force_mode_ctrl(port)) & BIT(10)) + e->advertised |= ADVERTISED_1000baseT_Full; + + a = rtl839x_get_port_reg_le(RTL839X_MAC_EEE_ABLTY); + pr_info("Link partner: %016llx\n", a); + if (rtl839x_get_port_reg_le(RTL839X_MAC_EEE_ABLTY) & BIT_ULL(port)) { + e->lp_advertised = ADVERTISED_100baseT_Full; + e->lp_advertised |= ADVERTISED_1000baseT_Full; + return 1; + } + + return 0; +} + +static void rtl839x_init_eee(struct rtl838x_switch_priv *priv, bool enable) +{ + int i; + + pr_info("Setting up EEE, state: %d\n", enable); + + // Set wake timer for TX and pause timer both to 0x21 + sw_w32_mask(0xff << 20| 0xff, 0x21 << 20| 0x21, RTL839X_EEE_TX_TIMER_GELITE_CTRL); + // Set pause wake timer for GIGA-EEE to 0x11 + sw_w32_mask(0xff << 20, 0x11 << 20, RTL839X_EEE_TX_TIMER_GIGA_CTRL); + // Set pause wake timer for 10GBit ports to 0x11 + sw_w32_mask(0xff << 20, 0x11 << 20, RTL839X_EEE_TX_TIMER_10G_CTRL); + + // Setup EEE on all ports + for (i = 0; i < priv->cpu_port; i++) { + if (priv->ports[i].phy) + rtl839x_port_eee_set(priv, i, enable); + } + priv->eee_enabled = enable; +} + const struct rtl838x_reg rtl839x_reg = { .mask_port_reg_be = rtl839x_mask_port_reg_be, .set_port_reg_be = rtl839x_set_port_reg_be, @@ -510,4 +587,7 @@ const struct rtl838x_reg rtl839x_reg = { .trk_mbr_ctr = rtl839x_trk_mbr_ctr, .rma_bpdu_fld_pmask = RTL839X_RMA_BPDU_FLD_PMSK, .spcl_trap_eapol_ctrl = RTL839X_SPCL_TRAP_EAPOL_CTRL, + .init_eee = rtl839x_init_eee, + .port_eee_set = rtl839x_port_eee_set, + .eee_port_ability = rtl839x_eee_port_ability, }; |