diff options
| -rw-r--r-- | drivers/net/ethernet/mscc/ocelot.c | 40 | ||||
| -rw-r--r-- | drivers/net/ethernet/mscc/ocelot_net.c | 29 | ||||
| -rw-r--r-- | include/soc/mscc/ocelot.h | 4 | 
3 files changed, 47 insertions, 26 deletions
| diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 8292e93a3782..1502bb2c8ea7 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -7,6 +7,7 @@  #include <linux/dsa/ocelot.h>  #include <linux/if_bridge.h>  #include <linux/iopoll.h> +#include <linux/phy/phy.h>  #include <soc/mscc/ocelot_hsio.h>  #include <soc/mscc/ocelot_vcap.h>  #include "ocelot.h" @@ -809,6 +810,45 @@ static int ocelot_port_flush(struct ocelot *ocelot, int port)  	return err;  } +int ocelot_port_configure_serdes(struct ocelot *ocelot, int port, +				 struct device_node *portnp) +{ +	struct ocelot_port *ocelot_port = ocelot->ports[port]; +	struct device *dev = ocelot->dev; +	int err; + +	/* Ensure clock signals and speed are set on all QSGMII links */ +	if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_QSGMII) +		ocelot_port_rmwl(ocelot_port, 0, +				 DEV_CLOCK_CFG_MAC_TX_RST | +				 DEV_CLOCK_CFG_MAC_RX_RST, +				 DEV_CLOCK_CFG); + +	if (ocelot_port->phy_mode != PHY_INTERFACE_MODE_INTERNAL) { +		struct phy *serdes = of_phy_get(portnp, NULL); + +		if (IS_ERR(serdes)) { +			err = PTR_ERR(serdes); +			dev_err_probe(dev, err, +				      "missing SerDes phys for port %d\n", +				      port); +			return err; +		} + +		err = phy_set_mode_ext(serdes, PHY_MODE_ETHERNET, +				       ocelot_port->phy_mode); +		of_phy_put(serdes); +		if (err) { +			dev_err(dev, "Could not SerDes mode on port %d: %pe\n", +				port, ERR_PTR(err)); +			return err; +		} +	} + +	return 0; +} +EXPORT_SYMBOL_GPL(ocelot_port_configure_serdes); +  void ocelot_phylink_mac_config(struct ocelot *ocelot, int port,  			       unsigned int link_an_mode,  			       const struct phylink_link_state *state) diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 590a2b2816ad..21a87a3fc556 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -1742,34 +1742,11 @@ static int ocelot_port_phylink_create(struct ocelot *ocelot, int port,  		return -EINVAL;  	} -	/* Ensure clock signals and speed are set on all QSGMII links */ -	if (phy_mode == PHY_INTERFACE_MODE_QSGMII) -		ocelot_port_rmwl(ocelot_port, 0, -				 DEV_CLOCK_CFG_MAC_TX_RST | -				 DEV_CLOCK_CFG_MAC_RX_RST, -				 DEV_CLOCK_CFG); -  	ocelot_port->phy_mode = phy_mode; -	if (phy_mode != PHY_INTERFACE_MODE_INTERNAL) { -		struct phy *serdes = of_phy_get(portnp, NULL); - -		if (IS_ERR(serdes)) { -			err = PTR_ERR(serdes); -			dev_err_probe(dev, err, -				      "missing SerDes phys for port %d\n", -				      port); -			return err; -		} - -		err = phy_set_mode_ext(serdes, PHY_MODE_ETHERNET, phy_mode); -		of_phy_put(serdes); -		if (err) { -			dev_err(dev, "Could not SerDes mode on port %d: %pe\n", -				port, ERR_PTR(err)); -			return err; -		} -	} +	err = ocelot_port_configure_serdes(ocelot, port, portnp); +	if (err) +		return err;  	priv = container_of(ocelot_port, struct ocelot_port_private, port); diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 87ade87d3540..d757b5e26d26 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -644,6 +644,7 @@ enum ocelot_tag_prefix {  };  struct ocelot; +struct device_node;  struct ocelot_ops {  	struct net_device *(*port_to_netdev)(struct ocelot *ocelot, int port); @@ -1111,6 +1112,9 @@ int ocelot_sb_occ_tc_port_bind_get(struct ocelot *ocelot, int port,  				   enum devlink_sb_pool_type pool_type,  				   u32 *p_cur, u32 *p_max); +int ocelot_port_configure_serdes(struct ocelot *ocelot, int port, +				 struct device_node *portnp); +  void ocelot_phylink_mac_config(struct ocelot *ocelot, int port,  			       unsigned int link_an_mode,  			       const struct phylink_link_state *state); | 
