Skip to content

Commit 85ee987

Browse files
dangowrtPaolo Abeni
authored andcommitted
net: dsa: add tag format for MxL862xx switches
Add proprietary special tag format for the MaxLinear MXL862xx family of switches. While using the same Ethertype as MaxLinear's GSW1xx switches, the actual tag format differs significantly, hence we need a dedicated tag driver for that. Signed-off-by: Daniel Golle <daniel@makrotopia.org> Link: https://patch.msgid.link/c64e6ddb6c93a4fac39f9ab9b2d8bf551a2b118d.1770433307.git.daniel@makrotopia.org Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 4ccc985 commit 85ee987

5 files changed

Lines changed: 121 additions & 0 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15631,6 +15631,7 @@ M: Daniel Golle <daniel@makrotopia.org>
1563115631
L: netdev@vger.kernel.org
1563215632
S: Maintained
1563315633
F: Documentation/devicetree/bindings/net/dsa/maxlinear,mxl862xx.yaml
15634+
F: net/dsa/tag_mxl862xx.c
1563415635

1563515636
MCAN DEVICE DRIVER
1563615637
M: Markus Schneider-Pargmann <msp@baylibre.com>

include/net/dsa.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct tc_action;
5757
#define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE 29
5858
#define DSA_TAG_PROTO_YT921X_VALUE 30
5959
#define DSA_TAG_PROTO_MXL_GSW1XX_VALUE 31
60+
#define DSA_TAG_PROTO_MXL862_VALUE 32
6061

