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

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Daniel Golle and committed by
Paolo Abeni
85ee9874 4ccc9851

+121
+1
MAINTAINERS
··· 15631 15631 L: netdev@vger.kernel.org 15632 15632 S: Maintained 15633 15633 F: Documentation/devicetree/bindings/net/dsa/maxlinear,mxl862xx.yaml 15634 + F: net/dsa/tag_mxl862xx.c 15634 15635 15635 15636 MCAN DEVICE DRIVER 15636 15637 M: Markus Schneider-Pargmann <msp@baylibre.com>
+2
include/net/dsa.h
··· 57 57 #define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE 29 58 58 #define DSA_TAG_PROTO_YT921X_VALUE 30 59 59 #define DSA_TAG_PROTO_MXL_GSW1XX_VALUE 31 60 + #define DSA_TAG_PROTO_MXL862_VALUE 32 60 61 61 62 enum dsa_tag_protocol { 62 63 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, ··· 92 91 DSA_TAG_PROTO_VSC73XX_8021Q = DSA_TAG_PROTO_VSC73XX_8021Q_VALUE, 93 92 DSA_TAG_PROTO_YT921X = DSA_TAG_PROTO_YT921X_VALUE, 94 93 DSA_TAG_PROTO_MXL_GSW1XX = DSA_TAG_PROTO_MXL_GSW1XX_VALUE, 94 + DSA_TAG_PROTO_MXL862 = DSA_TAG_PROTO_MXL862_VALUE, 95 95 }; 96 96 97 97 struct dsa_switch;
+7
net/dsa/Kconfig
··· 104 104 Say Y or M if you want to enable support for tagging frames for 105 105 Mediatek switches. 106 106 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 + 107 114 config NET_DSA_TAG_MXL_GSW1XX 108 115 tristate "Tag driver for MaxLinear GSW1xx switches" 109 116 help
+1
net/dsa/Makefile
··· 28 28 obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o 29 29 obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o 30 30 obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o 31 + obj-$(CONFIG_NET_DSA_TAG_MXL_862XX) += tag_mxl862xx.o 31 32 obj-$(CONFIG_NET_DSA_TAG_MXL_GSW1XX) += tag_mxl-gsw1xx.o 32 33 obj-$(CONFIG_NET_DSA_TAG_NONE) += tag_none.o 33 34 obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o
+110
net/dsa/tag_mxl862xx.c
··· 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);