mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 18:19:02 +00:00
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>
This commit is contained in:
parent
637deabb4a
commit
515d9c85f2
@ -577,58 +577,55 @@ static void rtl83xx_port_disable(struct dsa_switch *ds, int port)
|
|||||||
priv->ports[port].enable = false;
|
priv->ports[port].enable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl83xx_get_mac_eee(struct dsa_switch *ds, int port,
|
|
||||||
struct ethtool_eee *e)
|
|
||||||
{
|
|
||||||
struct rtl838x_switch_priv *priv = ds->priv;
|
|
||||||
|
|
||||||
pr_debug("%s: port %d", __func__, port);
|
|
||||||
e->supported = SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full;
|
|
||||||
if (sw_r32(priv->r->mac_force_mode_ctrl(port)) & BIT(9))
|
|
||||||
e->advertised |= ADVERTISED_100baseT_Full;
|
|
||||||
|
|
||||||
if (sw_r32(priv->r->mac_force_mode_ctrl(port)) & BIT(10))
|
|
||||||
e->advertised |= ADVERTISED_1000baseT_Full;
|
|
||||||
|
|
||||||
e->eee_enabled = priv->ports[port].eee_enabled;
|
|
||||||
pr_debug("enabled: %d, active %x\n", e->eee_enabled, e->advertised);
|
|
||||||
|
|
||||||
if (sw_r32(RTL838X_MAC_EEE_ABLTY) & BIT(port)) {
|
|
||||||
e->lp_advertised = ADVERTISED_100baseT_Full;
|
|
||||||
e->lp_advertised |= ADVERTISED_1000baseT_Full;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->eee_active = !!(e->advertised & e->lp_advertised);
|
|
||||||
pr_debug("active: %d, lp %x\n", e->eee_active, e->lp_advertised);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtl83xx_set_mac_eee(struct dsa_switch *ds, int port,
|
static int rtl83xx_set_mac_eee(struct dsa_switch *ds, int port,
|
||||||
struct ethtool_eee *e)
|
struct ethtool_eee *e)
|
||||||
{
|
{
|
||||||
struct rtl838x_switch_priv *priv = ds->priv;
|
struct rtl838x_switch_priv *priv = ds->priv;
|
||||||
|
|
||||||
pr_debug("%s: port %d", __func__, port);
|
if (e->eee_enabled && !priv->eee_enabled) {
|
||||||
if (e->eee_enabled) {
|
pr_info("Globally enabling EEE\n");
|
||||||
pr_debug("Globally enabling EEE\n");
|
priv->r->init_eee(priv, true);
|
||||||
sw_w32_mask(0x4, 0, RTL838X_SMI_GLB_CTRL);
|
|
||||||
}
|
|
||||||
if (e->eee_enabled) {
|
|
||||||
pr_debug("Enabling EEE for MAC %d\n", port);
|
|
||||||
sw_w32_mask(0, 3 << 9, priv->r->mac_force_mode_ctrl(port));
|
|
||||||
sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_TX_EN);
|
|
||||||
sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_RX_EN);
|
|
||||||
priv->ports[port].eee_enabled = true;
|
|
||||||
e->eee_enabled = true;
|
|
||||||
} else {
|
|
||||||
pr_debug("Disabling EEE for MAC %d\n", port);
|
|
||||||
sw_w32_mask(3 << 9, 0, priv->r->mac_force_mode_ctrl(port));
|
|
||||||
sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_TX_EN);
|
|
||||||
sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_RX_EN);
|
|
||||||
priv->ports[port].eee_enabled = false;
|
|
||||||
e->eee_enabled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->r->port_eee_set(priv, port, e->eee_enabled);
|
||||||
|
|
||||||
|
if (e->eee_enabled)
|
||||||
|
pr_info("Enabled EEE for port %d\n", port);
|
||||||
|
else
|
||||||
|
pr_info("Disabled EEE for port %d\n", port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl83xx_get_mac_eee(struct dsa_switch *ds, int port,
|
||||||
|
struct ethtool_eee *e)
|
||||||
|
{
|
||||||
|
struct rtl838x_switch_priv *priv = ds->priv;
|
||||||
|
|
||||||
|
e->supported = SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full;
|
||||||
|
|
||||||
|
priv->r->eee_port_ability(priv, e, port);
|
||||||
|
|
||||||
|
e->eee_enabled = priv->ports[port].eee_enabled;
|
||||||
|
|
||||||
|
e->eee_active = !!(e->advertised & e->lp_advertised);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl93xx_get_mac_eee(struct dsa_switch *ds, int port,
|
||||||
|
struct ethtool_eee *e)
|
||||||
|
{
|
||||||
|
struct rtl838x_switch_priv *priv = ds->priv;
|
||||||
|
|
||||||
|
e->supported = SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full
|
||||||
|
| SUPPORTED_2500baseX_Full;
|
||||||
|
|
||||||
|
priv->r->eee_port_ability(priv, e, port);
|
||||||
|
|
||||||
|
e->eee_enabled = priv->ports[port].eee_enabled;
|
||||||
|
|
||||||
|
e->eee_active = !!(e->advertised & e->lp_advertised);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,6 +1329,9 @@ const struct dsa_switch_ops rtl930x_switch_ops = {
|
|||||||
.port_enable = rtl83xx_port_enable,
|
.port_enable = rtl83xx_port_enable,
|
||||||
.port_disable = rtl83xx_port_disable,
|
.port_disable = rtl83xx_port_disable,
|
||||||
|
|
||||||
|
.get_mac_eee = rtl93xx_get_mac_eee,
|
||||||
|
.set_mac_eee = rtl83xx_set_mac_eee,
|
||||||
|
|
||||||
.set_ageing_time = rtl83xx_set_l2aging,
|
.set_ageing_time = rtl83xx_set_l2aging,
|
||||||
.port_bridge_join = rtl83xx_port_bridge_join,
|
.port_bridge_join = rtl83xx_port_bridge_join,
|
||||||
.port_bridge_leave = rtl83xx_port_bridge_leave,
|
.port_bridge_leave = rtl83xx_port_bridge_leave,
|
||||||
|
@ -263,6 +263,84 @@ void rtl838x_traffic_disable(int source, int dest)
|
|||||||
rtl838x_mask_port_reg(BIT(dest), 0, rtl838x_port_iso_ctrl(source));
|
rtl838x_mask_port_reg(BIT(dest), 0, rtl838x_port_iso_ctrl(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enables or disables the EEE/EEEP capability of a port
|
||||||
|
*/
|
||||||
|
static void rtl838x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable)
|
||||||
|
{
|
||||||
|
u32 v;
|
||||||
|
|
||||||
|
// This works only for Ethernet ports, and on the RTL838X, ports from 24 are SFP
|
||||||
|
if (port >= 24)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pr_debug("In %s: setting port %d to %d\n", __func__, port, enable);
|
||||||
|
v = enable ? 0x3 : 0x0;
|
||||||
|
|
||||||
|
// Set EEE state for 100 (bit 9) & 1000MBit (bit 10)
|
||||||
|
sw_w32_mask(0x3 << 9, v << 9, priv->r->mac_force_mode_ctrl(port));
|
||||||
|
|
||||||
|
// Set TX/RX EEE state
|
||||||
|
if (enable) {
|
||||||
|
sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_TX_EN);
|
||||||
|
sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_RX_EN);
|
||||||
|
} else {
|
||||||
|
sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_TX_EN);
|
||||||
|
sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_RX_EN);
|
||||||
|
}
|
||||||
|
priv->ports[port].eee_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get EEE own capabilities and negotiation result
|
||||||
|
*/
|
||||||
|
static int rtl838x_eee_port_ability(struct rtl838x_switch_priv *priv,
|
||||||
|
struct ethtool_eee *e, int port)
|
||||||
|
{
|
||||||
|
u64 link;
|
||||||
|
|
||||||
|
if (port >= 24)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
link = rtl839x_get_port_reg_le(RTL838X_MAC_LINK_STS);
|
||||||
|
if (!(link & BIT(port)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sw_r32(rtl838x_mac_force_mode_ctrl(port)) & BIT(9))
|
||||||
|
e->advertised |= ADVERTISED_100baseT_Full;
|
||||||
|
|
||||||
|
if (sw_r32(rtl838x_mac_force_mode_ctrl(port)) & BIT(10))
|
||||||
|
e->advertised |= ADVERTISED_1000baseT_Full;
|
||||||
|
|
||||||
|
if (sw_r32(RTL838X_MAC_EEE_ABLTY) & BIT(port)) {
|
||||||
|
e->lp_advertised = ADVERTISED_100baseT_Full;
|
||||||
|
e->lp_advertised |= ADVERTISED_1000baseT_Full;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl838x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pr_info("Setting up EEE, state: %d\n", enable);
|
||||||
|
sw_w32_mask(0x4, 0, RTL838X_SMI_GLB_CTRL);
|
||||||
|
|
||||||
|
/* Set timers for EEE */
|
||||||
|
sw_w32(0x5001411, RTL838X_EEE_TX_TIMER_GIGA_CTRL);
|
||||||
|
sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL);
|
||||||
|
|
||||||
|
// Enable EEE MAC support on ports
|
||||||
|
for (i = 0; i < priv->cpu_port; i++) {
|
||||||
|
if (priv->ports[i].phy)
|
||||||
|
rtl838x_port_eee_set(priv, i, enable);
|
||||||
|
}
|
||||||
|
priv->eee_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
const struct rtl838x_reg rtl838x_reg = {
|
const struct rtl838x_reg rtl838x_reg = {
|
||||||
.mask_port_reg_be = rtl838x_mask_port_reg,
|
.mask_port_reg_be = rtl838x_mask_port_reg,
|
||||||
.set_port_reg_be = rtl838x_set_port_reg,
|
.set_port_reg_be = rtl838x_set_port_reg,
|
||||||
@ -317,6 +395,9 @@ const struct rtl838x_reg rtl838x_reg = {
|
|||||||
.trk_mbr_ctr = rtl838x_trk_mbr_ctr,
|
.trk_mbr_ctr = rtl838x_trk_mbr_ctr,
|
||||||
.rma_bpdu_fld_pmask = RTL838X_RMA_BPDU_FLD_PMSK,
|
.rma_bpdu_fld_pmask = RTL838X_RMA_BPDU_FLD_PMSK,
|
||||||
.spcl_trap_eapol_ctrl = RTL838X_SPCL_TRAP_EAPOL_CTRL,
|
.spcl_trap_eapol_ctrl = RTL838X_SPCL_TRAP_EAPOL_CTRL,
|
||||||
|
.init_eee = rtl838x_init_eee,
|
||||||
|
.port_eee_set = rtl838x_port_eee_set,
|
||||||
|
.eee_port_ability = rtl838x_eee_port_ability,
|
||||||
};
|
};
|
||||||
|
|
||||||
irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
|
irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
|
||||||
|
@ -162,6 +162,16 @@
|
|||||||
#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04)
|
#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04)
|
||||||
#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08)
|
#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08)
|
||||||
|
|
||||||
|
#define RTL839X_EEE_TX_TIMER_GELITE_CTRL (0x042C)
|
||||||
|
#define RTL839X_EEE_TX_TIMER_GIGA_CTRL (0x0430)
|
||||||
|
#define RTL839X_EEE_TX_TIMER_10G_CTRL (0x0434)
|
||||||
|
#define RTL839X_EEE_CTRL(p) (0x8008 + ((p) << 7))
|
||||||
|
#define RTL839X_MAC_EEE_ABLTY (0x03C8)
|
||||||
|
|
||||||
|
#define RTL930X_MAC_EEE_ABLTY (0xCB34)
|
||||||
|
#define RTL930X_EEE_CTRL(p) (0x3274 + ((p) << 6))
|
||||||
|
#define RTL930X_EEEP_PORT_CTRL(p) (0x3278 + ((p) << 6))
|
||||||
|
|
||||||
/* L2 functionality */
|
/* L2 functionality */
|
||||||
#define RTL838X_L2_CTRL_0 (0x3200)
|
#define RTL838X_L2_CTRL_0 (0x3200)
|
||||||
#define RTL839X_L2_CTRL_0 (0x3800)
|
#define RTL839X_L2_CTRL_0 (0x3800)
|
||||||
@ -440,6 +450,10 @@ struct rtl838x_reg {
|
|||||||
int (*trk_mbr_ctr)(int group);
|
int (*trk_mbr_ctr)(int group);
|
||||||
int rma_bpdu_fld_pmask;
|
int rma_bpdu_fld_pmask;
|
||||||
int spcl_trap_eapol_ctrl;
|
int spcl_trap_eapol_ctrl;
|
||||||
|
void (*init_eee)(struct rtl838x_switch_priv *priv, bool enable);
|
||||||
|
void (*port_eee_set)(struct rtl838x_switch_priv *priv, int port, bool enable);
|
||||||
|
int (*eee_port_ability)(struct rtl838x_switch_priv *priv,
|
||||||
|
struct ethtool_eee *e, int port);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtl838x_switch_priv {
|
struct rtl838x_switch_priv {
|
||||||
@ -466,6 +480,7 @@ struct rtl838x_switch_priv {
|
|||||||
u64 lags_port_members[MAX_LAGS];
|
u64 lags_port_members[MAX_LAGS];
|
||||||
struct net_device *lag_devs[MAX_LAGS];
|
struct net_device *lag_devs[MAX_LAGS];
|
||||||
struct notifier_block nb;
|
struct notifier_block nb;
|
||||||
|
bool eee_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv);
|
void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv);
|
||||||
|
@ -456,6 +456,83 @@ static void rtl839x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port
|
|||||||
priv->r->exec_tbl0_cmd(cmd);
|
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 = {
|
const struct rtl838x_reg rtl839x_reg = {
|
||||||
.mask_port_reg_be = rtl839x_mask_port_reg_be,
|
.mask_port_reg_be = rtl839x_mask_port_reg_be,
|
||||||
.set_port_reg_be = rtl839x_set_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,
|
.trk_mbr_ctr = rtl839x_trk_mbr_ctr,
|
||||||
.rma_bpdu_fld_pmask = RTL839X_RMA_BPDU_FLD_PMSK,
|
.rma_bpdu_fld_pmask = RTL839X_RMA_BPDU_FLD_PMSK,
|
||||||
.spcl_trap_eapol_ctrl = RTL839X_SPCL_TRAP_EAPOL_CTRL,
|
.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,
|
||||||
};
|
};
|
||||||
|
@ -551,6 +551,95 @@ u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed)
|
|||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Enables or disables the EEE/EEEP capability of a port
|
||||||
|
*/
|
||||||
|
void rtl930x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable)
|
||||||
|
{
|
||||||
|
u32 v;
|
||||||
|
|
||||||
|
// This works only for Ethernet ports, and on the RTL930X, ports from 26 are SFP
|
||||||
|
if (port >= 26)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pr_debug("In %s: setting port %d to %d\n", __func__, port, enable);
|
||||||
|
v = enable ? 0x3f : 0x0;
|
||||||
|
|
||||||
|
// Set EEE/EEEP state for 100, 500, 1000MBit and 2.5, 5 and 10GBit
|
||||||
|
sw_w32_mask(0, v << 10, rtl930x_mac_force_mode_ctrl(port));
|
||||||
|
|
||||||
|
// Set TX/RX EEE state
|
||||||
|
v = enable ? 0x3 : 0x0;
|
||||||
|
sw_w32(v, RTL930X_EEE_CTRL(port));
|
||||||
|
|
||||||
|
priv->ports[port].eee_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get EEE own capabilities and negotiation result
|
||||||
|
*/
|
||||||
|
int rtl930x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port)
|
||||||
|
{
|
||||||
|
u32 link, a;
|
||||||
|
|
||||||
|
if (port >= 26)
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
pr_info("In %s, port %d\n", __func__, port);
|
||||||
|
link = sw_r32(RTL930X_MAC_LINK_STS);
|
||||||
|
link = sw_r32(RTL930X_MAC_LINK_STS);
|
||||||
|
if (!(link & BIT(port)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pr_info("Setting advertised\n");
|
||||||
|
if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(10))
|
||||||
|
e->advertised |= ADVERTISED_100baseT_Full;
|
||||||
|
|
||||||
|
if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(12))
|
||||||
|
e->advertised |= ADVERTISED_1000baseT_Full;
|
||||||
|
|
||||||
|
if (priv->ports[port].is2G5 && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(13)) {
|
||||||
|
pr_info("ADVERTISING 2.5G EEE\n");
|
||||||
|
e->advertised |= ADVERTISED_2500baseX_Full;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->ports[port].is10G && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(15))
|
||||||
|
e->advertised |= ADVERTISED_10000baseT_Full;
|
||||||
|
|
||||||
|
a = sw_r32(RTL930X_MAC_EEE_ABLTY);
|
||||||
|
a = sw_r32(RTL930X_MAC_EEE_ABLTY);
|
||||||
|
pr_info("Link partner: %08x\n", a);
|
||||||
|
if (a & BIT(port)) {
|
||||||
|
e->lp_advertised = ADVERTISED_100baseT_Full;
|
||||||
|
e->lp_advertised |= ADVERTISED_1000baseT_Full;
|
||||||
|
if (priv->ports[port].is2G5)
|
||||||
|
e->lp_advertised |= ADVERTISED_2500baseX_Full;
|
||||||
|
if (priv->ports[port].is10G)
|
||||||
|
e->lp_advertised |= ADVERTISED_10000baseT_Full;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read 2x to clear latched state
|
||||||
|
a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
|
||||||
|
a = sw_r32(RTL930X_EEEP_PORT_CTRL(port));
|
||||||
|
pr_info("%s RTL930X_EEEP_PORT_CTRL: %08x\n", __func__, a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pr_info("Setting up EEE, state: %d\n", enable);
|
||||||
|
|
||||||
|
// Setup EEE on all ports
|
||||||
|
for (i = 0; i < priv->cpu_port; i++) {
|
||||||
|
if (priv->ports[i].phy)
|
||||||
|
rtl930x_port_eee_set(priv, i, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->eee_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
const struct rtl838x_reg rtl930x_reg = {
|
const struct rtl838x_reg rtl930x_reg = {
|
||||||
.mask_port_reg_be = rtl838x_mask_port_reg,
|
.mask_port_reg_be = rtl838x_mask_port_reg,
|
||||||
@ -604,4 +693,7 @@ const struct rtl838x_reg rtl930x_reg = {
|
|||||||
.vlan_port_tag_sts_ctrl = RTL930X_VLAN_PORT_TAG_STS_CTRL,
|
.vlan_port_tag_sts_ctrl = RTL930X_VLAN_PORT_TAG_STS_CTRL,
|
||||||
.trk_mbr_ctr = rtl930x_trk_mbr_ctr,
|
.trk_mbr_ctr = rtl930x_trk_mbr_ctr,
|
||||||
.rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
|
.rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
|
||||||
|
.init_eee = rtl930x_init_eee,
|
||||||
|
.port_eee_set = rtl930x_port_eee_set,
|
||||||
|
.eee_port_ability = rtl930x_eee_port_ability,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user