Commit 7d63b21d authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'remove-phylink_validate-from-felix-dsa-driver'

Vladimir Oltean says:

====================
Remove phylink_validate() from Felix DSA driver

The Felix DSA driver still uses its own phylink_validate() procedure
rather than the (relatively newly introduced) phylink_generic_validate()
because the latter did not cater for the case where a PHY provides rate
matching between the Ethernet cable side speed and the SERDES side
speed (and does not advertise other speeds except for the SERDES speed).

This changed with Sean Anderson's generic support for rate matching PHYs
in phylib and phylink:
https://patchwork.kernel.org/project/netdevbpf/cover/20220920221235.1487501-1-sean.anderson@seco.com/

Building upon that support, this patch set makes Linux understand that
the PHYs used in combination with the Felix DSA driver (SCH-30841 riser
card with AQR412 PHY, used with SERDES protocol 0x7777 - 4x2500base-x,
plugged into LS1028A-QDS) do support PAUSE rate matching. This requires
Aquantia PHY driver support for new PHY IDs.

To activate the rate matching support in phylink, config->mac_capabilities
must be populated. Coincidentally, this also opts the Felix driver into
the generic phylink validation.

Next, code that is no longer necessary is eliminated. This includes the
Felix driver validation procedures for VSC9959 and VSC9953, the
workaround in the Ocelot switch library to leave RX flow control always
enabled, as well as DSA plumbing necessary for a custom phylink
validation procedure to be propagated to the hardware driver level.

Many thanks go to Sean Anderson for providing generic support for rate
matching.
====================

Link: https://lore.kernel.org/r/20221114170730.2189282-1-vladimir.oltean@nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b87584cb 53d04b98
Loading
Loading
Loading
Loading
+4 −12
Original line number Diff line number Diff line
@@ -1048,21 +1048,14 @@ static void felix_phylink_get_caps(struct dsa_switch *ds, int port,
	 */
	config->legacy_pre_march2020 = false;

	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
				   MAC_10 | MAC_100 | MAC_1000FD |
				   MAC_2500FD;

	__set_bit(ocelot->ports[port]->phy_mode,
		  config->supported_interfaces);
}

static void felix_phylink_validate(struct dsa_switch *ds, int port,
				   unsigned long *supported,
				   struct phylink_link_state *state)
{
	struct ocelot *ocelot = ds->priv;
	struct felix *felix = ocelot_to_felix(ocelot);

	if (felix->info->phylink_validate)
		felix->info->phylink_validate(ocelot, port, supported, state);
}

static struct phylink_pcs *felix_phylink_mac_select_pcs(struct dsa_switch *ds,
							int port,
							phy_interface_t iface)
@@ -2050,7 +2043,6 @@ const struct dsa_switch_ops felix_switch_ops = {
	.get_sset_count			= felix_get_sset_count,
	.get_ts_info			= felix_get_ts_info,
	.phylink_get_caps		= felix_phylink_get_caps,
	.phylink_validate		= felix_phylink_validate,
	.phylink_mac_select_pcs		= felix_phylink_mac_select_pcs,
	.phylink_mac_link_down		= felix_phylink_mac_link_down,
	.phylink_mac_link_up		= felix_phylink_mac_link_up,
+0 −3
Original line number Diff line number Diff line
@@ -52,9 +52,6 @@ struct felix_info {

	int	(*mdio_bus_alloc)(struct ocelot *ocelot);
	void	(*mdio_bus_free)(struct ocelot *ocelot);
	void	(*phylink_validate)(struct ocelot *ocelot, int port,
				    unsigned long *supported,
				    struct phylink_link_state *state);
	int	(*port_setup_tc)(struct dsa_switch *ds, int port,
				 enum tc_setup_type type, void *type_data);
	void	(*tas_guard_bands_update)(struct ocelot *ocelot, int port);
+0 −30
Original line number Diff line number Diff line
@@ -885,35 +885,6 @@ static int vsc9959_reset(struct ocelot *ocelot)
	return 0;
}

static void vsc9959_phylink_validate(struct ocelot *ocelot, int port,
				     unsigned long *supported,
				     struct phylink_link_state *state)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };

	phylink_set_port_modes(mask);
	phylink_set(mask, Autoneg);
	phylink_set(mask, Pause);
	phylink_set(mask, Asym_Pause);
	phylink_set(mask, 10baseT_Half);
	phylink_set(mask, 10baseT_Full);
	phylink_set(mask, 100baseT_Half);
	phylink_set(mask, 100baseT_Full);
	phylink_set(mask, 1000baseT_Half);
	phylink_set(mask, 1000baseT_Full);
	phylink_set(mask, 1000baseX_Full);

	if (state->interface == PHY_INTERFACE_MODE_INTERNAL ||
	    state->interface == PHY_INTERFACE_MODE_2500BASEX ||
	    state->interface == PHY_INTERFACE_MODE_USXGMII) {
		phylink_set(mask, 2500baseT_Full);
		phylink_set(mask, 2500baseX_Full);
	}

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

/* Watermark encode
 * Bit 8:   Unit; 0:1, 1:16
 * Bit 7-0: Value to be multiplied with unit
@@ -2588,7 +2559,6 @@ static const struct felix_info felix_info_vsc9959 = {
	.ptp_caps		= &vsc9959_ptp_caps,
	.mdio_bus_alloc		= vsc9959_mdio_bus_alloc,
	.mdio_bus_free		= vsc9959_mdio_bus_free,
	.phylink_validate	= vsc9959_phylink_validate,
	.port_modes		= vsc9959_port_modes,
	.port_setup_tc		= vsc9959_port_setup_tc,
	.port_sched_speed_set	= vsc9959_sched_speed_set,
+0 −27
Original line number Diff line number Diff line
@@ -840,32 +840,6 @@ static int vsc9953_reset(struct ocelot *ocelot)
	return 0;
}

static void vsc9953_phylink_validate(struct ocelot *ocelot, int port,
				     unsigned long *supported,
				     struct phylink_link_state *state)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };

	phylink_set_port_modes(mask);
	phylink_set(mask, Autoneg);
	phylink_set(mask, Pause);
	phylink_set(mask, Asym_Pause);
	phylink_set(mask, 10baseT_Full);
	phylink_set(mask, 10baseT_Half);
	phylink_set(mask, 100baseT_Full);
	phylink_set(mask, 100baseT_Half);
	phylink_set(mask, 1000baseT_Full);
	phylink_set(mask, 1000baseX_Full);

	if (state->interface == PHY_INTERFACE_MODE_INTERNAL) {
		phylink_set(mask, 2500baseT_Full);
		phylink_set(mask, 2500baseX_Full);
	}

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

/* Watermark encode
 * Bit 9:   Unit; 0:1, 1:16
 * Bit 8-0: Value to be multiplied with unit
@@ -1007,7 +981,6 @@ static const struct felix_info seville_info_vsc9953 = {
	.num_tx_queues		= OCELOT_NUM_TC,
	.mdio_bus_alloc		= vsc9953_mdio_bus_alloc,
	.mdio_bus_free		= vsc9953_mdio_bus_free,
	.phylink_validate	= vsc9953_phylink_validate,
	.port_modes		= vsc9953_port_modes,
};

+2 −4
Original line number Diff line number Diff line
@@ -872,9 +872,7 @@ void ocelot_phylink_mac_link_up(struct ocelot *ocelot, int port,
		return;
	}

	/* Handle RX pause in all cases, with 2500base-X this is used for rate
	 * adaptation.
	 */
	if (rx_pause)
		mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA;

	if (tx_pause)
Loading