summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/dsa/tag.h18
-rw-r--r--net/dsa/tag_brcm.c8
-rw-r--r--net/dsa/tag_gswip.c6
-rw-r--r--net/dsa/tag_hellcreek.c3
-rw-r--r--net/dsa/tag_ksz.c20
-rw-r--r--net/dsa/tag_mtk.c3
-rw-r--r--net/dsa/tag_mxl-gsw1xx.c7
-rw-r--r--net/dsa/tag_ocelot.c6
-rw-r--r--net/dsa/tag_qca.c3
-rw-r--r--net/dsa/tag_rtl4_a.c2
-rw-r--r--net/dsa/tag_rtl8_4.c3
-rw-r--r--net/dsa/tag_rzn1_a5psw.c3
-rw-r--r--net/dsa/tag_trailer.c3
-rw-r--r--net/dsa/tag_xrs700x.c8
-rw-r--r--net/dsa/tag_yt921x.c8
15 files changed, 46 insertions, 55 deletions
diff --git a/net/dsa/tag.h b/net/dsa/tag.h
index 5d80ddad4ff6..cf52283fe9df 100644
--- a/net/dsa/tag.h
+++ b/net/dsa/tag.h
@@ -319,6 +319,24 @@ static inline void *dsa_etype_header_pos_tx(struct sk_buff *skb)
return skb->data + 2 * ETH_ALEN;
}
+static inline unsigned long dsa_xmit_port_mask(const struct sk_buff *skb,
+ const struct net_device *dev)
+{
+ struct dsa_port *dp = dsa_user_to_port(dev);
+ unsigned long mask = BIT(dp->index);
+
+ if (IS_ENABLED(CONFIG_HSR) &&
+ unlikely(dev->features & NETIF_F_HW_HSR_DUP)) {
+ struct net_device *hsr_dev = dp->hsr_dev;
+ struct dsa_port *other_dp;
+
+ dsa_hsr_foreach_port(other_dp, dp->ds, hsr_dev)
+ mask |= BIT(other_dp->index);
+ }
+
+ return mask;
+}
+
/* Create 2 modaliases per tagging protocol, one to auto-load the module
* given the ID reported by get_tag_protocol(), and the other by name.
*/
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index eadb358179ce..cf9420439054 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -92,6 +92,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
{
struct dsa_port *dp = dsa_user_to_port(dev);
u16 queue = skb_get_queue_mapping(skb);
+ u16 port_mask;
u8 *brcm_tag;
/* The Ethernet switch we are interfaced with needs packets to be at
@@ -119,10 +120,9 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) |
((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT);
brcm_tag[1] = 0;
- brcm_tag[2] = 0;
- if (dp->index == 8)
- brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
- brcm_tag[3] = (1 << dp->index) & BRCM_IG_DSTMAP1_MASK;
+ port_mask = dsa_xmit_port_mask(skb, dev);
+ brcm_tag[2] = (port_mask >> 8) & BRCM_IG_DSTMAP2_MASK;
+ brcm_tag[3] = port_mask & BRCM_IG_DSTMAP1_MASK;
/* Now tell the conduit network device about the desired output queue
* as well
diff --git a/net/dsa/tag_gswip.c b/net/dsa/tag_gswip.c
index 51a1f46a567f..5fa436121087 100644
--- a/net/dsa/tag_gswip.c
+++ b/net/dsa/tag_gswip.c
@@ -48,8 +48,7 @@
/* Byte 3 */
#define GSWIP_TX_DPID_EN BIT(0)
-#define GSWIP_TX_PORT_MAP_SHIFT 1
-#define GSWIP_TX_PORT_MAP_MASK GENMASK(6, 1)
+#define GSWIP_TX_PORT_MAP GENMASK(6, 1)
#define GSWIP_RX_HEADER_LEN 8
@@ -61,7 +60,6 @@
static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
u8 *gswip_tag;
skb_push(skb, GSWIP_TX_HEADER_LEN);
@@ -70,7 +68,7 @@ static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
gswip_tag[0] = GSWIP_TX_SLPID_CPU;
gswip_tag[1] = GSWIP_TX_DPID_ELAN;
gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
- gswip_tag[3] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
+ gswip_tag[3] = FIELD_PREP(GSWIP_TX_PORT_MAP, dsa_xmit_port_mask(skb, dev));
gswip_tag[3] |= GSWIP_TX_DPID_EN;
return skb;
diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c
index 663b25785d95..544ab15685a2 100644
--- a/net/dsa/tag_hellcreek.c
+++ b/net/dsa/tag_hellcreek.c
@@ -20,7 +20,6 @@
static struct sk_buff *hellcreek_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
u8 *tag;
/* Calculate checksums (if required) before adding the trailer tag to
@@ -33,7 +32,7 @@ static struct sk_buff *hellcreek_xmit(struct sk_buff *skb,
/* Tag encoding */
tag = skb_put(skb, HELLCREEK_TAG_LEN);
- *tag = BIT(dp->index);
+ *tag = dsa_xmit_port_mask(skb, dev);
return skb;
}
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 0b7564b53790..9170a0148cc4 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -120,7 +120,6 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
struct ethhdr *hdr;
u8 *tag;
@@ -131,7 +130,7 @@ static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
hdr = skb_eth_hdr(skb);
- *tag = 1 << dp->index;
+ *tag = dsa_xmit_port_mask(skb, dev);
if (is_link_local_ether_addr(hdr->h_dest))
*tag |= KSZ8795_TAIL_TAG_OVERRIDE;
@@ -294,21 +293,12 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN);
hdr = skb_eth_hdr(skb);
- val = BIT(dp->index);
-
+ val = dsa_xmit_port_mask(skb, dev);
val |= FIELD_PREP(KSZ9477_TAIL_TAG_PRIO, prio);
if (is_link_local_ether_addr(hdr->h_dest))
val |= KSZ9477_TAIL_TAG_OVERRIDE;
- if (dev->features & NETIF_F_HW_HSR_DUP) {
- struct net_device *hsr_dev = dp->hsr_dev;
- struct dsa_port *other_dp;
-
- dsa_hsr_foreach_port(other_dp, dp->ds, hsr_dev)
- val |= BIT(other_dp->index);
- }
-
*tag = cpu_to_be16(val);
return ksz_defer_xmit(dp, skb);
@@ -371,8 +361,7 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
hdr = skb_eth_hdr(skb);
- *tag = BIT(dp->index);
-
+ *tag = dsa_xmit_port_mask(skb, dev);
*tag |= FIELD_PREP(KSZ9893_TAIL_TAG_PRIO, prio);
if (is_link_local_ether_addr(hdr->h_dest))
@@ -436,8 +425,7 @@ static struct sk_buff *lan937x_xmit(struct sk_buff *skb,
tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN);
- val = BIT(dp->index);
-
+ val = dsa_xmit_port_mask(skb, dev);
val |= FIELD_PREP(LAN937X_TAIL_TAG_PRIO, prio);
if (is_link_local_ether_addr(hdr->h_dest))
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index b670e3c53e91..dea3eecaf093 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -54,7 +54,8 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
* whether that's a combined special tag with 802.1Q header.
*/
mtk_tag[0] = xmit_tpid;
- mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
+ mtk_tag[1] = FIELD_PREP(MTK_HDR_XMIT_DP_BIT_MASK,
+ dsa_xmit_port_mask(skb, dev));
/* Tag control information is kept for 802.1Q */
if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) {
diff --git a/net/dsa/tag_mxl-gsw1xx.c b/net/dsa/tag_mxl-gsw1xx.c
index 701a079955f2..60f7c445e656 100644
--- a/net/dsa/tag_mxl-gsw1xx.c
+++ b/net/dsa/tag_mxl-gsw1xx.c
@@ -43,8 +43,8 @@
static struct sk_buff *gsw1xx_tag_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
__be16 *gsw1xx_tag;
+ u16 tag;
/* provide additional space 'GSW1XX_HEADER_LEN' bytes */
skb_push(skb, GSW1XX_HEADER_LEN);
@@ -55,9 +55,10 @@ static struct sk_buff *gsw1xx_tag_xmit(struct sk_buff *skb,
/* special tag ingress */
gsw1xx_tag = dsa_etype_header_pos_tx(skb);
gsw1xx_tag[0] = htons(ETH_P_MXLGSW);
- gsw1xx_tag[1] = htons(GSW1XX_TX_PORT_MAP_EN | GSW1XX_TX_LRN_DIS |
- FIELD_PREP(GSW1XX_TX_PORT_MAP, BIT(dp->index)));
+ tag = FIELD_PREP(GSW1XX_TX_PORT_MAP, dsa_xmit_port_mask(skb, dev)) |
+ GSW1XX_TX_PORT_MAP_EN | GSW1XX_TX_LRN_DIS;
+ gsw1xx_tag[1] = htons(tag);
gsw1xx_tag[2] = 0;
gsw1xx_tag[3] = 0;
diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c
index bf6608fc6be7..3405def79c2d 100644
--- a/net/dsa/tag_ocelot.c
+++ b/net/dsa/tag_ocelot.c
@@ -46,11 +46,10 @@ static void ocelot_xmit_common(struct sk_buff *skb, struct net_device *netdev,
static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
struct net_device *netdev)
{
- struct dsa_port *dp = dsa_user_to_port(netdev);
void *injection;
ocelot_xmit_common(skb, netdev, cpu_to_be32(0x8880000a), &injection);
- ocelot_ifh_set_dest(injection, BIT_ULL(dp->index));
+ ocelot_ifh_set_dest(injection, dsa_xmit_port_mask(skb, netdev));
return skb;
}
@@ -58,11 +57,10 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
static struct sk_buff *seville_xmit(struct sk_buff *skb,
struct net_device *netdev)
{
- struct dsa_port *dp = dsa_user_to_port(netdev);
void *injection;
ocelot_xmit_common(skb, netdev, cpu_to_be32(0x88800005), &injection);
- seville_ifh_set_dest(injection, BIT_ULL(dp->index));
+ seville_ifh_set_dest(injection, dsa_xmit_port_mask(skb, netdev));
return skb;
}
diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
index 0cf61286b426..6d56a28c914c 100644
--- a/net/dsa/tag_qca.c
+++ b/net/dsa/tag_qca.c
@@ -14,7 +14,6 @@
static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
__be16 *phdr;
u16 hdr;
@@ -26,7 +25,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set the version field, and set destination port information */
hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
hdr |= QCA_HDR_XMIT_FROM_CPU;
- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(dp->index));
+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, dsa_xmit_port_mask(skb, dev));
*phdr = htons(hdr);
diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c
index feaefa0e179b..3cc63eacfa03 100644
--- a/net/dsa/tag_rtl4_a.c
+++ b/net/dsa/tag_rtl4_a.c
@@ -57,7 +57,7 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
out = (RTL4_A_PROTOCOL_RTL8366RB << RTL4_A_PROTOCOL_SHIFT);
/* The lower bits indicate the port number */
- out |= BIT(dp->index);
+ out |= dsa_xmit_port_mask(skb, dev);
p = (__be16 *)(tag + 2);
*p = htons(out);
diff --git a/net/dsa/tag_rtl8_4.c b/net/dsa/tag_rtl8_4.c
index 15c2bae2b429..2464545da4d2 100644
--- a/net/dsa/tag_rtl8_4.c
+++ b/net/dsa/tag_rtl8_4.c
@@ -103,7 +103,6 @@
static void rtl8_4_write_tag(struct sk_buff *skb, struct net_device *dev,
void *tag)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
__be16 tag16[RTL8_4_TAG_LEN / 2];
/* Set Realtek EtherType */
@@ -116,7 +115,7 @@ static void rtl8_4_write_tag(struct sk_buff *skb, struct net_device *dev,
tag16[2] = htons(FIELD_PREP(RTL8_4_LEARN_DIS, 1));
/* Zero ALLOW; set RX (CPU->switch) forwarding port mask */
- tag16[3] = htons(FIELD_PREP(RTL8_4_RX, BIT(dp->index)));
+ tag16[3] = htons(FIELD_PREP(RTL8_4_RX, dsa_xmit_port_mask(skb, dev)));
memcpy(tag, tag16, RTL8_4_TAG_LEN);
}
diff --git a/net/dsa/tag_rzn1_a5psw.c b/net/dsa/tag_rzn1_a5psw.c
index 69d51221b1e5..10994b3470f6 100644
--- a/net/dsa/tag_rzn1_a5psw.c
+++ b/net/dsa/tag_rzn1_a5psw.c
@@ -39,7 +39,6 @@ struct a5psw_tag {
static struct sk_buff *a5psw_tag_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
struct a5psw_tag *ptag;
u32 data2_val;
@@ -60,7 +59,7 @@ static struct sk_buff *a5psw_tag_xmit(struct sk_buff *skb, struct net_device *de
ptag = dsa_etype_header_pos_tx(skb);
- data2_val = FIELD_PREP(A5PSW_CTRL_DATA_PORT, BIT(dp->index));
+ data2_val = FIELD_PREP(A5PSW_CTRL_DATA_PORT, dsa_xmit_port_mask(skb, dev));
ptag->ctrl_tag = htons(ETH_P_DSA_A5PSW);
ptag->ctrl_data = htons(A5PSW_CTRL_DATA_FORCE_FORWARD);
ptag->ctrl_data2_lo = htons(data2_val);
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index 22742a53d6f4..4dce24cfe6a7 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -14,12 +14,11 @@
static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct dsa_port *dp = dsa_user_to_port(dev);
u8 *trailer;
trailer = skb_put(skb, 4);
trailer[0] = 0x80;
- trailer[1] = 1 << dp->index;
+ trailer[1] = dsa_xmit_port_mask(skb, dev);
trailer[2] = 0x10;
trailer[3] = 0x00;
diff --git a/net/dsa/tag_xrs700x.c b/net/dsa/tag_xrs700x.c
index 68d4633ddd5e..a05219f702c6 100644
--- a/net/dsa/tag_xrs700x.c
+++ b/net/dsa/tag_xrs700x.c
@@ -13,16 +13,10 @@
static struct sk_buff *xrs700x_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct dsa_port *partner, *dp = dsa_user_to_port(dev);
u8 *trailer;
trailer = skb_put(skb, 1);
- trailer[0] = BIT(dp->index);
-
- if (dp->hsr_dev)
- dsa_hsr_foreach_port(partner, dp->ds, dp->hsr_dev)
- if (partner != dp)
- trailer[0] |= BIT(partner->index);
+ trailer[0] = dsa_xmit_port_mask(skb, dev);
return skb;
}
diff --git a/net/dsa/tag_yt921x.c b/net/dsa/tag_yt921x.c
index 995da44f0a2a..6bbfd42dc5df 100644
--- a/net/dsa/tag_yt921x.c
+++ b/net/dsa/tag_yt921x.c
@@ -38,14 +38,11 @@
#define YT921X_TAG_RX_CMD_FORWARDED 0x80
#define YT921X_TAG_RX_CMD_UNK_UCAST 0xb2
#define YT921X_TAG_RX_CMD_UNK_MCAST 0xb4
-#define YT921X_TAG_TX_PORTS_M GENMASK(10, 0)
-#define YT921X_TAG_TX_PORTn(port) BIT(port)
+#define YT921X_TAG_TX_PORTS GENMASK(10, 0)
static struct sk_buff *
yt921x_tag_xmit(struct sk_buff *skb, struct net_device *netdev)
{
- struct dsa_port *dp = dsa_user_to_port(netdev);
- unsigned int port = dp->index;
__be16 *tag;
u16 tx;
@@ -58,7 +55,8 @@ yt921x_tag_xmit(struct sk_buff *skb, struct net_device *netdev)
/* VLAN tag unrelated when TX */
tag[1] = 0;
tag[2] = 0;
- tx = YT921X_TAG_PORT_EN | YT921X_TAG_TX_PORTn(port);
+ tx = FIELD_PREP(YT921X_TAG_TX_PORTS, dsa_xmit_port_mask(skb, netdev)) |
+ YT921X_TAG_PORT_EN;
tag[3] = htons(tx);
return skb;