Commit 4a8e4640 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-dsa-convert-two-drivers-to-phylink_generic_validate'

Russell King says:

====================
net: dsa: convert two drivers to phylink_generic_validate()

Patches 1 to 3 update core DSA code to allow drivers to be converted,
and patches 4 and 5 convert hellcreek and lantiq to use this (both of
which received reviewed-by from their maintainers.) As the rest have
yet to be reviewed by their maintainers, they are not included here.

Patch 1 had a request to change the formatting of it; I have not done
so as I believe a patch should do one change and one change only -
reformatting it is a separate change that should be in its own patch.
However, as patch 2 gets rid of the reason for reformatting it, it
would be pointless, and pure noise to include such an intermediary
patch.

Instead, I have swapped the order of patches 2 and 3 from the RFC
series.
====================

Link: https://lore.kernel.org/r/YaYiiU9nvmVugqnJ@shell.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 8057cbb8 a2279b08
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -1384,14 +1384,19 @@ static void hellcreek_teardown(struct dsa_switch *ds)
	dsa_devlink_resources_unregister(ds);
}

static void hellcreek_phylink_validate(struct dsa_switch *ds, int port,
				       unsigned long *supported,
				       struct phylink_link_state *state)
static void hellcreek_phylink_get_caps(struct dsa_switch *ds, int port,
				       struct phylink_config *config)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
	struct hellcreek *hellcreek = ds->priv;

	dev_dbg(hellcreek->dev, "Phylink validate for port %d\n", port);
	__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
	__set_bit(PHY_INTERFACE_MODE_RGMII, config->supported_interfaces);

	/* Include GMII - the hardware does not support this interface
	 * mode, but it's the default interface mode for phylib, so we
	 * need it for compatibility with existing DT.
	 */
	__set_bit(PHY_INTERFACE_MODE_GMII, config->supported_interfaces);

	/* The MAC settings are a hardware configuration option and cannot be
	 * changed at run time or by strapping. Therefore the attached PHYs
@@ -1399,12 +1404,9 @@ static void hellcreek_phylink_validate(struct dsa_switch *ds, int port,
	 * by the hardware.
	 */
	if (hellcreek->pdata->is_100_mbits)
		phylink_set(mask, 100baseT_Full);
		config->mac_capabilities = MAC_100FD;
	else
		phylink_set(mask, 1000baseT_Full);

	linkmode_and(supported, supported, mask);
	linkmode_and(state->advertising, state->advertising, mask);
		config->mac_capabilities = MAC_1000FD;
}

static int
@@ -1755,7 +1757,7 @@ static const struct dsa_switch_ops hellcreek_ds_ops = {
	.get_strings	       = hellcreek_get_strings,
	.get_tag_protocol      = hellcreek_get_tag_protocol,
	.get_ts_info	       = hellcreek_get_ts_info,
	.phylink_validate      = hellcreek_phylink_validate,
	.phylink_get_caps      = hellcreek_phylink_get_caps,
	.port_bridge_flags     = hellcreek_bridge_flags,
	.port_bridge_join      = hellcreek_port_bridge_join,
	.port_bridge_leave     = hellcreek_port_bridge_leave,
+38 −82
Original line number Diff line number Diff line
@@ -1438,114 +1438,70 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port,
	return 0;
}

static void gswip_phylink_set_capab(unsigned long *supported,
				    struct phylink_link_state *state)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };

	/* Allow all the expected bits */
	phylink_set(mask, Autoneg);
	phylink_set_port_modes(mask);
	phylink_set(mask, Pause);
	phylink_set(mask, Asym_Pause);

	/* With the exclusion of MII, Reverse MII and Reduced MII, we
	 * support Gigabit, including Half duplex
	 */
	if (state->interface != PHY_INTERFACE_MODE_MII &&
	    state->interface != PHY_INTERFACE_MODE_REVMII &&
	    state->interface != PHY_INTERFACE_MODE_RMII) {
		phylink_set(mask, 1000baseT_Full);
		phylink_set(mask, 1000baseT_Half);
	}

	phylink_set(mask, 10baseT_Half);
	phylink_set(mask, 10baseT_Full);
	phylink_set(mask, 100baseT_Half);
	phylink_set(mask, 100baseT_Full);

	linkmode_and(supported, supported, mask);
	linkmode_and(state->advertising, state->advertising, mask);
}

