Commit acf242fc authored by Colin Foster's avatar Colin Foster Committed by David S. Miller
Browse files

net: dsa: felix: remove prevalidate_phy_mode interface



All users of the felix driver were creating their own prevalidate_phy_mode
function. The same logic can be performed in a more general way by using a
simple array of bit fields.

Signed-off-by: default avatarColin Foster <colin.foster@in-advantage.com>
Suggested-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 688a5efe
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -938,11 +938,28 @@ static int felix_get_ts_info(struct dsa_switch *ds, int port,
	return ocelot_get_ts_info(ocelot, port, info);
}

static const u32 felix_phy_match_table[PHY_INTERFACE_MODE_MAX] = {
	[PHY_INTERFACE_MODE_INTERNAL] = OCELOT_PORT_MODE_INTERNAL,
	[PHY_INTERFACE_MODE_SGMII] = OCELOT_PORT_MODE_SGMII,
	[PHY_INTERFACE_MODE_QSGMII] = OCELOT_PORT_MODE_QSGMII,
	[PHY_INTERFACE_MODE_USXGMII] = OCELOT_PORT_MODE_USXGMII,
	[PHY_INTERFACE_MODE_2500BASEX] = OCELOT_PORT_MODE_2500BASEX,
};

static int felix_validate_phy_mode(struct felix *felix, int port,
				   phy_interface_t phy_mode)
{
	u32 modes = felix->info->port_modes[port];

	if (felix_phy_match_table[phy_mode] & modes)
		return 0;
	return -EOPNOTSUPP;
}

