Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99717bdf authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'dsa-refactoring-set-1'



Andrew Lunn says:

====================
DSA refactoring: set 1

There has been a long running effort to refractor DSA probing to make
the switches true linux devices. Here are a small collection of
patches moving in this direction. Most have been seen before.

We take a little step forward by passing the dsa device point to the
driver, thus allowing it to perform resource allocations using the
normal mechanisms. This device structure will later be replaced by the
devices own device structure.

Future patches will add a true driver probe function, so we rename the
current probe function, cleaning up the namespace.

phys_port_mask continually confuses me, thinking it is about PHYs. But
it is actually about ports enabled to the outside world. So rename it to
enabled_port_mask.

Lots more patches yet to follow, this is just doing some ground work.

v2:
  enabled_port_mask instread of user_port_masks
  Added Tested-by's and Reviewed-by.
====================

Tested-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 71bbe25d c156913b
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -135,8 +135,17 @@ static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds)
	return BCM_SF2_STATS_SIZE;
}

static char *bcm_sf2_sw_probe(struct device *host_dev, int sw_addr)
static char *bcm_sf2_sw_drv_probe(struct device *dsa_dev,
				  struct device *host_dev,
				  int sw_addr, void **_priv)
{
	struct bcm_sf2_priv *priv;

	priv = devm_kzalloc(dsa_dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return NULL;
	*_priv = priv;

	return "Broadcom Starfighter 2";
}

@@ -151,7 +160,7 @@ static void bcm_sf2_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
	 * the same VLAN.
	 */
	for (i = 0; i < priv->hw_params.num_ports; i++) {
		if (!((1 << i) & ds->phys_port_mask))
		if (!((1 << i) & ds->enabled_port_mask))
			continue;

		reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(i));
@@ -1000,7 +1009,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
	/* Enable all valid ports and disable those unused */
	for (port = 0; port < priv->hw_params.num_ports; port++) {
		/* IMP port receives special treatment */
		if ((1 << port) & ds->phys_port_mask)
		if ((1 << port) & ds->enabled_port_mask)
			bcm_sf2_port_setup(ds, port, NULL);
		else if (dsa_is_cpu_port(ds, port))
			bcm_sf2_imp_setup(ds, port);
@@ -1013,11 +1022,12 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
	 * 7445D0, since 7445E0 disconnects the internal switch pseudo-PHY such
	 * that we can use the regular SWITCH_MDIO master controller instead.
	 *
	 * By default, DSA initializes ds->phys_mii_mask to ds->phys_port_mask
	 * to have a 1:1 mapping between Port address and PHY address in order
	 * to utilize the slave_mii_bus instance to read from Port PHYs. This is
	 * not what we want here, so we initialize phys_mii_mask 0 to always
	 * utilize the "master" MDIO bus backed by the "mdio-unimac" driver.
	 * By default, DSA initializes ds->phys_mii_mask to
	 * ds->enabled_port_mask to have a 1:1 mapping between Port address
	 * and PHY address in order to utilize the slave_mii_bus instance to
	 * read from Port PHYs. This is not what we want here, so we
	 * initialize phys_mii_mask 0 to always utilize the "master" MDIO
	 * bus backed by the "mdio-unimac" driver.
	 */
	if (of_machine_is_compatible("brcm,bcm7445d0"))
		ds->phys_mii_mask |= ((1 << BRCM_PSEUDO_PHY_ADDR) | (1 << 0));
@@ -1275,7 +1285,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
	 * bcm_sf2_sw_setup
	 */
	for (port = 0; port < DSA_MAX_PORTS; port++) {
		if ((1 << port) & ds->phys_port_mask ||
		if ((1 << port) & ds->enabled_port_mask ||
		    dsa_is_cpu_port(ds, port))
			bcm_sf2_port_disable(ds, port, NULL);
	}
@@ -1299,7 +1309,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
		bcm_sf2_gphy_enable_set(ds, true);

	for (port = 0; port < DSA_MAX_PORTS; port++) {
		if ((1 << port) & ds->phys_port_mask)
		if ((1 << port) & ds->enabled_port_mask)
			bcm_sf2_port_setup(ds, port, NULL);
		else if (dsa_is_cpu_port(ds, port))
			bcm_sf2_imp_setup(ds, port);
@@ -1362,8 +1372,7 @@ static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,

static struct dsa_switch_driver bcm_sf2_switch_driver = {
	.tag_protocol		= DSA_TAG_PROTO_BRCM,
	.priv_size		= sizeof(struct bcm_sf2_priv),
	.probe			= bcm_sf2_sw_probe,
	.probe			= bcm_sf2_sw_drv_probe,
	.setup			= bcm_sf2_sw_setup,
	.set_addr		= bcm_sf2_sw_set_addr,
	.get_phy_flags		= bcm_sf2_sw_get_phy_flags,
+29 −18
Original line number Diff line number Diff line
@@ -19,12 +19,9 @@

static int reg_read(struct dsa_switch *ds, int addr, int reg)
{
	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
	struct mv88e6060_priv *priv = ds_to_priv(ds);

	if (bus == NULL)
		return -EINVAL;

	return mdiobus_read_nested(bus, ds->pd->sw_addr + addr, reg);
	return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg);
}

#define REG_READ(addr, reg)					\
@@ -40,12 +37,9 @@ static int reg_read(struct dsa_switch *ds, int addr, int reg)

static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
{
	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);

	if (bus == NULL)
		return -EINVAL;
	struct mv88e6060_priv *priv = ds_to_priv(ds);

	return mdiobus_write_nested(bus, ds->pd->sw_addr + addr, reg, val);
	return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
}

#define REG_WRITE(addr, reg, val)				\
@@ -57,14 +51,10 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
			return __ret;				\
	})

static char *mv88e6060_probe(struct device *host_dev, int sw_addr)
static char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)
{
	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
	int ret;

	if (bus == NULL)
		return NULL;

	ret = mdiobus_read(bus, sw_addr + REG_PORT(0), PORT_SWITCH_ID);
	if (ret >= 0) {
		if (ret == PORT_SWITCH_ID_6060)
@@ -79,6 +69,27 @@ static char *mv88e6060_probe(struct device *host_dev, int sw_addr)
	return NULL;
}

static char *mv88e6060_drv_probe(struct device *dsa_dev,
				 struct device *host_dev,
				 int sw_addr, void **_priv)
{
	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
	struct mv88e6060_priv *priv;
	char *name;

	name = mv88e6060_get_name(bus, sw_addr);
	if (name) {
		priv = devm_kzalloc(dsa_dev, sizeof(*priv), GFP_KERNEL);
		if (!priv)
			return NULL;
		*_priv = priv;
		priv->bus = bus;
		priv->sw_addr = sw_addr;
	}

	return name;
}

static int mv88e6060_switch_reset(struct dsa_switch *ds)
{
	int i;
@@ -159,7 +170,7 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
	REG_WRITE(addr, PORT_VLAN_MAP,
		  ((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) |
		   (dsa_is_cpu_port(ds, p) ?
			ds->phys_port_mask :
			ds->enabled_port_mask :
			BIT(ds->dst->cpu_port)));

	/* Port Association Vector: when learning source addresses
@@ -174,8 +185,8 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)

static int mv88e6060_setup(struct dsa_switch *ds)
{
	int i;
	int ret;
	int i;

	ret = mv88e6060_switch_reset(ds);
	if (ret < 0)
@@ -238,7 +249,7 @@ mv88e6060_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)

static struct dsa_switch_driver mv88e6060_switch_driver = {
	.tag_protocol	= DSA_TAG_PROTO_TRAILER,
	.probe		= mv88e6060_probe,
	.probe		= mv88e6060_drv_probe,
	.setup		= mv88e6060_setup,
	.set_addr	= mv88e6060_set_addr,
	.phy_read	= mv88e6060_phy_read,
+11 −0
Original line number Diff line number Diff line
@@ -108,4 +108,15 @@
#define GLOBAL_ATU_MAC_23	0x0e
#define GLOBAL_ATU_MAC_45	0x0f

struct mv88e6060_priv {
	/* MDIO bus and address on bus to use. When in single chip
	 * mode, address is 0, and the switch uses multiple addresses
	 * on the bus.  When in multi-chip mode, the switch uses a
	 * single address which contains two registers used for
	 * indirect access to more registers.
	 */
	struct mii_bus *bus;
	int sw_addr;
};

#endif
+9 −5
Original line number Diff line number Diff line
@@ -29,9 +29,12 @@ static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
	{ PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
};

static char *mv88e6123_probe(struct device *host_dev, int sw_addr)
static char *mv88e6123_drv_probe(struct device *dsa_dev,
				 struct device *host_dev,
				 int sw_addr, void **priv)
{
	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table,
	return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
				   mv88e6123_table,
				   ARRAY_SIZE(mv88e6123_table));
}

@@ -73,6 +76,8 @@ static int mv88e6123_setup(struct dsa_switch *ds)
	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
	int ret;

	ps->ds = ds;

	ret = mv88e6xxx_setup_common(ds);
	if (ret < 0)
		return ret;
@@ -102,8 +107,7 @@ static int mv88e6123_setup(struct dsa_switch *ds)

struct dsa_switch_driver mv88e6123_switch_driver = {
	.tag_protocol		= DSA_TAG_PROTO_EDSA,
	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
	.probe			= mv88e6123_probe,
	.probe			= mv88e6123_drv_probe,
	.setup			= mv88e6123_setup,
	.set_addr		= mv88e6xxx_set_addr_indirect,
	.phy_read		= mv88e6xxx_phy_read,
+9 −5
Original line number Diff line number Diff line
@@ -25,9 +25,12 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
	{ PORT_SWITCH_ID_6185, "Marvell 88E6185" },
};

static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
static char *mv88e6131_drv_probe(struct device *dsa_dev,
				 struct device *host_dev,
				 int sw_addr, void **priv)
{
	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table,
	return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
				   mv88e6131_table,
				   ARRAY_SIZE(mv88e6131_table));
}

@@ -91,6 +94,8 @@ static int mv88e6131_setup(struct dsa_switch *ds)
	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
	int ret;

	ps->ds = ds;

	ret = mv88e6xxx_setup_common(ds);
	if (ret < 0)
		return ret;
@@ -159,8 +164,7 @@ mv88e6131_phy_write(struct dsa_switch *ds,

struct dsa_switch_driver mv88e6131_switch_driver = {
	.tag_protocol		= DSA_TAG_PROTO_DSA,
	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
	.probe			= mv88e6131_probe,
	.probe			= mv88e6131_drv_probe,
	.setup			= mv88e6131_setup,
	.set_addr		= mv88e6xxx_set_addr_direct,
	.phy_read		= mv88e6131_phy_read,
Loading