6162
enum dsa_tag_protocol {
6263
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -91,6 +92,7 @@ enum dsa_tag_protocol {
9192
DSA_TAG_PROTO_VSC73XX_8021Q = DSA_TAG_PROTO_VSC73XX_8021Q_VALUE,
9293
DSA_TAG_PROTO_YT921X = DSA_TAG_PROTO_YT921X_VALUE,
9394
DSA_TAG_PROTO_MXL_GSW1XX = DSA_TAG_PROTO_MXL_GSW1XX_VALUE,
95+
DSA_TAG_PROTO_MXL862 = DSA_TAG_PROTO_MXL862_VALUE,
9496
};
9597

9698
struct dsa_switch;

net/dsa/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ config NET_DSA_TAG_MTK
104104
Say Y or M if you want to enable support for tagging frames for
105105
Mediatek switches.
106106

107+
config NET_DSA_TAG_MXL_862XX
108+
tristate "Tag driver for MaxLinear MxL862xx switches"
109+
help
110+
Say Y or M if you want to enable support for tagging frames for the
111+
MaxLinear MxL86252 and MxL86282 switches using their native 8-byte
112+
tagging protocol.
113+
107114
config NET_DSA_TAG_MXL_GSW1XX
108115
tristate "Tag driver for MaxLinear GSW1xx switches"
109116
help

net/dsa/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o
2828
obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
2929
obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
3030
obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
31+
obj-$(CONFIG_NET_DSA_TAG_MXL_862XX) += tag_mxl862xx.o
3132
obj-$(CONFIG_NET_DSA_TAG_MXL_GSW1XX) += tag_mxl-gsw1xx.o
3233
obj-$(CONFIG_NET_DSA_TAG_NONE) += tag_none.o
3334
obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o

net/dsa/tag_mxl862xx.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* DSA Special Tag for MaxLinear 862xx switch chips
4+
*
5+
* Copyright (C) 2025 Daniel Golle <daniel@makrotopia.org>
6+
* Copyright (C) 2024 MaxLinear Inc.
7+
*/
8+
9+
#include <linux/bitops.h>
10+
#include <linux/etherdevice.h>
11+
#include <linux/skbuff.h>
12+
#include <net/dsa.h>
13+
#include "tag.h"
14+
15+
#define MXL862_NAME "mxl862xx"
16+
17+
#define MXL862_HEADER_LEN 8
18+
19+
/* Word 0 -> EtherType */
20+
21+
/* Word 2 */
22+
#define MXL862_SUBIF_ID GENMASK(4, 0)
23+
24+
/* Word 3 */
25+
#define MXL862_IGP_EGP GENMASK(3, 0)
26+
27+
static struct sk_buff *mxl862_tag_xmit(struct sk_buff *skb,
28+
struct net_device *dev)
29+
{
30+
struct dsa_port *dp = dsa_user_to_port(dev);
31+
struct dsa_port *cpu_dp = dp->cpu_dp;
32+
unsigned int cpu_port, sub_interface;
33+
__be16 *mxl862_tag;
34+
35+
cpu_port = cpu_dp->index;
36+
37+
/* target port sub-interface ID relative to the CPU port */
38+
sub_interface = dp->index + 16 - cpu_port;
39+
40+
/* provide additional space 'MXL862_HEADER_LEN' bytes */
41+
skb_push(skb, MXL862_HEADER_LEN);
42+
43+
/* shift MAC address to the beginning of the enlarged buffer,
44+
* releasing the space required for DSA tag (between MAC address and
45+
* Ethertype)
46+
*/
47+
dsa_alloc_etype_header(skb, MXL862_HEADER_LEN);
48+
49+
/* special tag ingress (from the perspective of the switch) */
50+
mxl862_tag = dsa_etype_header_pos_tx(skb);
51+
mxl862_tag[0] = htons(ETH_P_MXLGSW);
52+
mxl862_tag[1] = 0;
53+
mxl862_tag[2] = htons(FIELD_PREP(MXL862_SUBIF_ID, sub_interface));
54+
mxl862_tag[3] = htons(FIELD_PREP(MXL862_IGP_EGP, cpu_port));
55+
56+
return skb;
57+
}
58+
59+
static struct sk_buff *mxl862_tag_rcv(struct sk_buff *skb,
60+
struct net_device *dev)
61+
{
62+
__be16 *mxl862_tag;
63+
int port;
64+
65+
if (unlikely(!pskb_may_pull(skb, MXL862_HEADER_LEN))) {
66+
dev_warn_ratelimited(&dev->dev, "Cannot pull SKB, packet dropped\n");
67+
return NULL;
68+
}
69+
70+
mxl862_tag = dsa_etype_header_pos_rx(skb);
71+
72+
if (unlikely(mxl862_tag[0] != htons(ETH_P_MXLGSW))) {
73+
dev_warn_ratelimited(&dev->dev,
74+
"Invalid special tag marker, packet dropped, tag: %8ph\n",
75+
mxl862_tag);
76+
return NULL;
77+
}
78+
79+
/* Get source port information */
80+
port = FIELD_GET(MXL862_IGP_EGP, ntohs(mxl862_tag[3]));
81+
skb->dev = dsa_conduit_find_user(dev, 0, port);
82+
if (unlikely(!skb->dev)) {
83+
dev_warn_ratelimited(&dev->dev,
84+
"Invalid source port, packet dropped, tag: %8ph\n",
85+
mxl862_tag);
86+
return NULL;
87+
}
88+
89+
/* remove the MxL862xx special tag between the MAC addresses and the
90+
* current ethertype field.
91+
*/
92+
skb_pull_rcsum(skb, MXL862_HEADER_LEN);
93+
dsa_strip_etype_header(skb, MXL862_HEADER_LEN);
94+
95+
return skb;
96+
}
97+
98+
static const struct dsa_device_ops mxl862_netdev_ops = {
99+
.name = MXL862_NAME,
100+
.proto = DSA_TAG_PROTO_MXL862,
101+
.xmit = mxl862_tag_xmit,
102+
.rcv = mxl862_tag_rcv,
103+
.needed_headroom = MXL862_HEADER_LEN,
104+
};
105+
106+
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_MXL862, MXL862_NAME);
107+
MODULE_DESCRIPTION("DSA tag driver for MaxLinear MxL862xx switches");
108+
MODULE_LICENSE("GPL");
109+
110+
module_dsa_tag_driver(mxl862_netdev_ops);

0 commit comments

Comments
 (0)