static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
					  unsigned long *supported,
					  struct phylink_link_state *state)
static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
					  struct phylink_config *config)
{
	switch (port) {
	case 0:
	case 1:
		if (!phy_interface_mode_is_rgmii(state->interface) &&
		    state->interface != PHY_INTERFACE_MODE_MII &&
		    state->interface != PHY_INTERFACE_MODE_REVMII &&
		    state->interface != PHY_INTERFACE_MODE_RMII)
			goto unsupported;
		phy_interface_set_rgmii(config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_MII,
			  config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_REVMII,
			  config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_RMII,
			  config->supported_interfaces);
		break;

	case 2:
	case 3:
	case 4:
		if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
			goto unsupported;
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		break;

	case 5:
		if (!phy_interface_mode_is_rgmii(state->interface) &&
		    state->interface != PHY_INTERFACE_MODE_INTERNAL)
			goto unsupported;
		phy_interface_set_rgmii(config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		break;
	default:
		linkmode_zero(supported);
		dev_err(ds->dev, "Unsupported port: %i\n", port);
		return;
	}

	gswip_phylink_set_capab(supported, state);

	return;

unsupported:
	linkmode_zero(supported);
	dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
		phy_modes(state->interface), port);
	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
		MAC_10 | MAC_100 | MAC_1000;
}

static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port,
					  unsigned long *supported,
					  struct phylink_link_state *state)
static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
					  struct phylink_config *config)
{
	switch (port) {
	case 0:
		if (!phy_interface_mode_is_rgmii(state->interface) &&
		    state->interface != PHY_INTERFACE_MODE_GMII &&
		    state->interface != PHY_INTERFACE_MODE_RMII)
			goto unsupported;
		phy_interface_set_rgmii(config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_GMII,
			  config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_RMII,
			  config->supported_interfaces);
		break;

	case 1:
	case 2:
	case 3:
	case 4:
		if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
			goto unsupported;
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		break;

	case 5:
		if (!phy_interface_mode_is_rgmii(state->interface) &&
		    state->interface != PHY_INTERFACE_MODE_INTERNAL &&
		    state->interface != PHY_INTERFACE_MODE_RMII)
			goto unsupported;
		phy_interface_set_rgmii(config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_RMII,
			  config->supported_interfaces);
		break;
	default:
		linkmode_zero(supported);
		dev_err(ds->dev, "Unsupported port: %i\n", port);
		return;
	}

	gswip_phylink_set_capab(supported, state);

	return;

unsupported:
	linkmode_zero(supported);
	dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
		phy_modes(state->interface), port);
	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
		MAC_10 | MAC_100 | MAC_1000;
}

static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link)
@@ -1827,7 +1783,7 @@ static const struct dsa_switch_ops gswip_xrx200_switch_ops = {
	.port_fdb_add		= gswip_port_fdb_add,
	.port_fdb_del		= gswip_port_fdb_del,
	.port_fdb_dump		= gswip_port_fdb_dump,
	.phylink_validate	= gswip_xrx200_phylink_validate,
	.phylink_get_caps	= gswip_xrx200_phylink_get_caps,
	.phylink_mac_config	= gswip_phylink_mac_config,
	.phylink_mac_link_down	= gswip_phylink_mac_link_down,
	.phylink_mac_link_up	= gswip_phylink_mac_link_up,
@@ -1851,7 +1807,7 @@ static const struct dsa_switch_ops gswip_xrx300_switch_ops = {
	.port_fdb_add		= gswip_port_fdb_add,
	.port_fdb_del		= gswip_port_fdb_del,
	.port_fdb_dump		= gswip_port_fdb_dump,
	.phylink_validate	= gswip_xrx300_phylink_validate,
	.phylink_get_caps	= gswip_xrx300_phylink_get_caps,
	.phylink_mac_config	= gswip_phylink_mac_config,
	.phylink_mac_link_down	= gswip_phylink_mac_link_down,
	.phylink_mac_link_up	= gswip_phylink_mac_link_up,
+2 −2
Original line number Diff line number Diff line
@@ -645,8 +645,8 @@ struct dsa_switch_ops {
	/*
	 * PHYLINK integration
	 */
	void	(*phylink_get_interfaces)(struct dsa_switch *ds, int port,
					  unsigned long *supported_interfaces);
	void	(*phylink_get_caps)(struct dsa_switch *ds, int port,
				    struct phylink_config *config);
	void	(*phylink_validate)(struct dsa_switch *ds, int port,
				    unsigned long *supported,
				    struct phylink_link_state *state);
+1 −1
Original line number Diff line number Diff line
@@ -258,13 +258,13 @@ int dsa_port_mrp_add_ring_role(const struct dsa_port *dp,
			       const struct switchdev_obj_ring_role_mrp *mrp);
int dsa_port_mrp_del_ring_role(const struct dsa_port *dp,
			       const struct switchdev_obj_ring_role_mrp *mrp);
int dsa_port_phylink_create(struct dsa_port *dp);
int dsa_port_link_register_of(struct dsa_port *dp);
void dsa_port_link_unregister_of(struct dsa_port *dp);
int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr);
int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast);
void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast);
extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;

static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
						 const struct net_device *dev)
+31 −17
Original line number Diff line number Diff line
@@ -981,8 +981,11 @@ static void dsa_port_phylink_validate(struct phylink_config *config,
	struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
	struct dsa_switch *ds = dp->ds;

	if (!ds->ops->phylink_validate)
	if (!ds->ops->phylink_validate) {
		if (config->mac_capabilities)
			phylink_generic_validate(config, supported, state);
		return;
	}

	ds->ops->phylink_validate(ds, dp->index, supported, state);
}
@@ -1072,7 +1075,7 @@ static void dsa_port_phylink_mac_link_up(struct phylink_config *config,
				     speed, duplex, tx_pause, rx_pause);
}

const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
	.validate = dsa_port_phylink_validate,
	.mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
	.mac_config = dsa_port_phylink_mac_config,
@@ -1081,6 +1084,29 @@ const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
	.mac_link_up = dsa_port_phylink_mac_link_up,
};

int dsa_port_phylink_create(struct dsa_port *dp)
{
	struct dsa_switch *ds = dp->ds;
	phy_interface_t mode;
	int err;

	err = of_get_phy_mode(dp->dn, &mode);
	if (err)
		mode = PHY_INTERFACE_MODE_NA;

	if (ds->ops->phylink_get_caps)
		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);

	dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
				mode, &dsa_port_phylink_mac_ops);
	if (IS_ERR(dp->pl)) {
		pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
		return PTR_ERR(dp->pl);
	}

	return 0;
}

static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
{
	struct dsa_switch *ds = dp->ds;
@@ -1157,27 +1183,15 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
{
	struct dsa_switch *ds = dp->ds;
	struct device_node *port_dn = dp->dn;
	phy_interface_t mode;
	int err;

	err = of_get_phy_mode(port_dn, &mode);
	if (err)
		mode = PHY_INTERFACE_MODE_NA;

	dp->pl_config.dev = ds->dev;
	dp->pl_config.type = PHYLINK_DEV;
	dp->pl_config.pcs_poll = ds->pcs_poll;

	if (ds->ops->phylink_get_interfaces)
		ds->ops->phylink_get_interfaces(ds, dp->index,
					dp->pl_config.supported_interfaces);

	dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
				mode, &dsa_port_phylink_mac_ops);
	if (IS_ERR(dp->pl)) {
		pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
		return PTR_ERR(dp->pl);
	}
	err = dsa_port_phylink_create(dp);
	if (err)
		return err;

	err = phylink_of_phy_connect(dp->pl, port_dn, 0);
	if (err && err != -ENODEV) {
Loading