static int felix_parse_ports_node(struct felix *felix,
				  struct device_node *ports_node,
				  phy_interface_t *port_phy_modes)
{
	struct ocelot *ocelot = &felix->ocelot;
	struct device *dev = felix->ocelot.dev;
	struct device_node *child;

@@ -969,7 +986,7 @@ static int felix_parse_ports_node(struct felix *felix,
			return -ENODEV;
		}

		err = felix->info->prevalidate_phy_mode(ocelot, port, phy_mode);
		err = felix_validate_phy_mode(felix, port, phy_mode);
		if (err < 0) {
			dev_err(dev, "Unsupported PHY mode %s on port %d\n",
				phy_modes(phy_mode), port);
+7 −2
Original line number Diff line number Diff line
@@ -7,6 +7,12 @@
#define ocelot_to_felix(o)		container_of((o), struct felix, ocelot)
#define FELIX_MAC_QUIRKS		OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION

#define OCELOT_PORT_MODE_INTERNAL	BIT(0)
#define OCELOT_PORT_MODE_SGMII		BIT(1)
#define OCELOT_PORT_MODE_QSGMII		BIT(2)
#define OCELOT_PORT_MODE_2500BASEX	BIT(3)
#define OCELOT_PORT_MODE_USXGMII	BIT(4)

/* Platform-specific information */
struct felix_info {
	const struct resource		*target_io_res;
@@ -15,6 +21,7 @@ struct felix_info {
	const struct reg_field		*regfields;
	const u32 *const		*map;
	const struct ocelot_ops		*ops;
	const u32			*port_modes;
	int				num_mact_rows;
	const struct ocelot_stat_layout	*stats_layout;
	unsigned int			num_stats;
@@ -44,8 +51,6 @@ struct felix_info {
	void	(*phylink_validate)(struct ocelot *ocelot, int port,
				    unsigned long *supported,
				    struct phylink_link_state *state);
	int	(*prevalidate_phy_mode)(struct ocelot *ocelot, int port,
					phy_interface_t phy_mode);
	int	(*port_setup_tc)(struct dsa_switch *ds, int port,
				 enum tc_setup_type type, void *type_data);
	void	(*port_sched_speed_set)(struct ocelot *ocelot, int port,
+17 −23
Original line number Diff line number Diff line
@@ -18,12 +18,27 @@
#include <linux/pci.h>
#include "felix.h"

#define VSC9959_NUM_PORTS		6

#define VSC9959_TAS_GCL_ENTRY_MAX	63
#define VSC9959_VCAP_POLICER_BASE	63
#define VSC9959_VCAP_POLICER_MAX	383
#define VSC9959_SWITCH_PCI_BAR		4
#define VSC9959_IMDIO_PCI_BAR		0

#define VSC9959_PORT_MODE_SERDES	(OCELOT_PORT_MODE_SGMII | \
					 OCELOT_PORT_MODE_QSGMII | \
					 OCELOT_PORT_MODE_2500BASEX | \
					 OCELOT_PORT_MODE_USXGMII)

static const u32 vsc9959_port_modes[VSC9959_NUM_PORTS] = {
	VSC9959_PORT_MODE_SERDES,
	VSC9959_PORT_MODE_SERDES,
	VSC9959_PORT_MODE_SERDES,
	VSC9959_PORT_MODE_SERDES,
	OCELOT_PORT_MODE_INTERNAL,
};

static const u32 vsc9959_ana_regmap[] = {
	REG(ANA_ADVLEARN,			0x0089a0),
	REG(ANA_VLANMASK,			0x0089a4),
@@ -968,27 +983,6 @@ static void vsc9959_phylink_validate(struct ocelot *ocelot, int port,
	linkmode_and(state->advertising, state->advertising, mask);
}

static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
					phy_interface_t phy_mode)
{
	switch (phy_mode) {
	case PHY_INTERFACE_MODE_INTERNAL:
		if (port != 4 && port != 5)
			return -ENOTSUPP;
		return 0;
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
	case PHY_INTERFACE_MODE_USXGMII:
	case PHY_INTERFACE_MODE_2500BASEX:
		/* Not supported on internal to-CPU ports */
		if (port == 4 || port == 5)
			return -ENOTSUPP;
		return 0;
	default:
		return -ENOTSUPP;
	}
}

/* Watermark encode
 * Bit 8:   Unit; 0:1, 1:16
 * Bit 7-0: Value to be multiplied with unit
@@ -2224,14 +2218,14 @@ static const struct felix_info felix_info_vsc9959 = {
	.vcap_pol_base2		= 0,
	.vcap_pol_max2		= 0,
	.num_mact_rows		= 2048,
	.num_ports		= 6,
	.num_ports		= VSC9959_NUM_PORTS,
	.num_tx_queues		= OCELOT_NUM_TC,
	.quirk_no_xtr_irq	= true,
	.ptp_caps		= &vsc9959_ptp_caps,
	.mdio_bus_alloc		= vsc9959_mdio_bus_alloc,
	.mdio_bus_free		= vsc9959_mdio_bus_free,
	.phylink_validate	= vsc9959_phylink_validate,
	.prevalidate_phy_mode	= vsc9959_prevalidate_phy_mode,
	.port_modes		= vsc9959_port_modes,
	.port_setup_tc		= vsc9959_port_setup_tc,
	.port_sched_speed_set	= vsc9959_sched_speed_set,
	.init_regmap		= ocelot_regmap_init,
+20 −21
Original line number Diff line number Diff line
@@ -14,11 +14,29 @@
#include <linux/iopoll.h>
#include "felix.h"

#define VSC9953_NUM_PORTS			10

#define VSC9953_VCAP_POLICER_BASE		11
#define VSC9953_VCAP_POLICER_MAX		31
#define VSC9953_VCAP_POLICER_BASE2		120
#define VSC9953_VCAP_POLICER_MAX2		161

#define VSC9953_PORT_MODE_SERDES		(OCELOT_PORT_MODE_SGMII | \
						 OCELOT_PORT_MODE_QSGMII)

static const u32 vsc9953_port_modes[VSC9953_NUM_PORTS] = {
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	VSC9953_PORT_MODE_SERDES,
	OCELOT_PORT_MODE_INTERNAL,
	OCELOT_PORT_MODE_INTERNAL,
};

static const u32 vsc9953_ana_regmap[] = {
	REG(ANA_ADVLEARN,			0x00b500),
	REG(ANA_VLANMASK,			0x00b504),
@@ -938,25 +956,6 @@ static void vsc9953_phylink_validate(struct ocelot *ocelot, int port,
	linkmode_and(state->advertising, state->advertising, mask);
}

static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port,
					phy_interface_t phy_mode)
{
	switch (phy_mode) {
	case PHY_INTERFACE_MODE_INTERNAL:
		if (port != 8 && port != 9)
			return -ENOTSUPP;
		return 0;
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
		/* Not supported on internal to-CPU ports */
		if (port == 8 || port == 9)
			return -ENOTSUPP;
		return 0;
	default:
		return -ENOTSUPP;
	}
}

/* Watermark encode
 * Bit 9:   Unit; 0:1, 1:16
 * Bit 8-0: Value to be multiplied with unit
@@ -1094,12 +1093,12 @@ static const struct felix_info seville_info_vsc9953 = {
	.vcap_pol_base2		= VSC9953_VCAP_POLICER_BASE2,
	.vcap_pol_max2		= VSC9953_VCAP_POLICER_MAX2,
	.num_mact_rows		= 2048,
	.num_ports		= 10,
	.num_ports		= VSC9953_NUM_PORTS,
	.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,
	.prevalidate_phy_mode	= vsc9953_prevalidate_phy_mode,
	.port_modes		= vsc9953_port_modes,
	.init_regmap		= ocelot_regmap_init,
};