Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Florian Fainelli and committed by
David S. Miller
4d776482 8d2ff126

+78 -29
+14 -8
drivers/net/dsa/b53/b53_common.c
··· 573 573 574 574 void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) 575 575 { 576 - bool tag_en = !(ds->ops->get_tag_protocol(ds, port) == 577 - DSA_TAG_PROTO_NONE); 578 576 struct b53_device *dev = ds->priv; 577 + bool tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE); 579 578 u8 hdr_ctl, val; 580 579 u16 reg; 581 580 ··· 1875 1876 return ret; 1876 1877 } 1877 1878 1878 - enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port) 1879 + enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, 1880 + enum dsa_tag_protocol mprot) 1879 1881 { 1880 1882 struct b53_device *dev = ds->priv; 1881 1883 ··· 1886 1886 * misses on multicast addresses (TBD). 1887 1887 */ 1888 1888 if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) || 1889 - !b53_can_enable_brcm_tags(ds, port)) 1890 - return DSA_TAG_PROTO_NONE; 1889 + !b53_can_enable_brcm_tags(ds, port)) { 1890 + dev->tag_protocol = DSA_TAG_PROTO_NONE; 1891 + goto out; 1892 + } 1891 1893 1892 1894 /* Broadcom BCM58xx chips have a flow accelerator on Port 8 1893 1895 * which requires us to use the prepended Broadcom tag type 1894 1896 */ 1895 - if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) 1896 - return DSA_TAG_PROTO_BRCM_PREPEND; 1897 + if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) { 1898 + dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND; 1899 + goto out; 1900 + } 1897 1901 1898 - return DSA_TAG_PROTO_BRCM; 1902 + dev->tag_protocol = DSA_TAG_PROTO_BRCM; 1903 + out: 1904 + return dev->tag_protocol; 1899 1905 } 1900 1906 EXPORT_SYMBOL(b53_get_tag_protocol); 1901 1907
+3 -1
drivers/net/dsa/b53/b53_priv.h
··· 118 118 u8 jumbo_size_reg; 119 119 int reset_gpio; 120 120 u8 num_arl_entries; 121 + enum dsa_tag_protocol tag_protocol; 121 122 122 123 /* used ports mask */ 123 124 u16 enabled_ports; ··· 360 359 const struct switchdev_obj_port_mdb *mdb); 361 360 int b53_mirror_add(struct dsa_switch *ds, int port, 362 361 struct dsa_mall_mirror_tc_entry *mirror, bool ingress); 363 - enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port); 362 + enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, 363 + enum dsa_tag_protocol mprot); 364 364 void b53_mirror_del(struct dsa_switch *ds, int port, 365 365 struct dsa_mall_mirror_tc_entry *mirror); 366 366 int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
+2 -1
drivers/net/dsa/dsa_loop.c
··· 61 61 static struct phy_device *phydevs[PHY_MAX_ADDR]; 62 62 63 63 static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds, 64 - int port) 64 + int port, 65 + enum dsa_tag_protocol mp) 65 66 { 66 67 dev_dbg(ds->dev, "%s: port: %d\n", __func__, port); 67 68
+2 -1
drivers/net/dsa/lan9303-core.c
··· 883 883 /* ---------------------------- DSA -----------------------------------*/ 884 884 885 885 static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds, 886 - int port) 886 + int port, 887 + enum dsa_tag_protocol mp) 887 888 { 888 889 return DSA_TAG_PROTO_LAN9303; 889 890 }
+2 -1
drivers/net/dsa/lantiq_gswip.c
··· 841 841 } 842 842 843 843 static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds, 844 - int port) 844 + int port, 845 + enum dsa_tag_protocol mp) 845 846 { 846 847 return DSA_TAG_PROTO_GSWIP; 847 848 }
+2 -1
drivers/net/dsa/microchip/ksz8795.c
··· 645 645 } 646 646 647 647 static enum dsa_tag_protocol ksz8795_get_tag_protocol(struct dsa_switch *ds, 648 - int port) 648 + int port, 649 + enum dsa_tag_protocol mp) 649 650 { 650 651 return DSA_TAG_PROTO_KSZ8795; 651 652 }
+2 -1
drivers/net/dsa/microchip/ksz9477.c
··· 295 295 } 296 296 297 297 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, 298 - int port) 298 + int port, 299 + enum dsa_tag_protocol mp) 299 300 { 300 301 enum dsa_tag_protocol proto = DSA_TAG_PROTO_KSZ9477; 301 302 struct ksz_device *dev = ds->priv;
+2 -1
drivers/net/dsa/mt7530.c
··· 1223 1223 } 1224 1224 1225 1225 static enum dsa_tag_protocol 1226 - mtk_get_tag_protocol(struct dsa_switch *ds, int port) 1226 + mtk_get_tag_protocol(struct dsa_switch *ds, int port, 1227 + enum dsa_tag_protocol mp) 1227 1228 { 1228 1229 struct mt7530_priv *priv = ds->priv; 1229 1230
+2 -1
drivers/net/dsa/mv88e6060.c
··· 43 43 } 44 44 45 45 static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds, 46 - int port) 46 + int port, 47 + enum dsa_tag_protocol m) 47 48 { 48 49 return DSA_TAG_PROTO_TRAILER; 49 50 }
+2 -1
drivers/net/dsa/mv88e6xxx/chip.c
··· 5217 5217 } 5218 5218 5219 5219 static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, 5220 - int port) 5220 + int port, 5221 + enum dsa_tag_protocol m) 5221 5222 { 5222 5223 struct mv88e6xxx_chip *chip = ds->priv; 5223 5224
+2 -1
drivers/net/dsa/ocelot/felix.c
··· 16 16 #include "felix.h" 17 17 18 18 static enum dsa_tag_protocol felix_get_tag_protocol(struct dsa_switch *ds, 19 - int port) 19 + int port, 20 + enum dsa_tag_protocol mp) 20 21 { 21 22 return DSA_TAG_PROTO_OCELOT; 22 23 }
+2 -1
drivers/net/dsa/qca/ar9331.c
··· 347 347 } 348 348 349 349 static enum dsa_tag_protocol ar9331_sw_get_tag_protocol(struct dsa_switch *ds, 350 - int port) 350 + int port, 351 + enum dsa_tag_protocol m) 351 352 { 352 353 return DSA_TAG_PROTO_AR9331; 353 354 }
+2 -1
drivers/net/dsa/qca8k.c
··· 1017 1017 } 1018 1018 1019 1019 static enum dsa_tag_protocol 1020 - qca8k_get_tag_protocol(struct dsa_switch *ds, int port) 1020 + qca8k_get_tag_protocol(struct dsa_switch *ds, int port, 1021 + enum dsa_tag_protocol mp) 1021 1022 { 1022 1023 return DSA_TAG_PROTO_QCA; 1023 1024 }
+2 -1
drivers/net/dsa/rtl8366rb.c
··· 964 964 } 965 965 966 966 static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds, 967 - int port) 967 + int port, 968 + enum dsa_tag_protocol mp) 968 969 { 969 970 /* For now, the RTL switches are handled without any custom tags. 970 971 *
+2 -1
drivers/net/dsa/sja1105/sja1105_main.c
··· 1534 1534 } 1535 1535 1536 1536 static enum dsa_tag_protocol 1537 - sja1105_get_tag_protocol(struct dsa_switch *ds, int port) 1537 + sja1105_get_tag_protocol(struct dsa_switch *ds, int port, 1538 + enum dsa_tag_protocol mp) 1538 1539 { 1539 1540 return DSA_TAG_PROTO_SJA1105; 1540 1541 }
+2 -1
drivers/net/dsa/vitesse-vsc73xx-core.c
··· 542 542 } 543 543 544 544 static enum dsa_tag_protocol vsc73xx_get_tag_protocol(struct dsa_switch *ds, 545 - int port) 545 + int port, 546 + enum dsa_tag_protocol mp) 546 547 { 547 548 /* The switch internally uses a 8 byte header with length, 548 549 * source port, tag, LPA and priority. This is supposedly
+2 -1
include/net/dsa.h
··· 380 380 bool is_static, void *data); 381 381 struct dsa_switch_ops { 382 382 enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds, 383 - int port); 383 + int port, 384 + enum dsa_tag_protocol mprot); 384 385 385 386 int (*setup)(struct dsa_switch *ds); 386 387 void (*teardown)(struct dsa_switch *ds);
+29 -2
net/dsa/dsa2.c
··· 614 614 return 0; 615 615 } 616 616 617 + static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp, 618 + struct net_device *master) 619 + { 620 + enum dsa_tag_protocol tag_protocol = DSA_TAG_PROTO_NONE; 621 + struct dsa_switch *mds, *ds = dp->ds; 622 + unsigned int mdp_upstream; 623 + struct dsa_port *mdp; 624 + 625 + /* It is possible to stack DSA switches onto one another when that 626 + * happens the switch driver may want to know if its tagging protocol 627 + * is going to work in such a configuration. 628 + */ 629 + if (dsa_slave_dev_check(master)) { 630 + mdp = dsa_slave_to_port(master); 631 + mds = mdp->ds; 632 + mdp_upstream = dsa_upstream_port(mds, mdp->index); 633 + tag_protocol = mds->ops->get_tag_protocol(mds, mdp_upstream, 634 + DSA_TAG_PROTO_NONE); 635 + } 636 + 637 + /* If the master device is not itself a DSA slave in a disjoint DSA 638 + * tree, then return immediately. 639 + */ 640 + return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol); 641 + } 642 + 617 643 static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) 618 644 { 619 645 struct dsa_switch *ds = dp->ds; ··· 647 621 const struct dsa_device_ops *tag_ops; 648 622 enum dsa_tag_protocol tag_protocol; 649 623 650 - tag_protocol = ds->ops->get_tag_protocol(ds, dp->index); 624 + tag_protocol = dsa_get_tag_protocol(dp, master); 651 625 tag_ops = dsa_tag_driver_get(tag_protocol); 652 626 if (IS_ERR(tag_ops)) { 653 627 if (PTR_ERR(tag_ops) == -ENOPROTOOPT) 654 628 return -EPROBE_DEFER; 655 629 dev_warn(ds->dev, "No tagger for this switch\n"); 630 + dp->master = NULL; 656 631 return PTR_ERR(tag_ops); 657 632 } 658 633 634 + dp->master = master; 659 635 dp->type = DSA_PORT_TYPE_CPU; 660 636 dp->filter = tag_ops->filter; 661 637 dp->rcv = tag_ops->rcv; 662 638 dp->tag_ops = tag_ops; 663 - dp->master = master; 664 639 dp->dst = dst; 665 640 666 641 return 0;
+1
net/dsa/dsa_priv.h
··· 157 157 void dsa_slave_mii_bus_init(struct dsa_switch *ds); 158 158 int dsa_slave_create(struct dsa_port *dp); 159 159 void dsa_slave_destroy(struct net_device *slave_dev); 160 + bool dsa_slave_dev_check(const struct net_device *dev); 160 161 int dsa_slave_suspend(struct net_device *slave_dev); 161 162 int dsa_slave_resume(struct net_device *slave_dev); 162 163 int dsa_slave_register_notifier(void);
+1 -3
net/dsa/slave.c
··· 22 22 23 23 #include "dsa_priv.h" 24 24 25 - static bool dsa_slave_dev_check(const struct net_device *dev); 26 - 27 25 /* slave mii_bus handling ***************************************************/ 28 26 static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg) 29 27 { ··· 1471 1473 free_netdev(slave_dev); 1472 1474 } 1473 1475 1474 - static bool dsa_slave_dev_check(const struct net_device *dev) 1476 + bool dsa_slave_dev_check(const struct net_device *dev) 1475 1477 { 1476 1478 return dev->netdev_ops == &dsa_slave_netdev_ops; 1477 1479 }