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

Merge branch 'dsa-b53-Support-prepended-Broadcom-tags'

Florian Fainelli says:

====================
net: dsa: b53: Support prepended Broadcom tags

This patch series adds support for prepended 4-bytes Broadcom tags that we
already support. This type of tag will typically be used when interfaced to
a SoC like BCM58xx (NorthStar Plus) which supports a Flow Accelerator (WIP).
In that case, we need to support a slightly different tagging format.

The first patch does a bit of re-factoring and passes a port index to
the get_tag_protocol() function since at least two different drivers need
that type of information (mt7530, b53) to support tagging or not.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+109 -44
+1
drivers/net/dsa/b53/Kconfig
··· 2 2 tristate "Broadcom BCM53xx managed switch support" 3 3 depends on NET_DSA 4 4 select NET_DSA_TAG_BRCM 5 + select NET_DSA_TAG_BRCM_PREPEND 5 6 help 6 7 This driver adds support for Broadcom managed switch chips. It supports 7 8 BCM5325E, BCM5365, BCM539x, BCM53115 and BCM53125 as well as BCM63XX
+21 -21
drivers/net/dsa/b53/b53_common.c
··· 541 541 542 542 void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) 543 543 { 544 - bool tag_en = !!(ds->ops->get_tag_protocol(ds) == DSA_TAG_PROTO_BRCM); 544 + bool tag_en = !(ds->ops->get_tag_protocol(ds, port) == 545 + DSA_TAG_PROTO_NONE); 545 546 struct b53_device *dev = ds->priv; 546 547 u8 hdr_ctl, val; 547 548 u16 reg; ··· 1479 1478 } 1480 1479 EXPORT_SYMBOL(b53_br_fast_age); 1481 1480 1482 - static bool b53_can_enable_brcm_tags(struct dsa_switch *ds) 1481 + static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port) 1483 1482 { 1484 - unsigned int brcm_tag_mask; 1485 - unsigned int i; 1486 - 1487 1483 /* Broadcom switches will accept enabling Broadcom tags on the 1488 1484 * following ports: 5, 7 and 8, any other port is not supported 1489 1485 */ 1490 - brcm_tag_mask = BIT(B53_CPU_PORT_25) | BIT(7) | BIT(B53_CPU_PORT); 1491 - 1492 - for (i = 0; i < ds->num_ports; i++) { 1493 - if (dsa_is_cpu_port(ds, i)) { 1494 - if (!(BIT(i) & brcm_tag_mask)) { 1495 - dev_warn(ds->dev, 1496 - "Port %d is not Broadcom tag capable\n", 1497 - i); 1498 - return false; 1499 - } 1500 - } 1486 + switch (port) { 1487 + case B53_CPU_PORT_25: 1488 + case 7: 1489 + case B53_CPU_PORT: 1490 + return true; 1501 1491 } 1502 1492 1503 - return true; 1493 + dev_warn(ds->dev, "Port %d is not Broadcom tag capable\n", port); 1494 + return false; 1504 1495 } 1505 1496 1506 - static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds) 1497 + static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, 1498 + int port) 1507 1499 { 1508 1500 struct b53_device *dev = ds->priv; 1509 1501 1510 1502 /* Older models support a different tag format that we do not 1511 1503 * support in net/dsa/tag_brcm.c yet. 1512 1504 */ 1513 - if (is5325(dev) || is5365(dev) || !b53_can_enable_brcm_tags(ds)) 1505 + if (is5325(dev) || is5365(dev) || !b53_can_enable_brcm_tags(ds, port)) 1514 1506 return DSA_TAG_PROTO_NONE; 1515 - else 1516 - return DSA_TAG_PROTO_BRCM; 1507 + 1508 + /* Broadcom BCM58xx chips have a flow accelerator on Port 8 1509 + * which requires us to use the prepended Broadcom tag type 1510 + */ 1511 + if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) 1512 + return DSA_TAG_PROTO_BRCM_PREPEND; 1513 + 1514 + return DSA_TAG_PROTO_BRCM; 1517 1515 } 1518 1516 1519 1517 int b53_mirror_add(struct dsa_switch *ds, int port,
+2 -1
drivers/net/dsa/bcm_sf2.c
··· 35 35 #include "b53/b53_priv.h" 36 36 #include "b53/b53_regs.h" 37 37 38 - static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds) 38 + static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds, 39 + int port) 39 40 { 40 41 return DSA_TAG_PROTO_BRCM; 41 42 }
+2 -1
drivers/net/dsa/dsa_loop.c
··· 64 64 65 65 static struct phy_device *phydevs[PHY_MAX_ADDR]; 66 66 67 - static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds) 67 + static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds, 68 + int port) 68 69 { 69 70 dev_dbg(ds->dev, "%s\n", __func__); 70 71
+2 -1
drivers/net/dsa/lan9303-core.c
··· 894 894 895 895 /* ---------------------------- DSA -----------------------------------*/ 896 896 897 - static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds) 897 + static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds, 898 + int port) 898 899 { 899 900 return DSA_TAG_PROTO_LAN9303; 900 901 }
+2 -1
drivers/net/dsa/microchip/ksz_common.c
··· 394 394 return 0; 395 395 } 396 396 397 - static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds) 397 + static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, 398 + int port) 398 399 { 399 400 return DSA_TAG_PROTO_KSZ; 400 401 }
+2 -2
drivers/net/dsa/mt7530.c
··· 907 907 } 908 908 909 909 static enum dsa_tag_protocol 910 - mtk_get_tag_protocol(struct dsa_switch *ds) 910 + mtk_get_tag_protocol(struct dsa_switch *ds, int port) 911 911 { 912 912 struct mt7530_priv *priv = ds->priv; 913 913 914 - if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) { 914 + if (port != MT7530_CPU_PORT) { 915 915 dev_warn(priv->dev, 916 916 "port not matched with tagging CPU port\n"); 917 917 return DSA_TAG_PROTO_NONE;
+2 -1
drivers/net/dsa/mv88e6060.c
··· 70 70 return NULL; 71 71 } 72 72 73 - static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds) 73 + static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds, 74 + int port) 74 75 { 75 76 return DSA_TAG_PROTO_TRAILER; 76 77 }
+2 -1
drivers/net/dsa/mv88e6xxx/chip.c
··· 3731 3731 return 0; 3732 3732 } 3733 3733 3734 - static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds) 3734 + static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, 3735 + int port) 3735 3736 { 3736 3737 struct mv88e6xxx_chip *chip = ds->priv; 3737 3738
+1 -1
drivers/net/dsa/qca8k.c
··· 823 823 } 824 824 825 825 static enum dsa_tag_protocol 826 - qca8k_get_tag_protocol(struct dsa_switch *ds) 826 + qca8k_get_tag_protocol(struct dsa_switch *ds, int port) 827 827 { 828 828 return DSA_TAG_PROTO_QCA; 829 829 }
+3 -1
include/net/dsa.h
··· 29 29 enum dsa_tag_protocol { 30 30 DSA_TAG_PROTO_NONE = 0, 31 31 DSA_TAG_PROTO_BRCM, 32 + DSA_TAG_PROTO_BRCM_PREPEND, 32 33 DSA_TAG_PROTO_DSA, 33 34 DSA_TAG_PROTO_EDSA, 34 35 DSA_TAG_PROTO_KSZ, ··· 322 321 struct device *host_dev, int sw_addr, 323 322 void **priv); 324 323 325 - enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds); 324 + enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds, 325 + int port); 326 326 327 327 int (*setup)(struct dsa_switch *ds); 328 328 u32 (*get_phy_flags)(struct dsa_switch *ds, int port);
+3
net/dsa/Kconfig
··· 19 19 config NET_DSA_TAG_BRCM 20 20 bool 21 21 22 + config NET_DSA_TAG_BRCM_PREPEND 23 + bool 24 + 22 25 config NET_DSA_TAG_DSA 23 26 bool 24 27
+1
net/dsa/Makefile
··· 5 5 6 6 # tagging formats 7 7 dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o 8 + dsa_core-$(CONFIG_NET_DSA_TAG_BRCM_PREPEND) += tag_brcm.o 8 9 dsa_core-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o 9 10 dsa_core-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o 10 11 dsa_core-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
+3
net/dsa/dsa.c
··· 44 44 #ifdef CONFIG_NET_DSA_TAG_BRCM 45 45 [DSA_TAG_PROTO_BRCM] = &brcm_netdev_ops, 46 46 #endif 47 + #ifdef CONFIG_NET_DSA_TAG_BRCM_PREPEND 48 + [DSA_TAG_PROTO_BRCM_PREPEND] = &brcm_prepend_netdev_ops, 49 + #endif 47 50 #ifdef CONFIG_NET_DSA_TAG_DSA 48 51 [DSA_TAG_PROTO_DSA] = &dsa_netdev_ops, 49 52 #endif
+1 -1
net/dsa/dsa2.c
··· 539 539 const struct dsa_device_ops *tag_ops; 540 540 enum dsa_tag_protocol tag_protocol; 541 541 542 - tag_protocol = ds->ops->get_tag_protocol(ds); 542 + tag_protocol = ds->ops->get_tag_protocol(ds, dp->index); 543 543 tag_ops = dsa_resolve_tag_protocol(tag_protocol); 544 544 if (IS_ERR(tag_ops)) { 545 545 dev_warn(ds->dev, "No tagger for this switch\n");
+1
net/dsa/dsa_priv.h
··· 191 191 192 192 /* tag_brcm.c */ 193 193 extern const struct dsa_device_ops brcm_netdev_ops; 194 + extern const struct dsa_device_ops brcm_prepend_netdev_ops; 194 195 195 196 /* tag_dsa.c */ 196 197 extern const struct dsa_device_ops dsa_netdev_ops;
+1 -1
net/dsa/legacy.c
··· 151 151 const struct dsa_device_ops *tag_ops; 152 152 enum dsa_tag_protocol tag_protocol; 153 153 154 - tag_protocol = ops->get_tag_protocol(ds); 154 + tag_protocol = ops->get_tag_protocol(ds, dst->cpu_dp->index); 155 155 tag_ops = dsa_resolve_tag_protocol(tag_protocol); 156 156 if (IS_ERR(tag_ops)) 157 157 return PTR_ERR(tag_ops);
+59 -11
net/dsa/tag_brcm.c
··· 59 59 #define BRCM_EG_TC_MASK 0x7 60 60 #define BRCM_EG_PID_MASK 0x1f 61 61 62 - static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev) 62 + static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, 63 + struct net_device *dev, 64 + unsigned int offset) 63 65 { 64 66 struct dsa_port *dp = dsa_slave_to_port(dev); 65 67 u16 queue = skb_get_queue_mapping(skb); ··· 72 70 73 71 skb_push(skb, BRCM_TAG_LEN); 74 72 75 - memmove(skb->data, skb->data + BRCM_TAG_LEN, 2 * ETH_ALEN); 73 + if (offset) 74 + memmove(skb->data, skb->data + BRCM_TAG_LEN, offset); 76 75 77 - /* Build the tag after the MAC Source Address */ 78 - brcm_tag = skb->data + 2 * ETH_ALEN; 76 + brcm_tag = skb->data + offset; 79 77 80 78 /* Set the ingress opcode, traffic class, tag enforcment is 81 79 * deprecated ··· 96 94 return skb; 97 95 } 98 96 99 - static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, 100 - struct packet_type *pt) 97 + static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, 98 + struct net_device *dev, 99 + struct packet_type *pt, 100 + unsigned int offset) 101 101 { 102 102 int source_port; 103 103 u8 *brcm_tag; ··· 107 103 if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN))) 108 104 return NULL; 109 105 110 - /* skb->data points to the EtherType, the tag is right before it */ 111 - brcm_tag = skb->data - 2; 106 + brcm_tag = skb->data - offset; 112 107 113 108 /* The opcode should never be different than 0b000 */ 114 109 if (unlikely((brcm_tag[0] >> BRCM_OPCODE_SHIFT) & BRCM_OPCODE_MASK)) ··· 129 126 /* Remove Broadcom tag and update checksum */ 130 127 skb_pull_rcsum(skb, BRCM_TAG_LEN); 131 128 129 + return skb; 130 + } 131 + 132 + #ifdef CONFIG_NET_DSA_TAG_BRCM 133 + static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, 134 + struct net_device *dev) 135 + { 136 + /* Build the tag after the MAC Source Address */ 137 + return brcm_tag_xmit_ll(skb, dev, 2 * ETH_ALEN); 138 + } 139 + 140 + 141 + static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, 142 + struct packet_type *pt) 143 + { 144 + struct sk_buff *nskb; 145 + 146 + /* skb->data points to the EtherType, the tag is right before it */ 147 + nskb = brcm_tag_rcv_ll(skb, dev, pt, 2); 148 + if (!nskb) 149 + return nskb; 150 + 132 151 /* Move the Ethernet DA and SA */ 133 - memmove(skb->data - ETH_HLEN, 134 - skb->data - ETH_HLEN - BRCM_TAG_LEN, 152 + memmove(nskb->data - ETH_HLEN, 153 + nskb->data - ETH_HLEN - BRCM_TAG_LEN, 135 154 2 * ETH_ALEN); 136 155 137 - return skb; 156 + return nskb; 138 157 } 139 158 140 159 const struct dsa_device_ops brcm_netdev_ops = { 141 160 .xmit = brcm_tag_xmit, 142 161 .rcv = brcm_tag_rcv, 143 162 }; 163 + #endif 164 + 165 + #ifdef CONFIG_NET_DSA_TAG_BRCM_PREPEND 166 + static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb, 167 + struct net_device *dev) 168 + { 169 + /* tag is prepended to the packet */ 170 + return brcm_tag_xmit_ll(skb, dev, 0); 171 + } 172 + 173 + static struct sk_buff *brcm_tag_rcv_prepend(struct sk_buff *skb, 174 + struct net_device *dev, 175 + struct packet_type *pt) 176 + { 177 + /* tag is prepended to the packet */ 178 + return brcm_tag_rcv_ll(skb, dev, pt, ETH_HLEN); 179 + } 180 + 181 + const struct dsa_device_ops brcm_prepend_netdev_ops = { 182 + .xmit = brcm_tag_xmit_prepend, 183 + .rcv = brcm_tag_rcv_prepend, 184 + }; 185 + #endif