Commit a853c68e authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: pcs: xpcs: export xpcs_do_config and xpcs_link_up

The sja1105 hardware has a quirk in that some changes require a switch
reset, which loses all configuration. When the reset is initiated,
everything needs to be reprogrammed, including the MACs and the PCS.
This is currently done in sja1105_static_config_reload() - we manually
call sja1105_adjust_port_config(), sja1105_sgmii_pcs_config() and
sja1105_sgmii_pcs_force_speed() which are all internal functions.

There is a desire for sja1105 to use the common xpcs driver, and that
means that the equivalents of those functions, xpcs_do_config() and
xpcs_link_up() respectively, will no longer be local functions.

Forcing phylink to retrigger a resolve somehow, say by doing dev_close()
followed by dev_open() is not really an option, because the CPU port
might have a PCS as well, and there is no net device which we can close
and reopen for that. Additionally, the dev_close/dev_open sequence might
force a renegotiation of the copper-side link for SGMII ports connected
to a PHY, and this is undesirable as well, because the switch reset is
much quicker than a PHY autoneg, so we would have a lot more downtime.

The only solution I see is for the sja1105 driver to keep doing what
it's doing, and that means we need to export the equivalents from xpcs
for sja1105_sgmii_pcs_config and sja1105_sgmii_pcs_force_speed, and call
them directly in sja1105_static_config_reload(). This will be done
during the conversion patch.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f7380bba
...@@ -757,7 +757,7 @@ static int xpcs_config_2500basex(struct dw_xpcs *xpcs) ...@@ -757,7 +757,7 @@ static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret); return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
} }
static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
unsigned int mode) unsigned int mode)
{ {
const struct xpcs_compat *compat; const struct xpcs_compat *compat;
...@@ -797,6 +797,7 @@ static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, ...@@ -797,6 +797,7 @@ static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(xpcs_do_config);
static int xpcs_config(struct phylink_pcs *pcs, unsigned int mode, static int xpcs_config(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface, phy_interface_t interface,
...@@ -945,7 +946,7 @@ static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode, ...@@ -945,7 +946,7 @@ static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode,
pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret)); pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
} }
static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface, int speed, int duplex) phy_interface_t interface, int speed, int duplex)
{ {
struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
...@@ -955,6 +956,7 @@ static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, ...@@ -955,6 +956,7 @@ static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
if (interface == PHY_INTERFACE_MODE_SGMII) if (interface == PHY_INTERFACE_MODE_SGMII)
return xpcs_link_up_sgmii(xpcs, mode, speed, duplex); return xpcs_link_up_sgmii(xpcs, mode, speed, duplex);
} }
EXPORT_SYMBOL_GPL(xpcs_link_up);
static u32 xpcs_get_id(struct dw_xpcs *xpcs) static u32 xpcs_get_id(struct dw_xpcs *xpcs)
{ {
......
...@@ -27,6 +27,10 @@ struct dw_xpcs { ...@@ -27,6 +27,10 @@ struct dw_xpcs {
}; };
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface); int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface, int speed, int duplex);
int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
unsigned int mode);
void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported, void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
struct phylink_link_state *state); struct phylink_link_state *state);
int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment