Commit 4d776482 authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller
Browse files

net: dsa: Get information about stacked DSA protocol



It is possible to stack multiple DSA switches in a way that they are not
part of the tree (disjoint) but the DSA master of a switch is a DSA
slave of another. When that happens switch drivers may have to know this
is the case so as to determine whether their tagging protocol has a
remove chance of working.

This is useful for specific switch drivers such as b53 where devices
have been known to be stacked in the wild without the Broadcom tag
protocol supporting that feature. This allows b53 to continue supporting
those devices by forcing the disabling of Broadcom tags on the outermost
switches if necessary.

The get_tag_protocol() function is therefore updated to gain an
additional enum dsa_tag_protocol argument which denotes the current
tagging protocol used by the DSA master we are attached to, else
DSA_TAG_PROTO_NONE for the top of the dsa_switch_tree.

Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8d2ff126
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -573,9 +573,8 @@ EXPORT_SYMBOL(b53_disable_port);

void b53_brcm_hdr_setup(struct dsa_switch *ds, int port)
{
	bool tag_en = !(ds->ops->get_tag_protocol(ds, port) ==
			 DSA_TAG_PROTO_NONE);
	struct b53_device *dev = ds->priv;
	bool tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE);
	u8 hdr_ctl, val;
	u16 reg;

@@ -1876,7 +1875,8 @@ static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port)
	return ret;
}

enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port)
enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
					   enum dsa_tag_protocol mprot)
{
	struct b53_device *dev = ds->priv;

@@ -1886,16 +1886,22 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port)
	 * misses on multicast addresses (TBD).
	 */
	if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) ||
	    !b53_can_enable_brcm_tags(ds, port))
		return DSA_TAG_PROTO_NONE;
	    !b53_can_enable_brcm_tags(ds, port)) {
		dev->tag_protocol = DSA_TAG_PROTO_NONE;
		goto out;
	}

	/* Broadcom BCM58xx chips have a flow accelerator on Port 8
	 * which requires us to use the prepended Broadcom tag type
	 */
	if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT)
		return DSA_TAG_PROTO_BRCM_PREPEND;
	if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) {
		dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND;
		goto out;
	}

	return DSA_TAG_PROTO_BRCM;
	dev->tag_protocol = DSA_TAG_PROTO_BRCM;
out:
	return dev->tag_protocol;
}
EXPORT_SYMBOL(b53_get_tag_protocol);

+3 −1
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ struct b53_device {
	u8 jumbo_size_reg;
	int reset_gpio;
	u8 num_arl_entries;
	enum dsa_tag_protocol tag_protocol;

	/* used ports mask */
	u16 enabled_ports;
@@ -359,7 +360,8 @@ int b53_mdb_del(struct dsa_switch *ds, int port,
		const struct switchdev_obj_port_mdb *mdb);
int b53_mirror_add(struct dsa_switch *ds, int port,
		   struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port);
enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
					   enum dsa_tag_protocol mprot);
void b53_mirror_del(struct dsa_switch *ds, int port,
		    struct dsa_mall_mirror_tc_entry *mirror);
int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
+2 −1
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ struct dsa_loop_priv {
static struct phy_device *phydevs[PHY_MAX_ADDR];

static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,
						   int port)
						   int port,
						   enum dsa_tag_protocol mp)
{
	dev_dbg(ds->dev, "%s: port: %d\n", __func__, port);

+2 −1
Original line number Diff line number Diff line
@@ -883,7 +883,8 @@ static int lan9303_check_device(struct lan9303 *chip)
/* ---------------------------- DSA -----------------------------------*/

static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds,
						      int port)
						      int port,
						      enum dsa_tag_protocol mp)
{
	return DSA_TAG_PROTO_LAN9303;
}
+2 −1
Original line number Diff line number Diff line
@@ -841,7 +841,8 @@ static int gswip_setup(struct dsa_switch *ds)
}

static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,
						    int port)
						    int port,
						    enum dsa_tag_protocol mp)
{
	return DSA_TAG_PROTO_GSWIP;
}
Loading