mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 13:34:30 +00:00
net: mscc: ocelot: expose serdes configuration function
During chip initialization, ports that use SGMII / QSGMII to interface to external phys need to be configured on the VSC7513 and VSC7514. Expose this configuration routine, so it can be used by DSA drivers. Signed-off-by: Colin Foster <colin.foster@in-advantage.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
69f7f89c0d
commit
dfca93ed51
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user