realtek: enable SerDes NWAY and SGMII negotiation
This allows copper SFPs to negotiate speeds lower than 1gig. Acked-by: Birger Koblitz <mail@birger-koblitz.de> Signed-off-by: Bjørn Mork <bjorn@mork.no> (cherry picked from commit 963b2ae702510c11e912c9438fdb9222763a22d5)
This commit is contained in:
parent
037dc6b251
commit
37920d6ee1
@ -368,8 +368,8 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
|
|||||||
|
|
||||||
/* Enable PHY control via SoC */
|
/* Enable PHY control via SoC */
|
||||||
if (priv->family_id == RTL8380_FAMILY_ID) {
|
if (priv->family_id == RTL8380_FAMILY_ID) {
|
||||||
/* Enable PHY control via SoC */
|
/* Enable SerDes NWAY and PHY control via SoC */
|
||||||
sw_w32_mask(0, BIT(15), RTL838X_SMI_GLB_CTRL);
|
sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL);
|
||||||
} else {
|
} else {
|
||||||
/* Disable PHY polling via SoC */
|
/* Disable PHY polling via SoC */
|
||||||
sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL);
|
sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL);
|
||||||
|
@ -344,6 +344,44 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rtl83xx_config_interface(int port, phy_interface_t interface)
|
||||||
|
{
|
||||||
|
u32 old, int_shift, sds_shift;
|
||||||
|
|
||||||
|
switch (port) {
|
||||||
|
case 24:
|
||||||
|
int_shift = 0;
|
||||||
|
sds_shift = 5;
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
int_shift = 3;
|
||||||
|
sds_shift = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = sw_r32(RTL838X_SDS_MODE_SEL);
|
||||||
|
switch (interface) {
|
||||||
|
case PHY_INTERFACE_MODE_1000BASEX:
|
||||||
|
if ((old >> sds_shift & 0x1f) == 4)
|
||||||
|
return;
|
||||||
|
sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL);
|
||||||
|
sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL);
|
||||||
|
break;
|
||||||
|
case PHY_INTERFACE_MODE_SGMII:
|
||||||
|
if ((old >> sds_shift & 0x1f) == 2)
|
||||||
|
return;
|
||||||
|
sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL);
|
||||||
|
sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pr_debug("configured port %d for interface %s\n", port, phy_modes(interface));
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
|
static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
|
||||||
unsigned int mode,
|
unsigned int mode,
|
||||||
const struct phylink_link_state *state)
|
const struct phylink_link_state *state)
|
||||||
@ -377,10 +415,11 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
|
|||||||
reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
|
reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
|
||||||
/* Auto-Negotiation does not work for MAC in RTL8390 */
|
/* Auto-Negotiation does not work for MAC in RTL8390 */
|
||||||
if (priv->family_id == RTL8380_FAMILY_ID) {
|
if (priv->family_id == RTL8380_FAMILY_ID) {
|
||||||
if (mode == MLO_AN_PHY) {
|
if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
|
||||||
pr_debug("PHY autonegotiates\n");
|
pr_debug("PHY autonegotiates\n");
|
||||||
reg |= BIT(2);
|
reg |= BIT(2);
|
||||||
sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
|
sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
|
||||||
|
rtl83xx_config_interface(port, state->interface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user