return 0;
}
-static int rtl83xx_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
+static int rtldsa_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *eee)
{
- 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_keee *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);
+ /*
+ * Until kernel 6.6 the Realtek device specific get_mac_eee() functions filled many
+ * fields of the eee structure manually. That came from the fact, that the phy
+ * driver could not report EEE capabilities on its own. Upstream will replace this
+ * function with a simple boolean support_eee() getter starting from 6.14. That only
+ * checks if a port can provide EEE or not. In the best case it can be replaced with
+ * dsa_supports_eee() in the future. For now align to other upstream DSA drivers.
+ */
return 0;
}
.port_enable = rtl83xx_port_enable,
.port_disable = rtl83xx_port_disable,
- .get_mac_eee = rtl83xx_get_mac_eee,
+ .get_mac_eee = rtldsa_get_mac_eee,
.set_mac_eee = rtl83xx_set_mac_eee,
.set_ageing_time = rtl83xx_set_ageing_time,
.port_enable = rtl83xx_port_enable,
.port_disable = rtl83xx_port_disable,
- .get_mac_eee = rtl93xx_get_mac_eee,
+ .get_mac_eee = rtldsa_get_mac_eee,
.set_mac_eee = rtl83xx_set_mac_eee,
.set_ageing_time = rtl83xx_set_ageing_time,
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)
{
pr_debug("Setting up EEE, state: %d\n", enable);
.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,
.l2_hash_seed = rtl838x_l2_hash_seed,
.l2_hash_key = rtl838x_l2_hash_key,
.read_mcast_pmask = rtl838x_read_mcast_pmask,
#define RTL930X_EEE_CTRL(p) (0x3274 + ((p) << 6))
#define RTL930X_EEEP_PORT_CTRL(p) (0x3278 + ((p) << 6))
+#define RTL931X_MAC_EEE_ABLTY (0x0f08)
+
/* L2 functionality */
#define RTL838X_L2_CTRL_0 (0x3200)
#define RTL839X_L2_CTRL_0 (0x3800)
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);
u64 (*l2_hash_seed)(u64 mac, u32 vid);
u32 (*l2_hash_key)(struct rtl838x_switch_priv *priv, u64 seed);
u64 (*read_mcast_pmask)(int idx);
priv->ports[port].eee_enabled = enable;
}
-/* Get EEE own capabilities and negotiation result */
-static 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_debug("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)
{
pr_debug("Setting up EEE, state: %d\n", enable);
.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,
.l2_hash_seed = rtl839x_l2_hash_seed,
.l2_hash_key = rtl839x_l2_hash_key,
.read_mcast_pmask = rtl839x_read_mcast_pmask,
priv->ports[port].eee_enabled = enable;
}
-/* Get EEE own capabilities and negotiation result */
-static 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_debug("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_debug("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_debug("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_debug("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_debug("%s RTL930X_EEEP_PORT_CTRL: %08x\n", __func__, a);
-
- return 0;
-}
-
static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
{
pr_debug("Setting up EEE, state: %d\n", enable);
.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,
.l2_hash_seed = rtl930x_l2_hash_seed,
.l2_hash_key = rtl930x_l2_hash_key,
.read_mcast_pmask = rtl930x_read_mcast_pmask,