Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * net/dsa/tag_ksz.c - Microchip KSZ Switch tag format handling
0004  * Copyright (c) 2017 Microchip Technology
0005  */
0006 
0007 #include <linux/etherdevice.h>
0008 #include <linux/list.h>
0009 #include <net/dsa.h>
0010 #include "dsa_priv.h"
0011 
0012 /* Typically only one byte is used for tail tag. */
0013 #define KSZ_EGRESS_TAG_LEN      1
0014 #define KSZ_INGRESS_TAG_LEN     1
0015 
0016 static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
0017                       struct net_device *dev,
0018                       unsigned int port, unsigned int len)
0019 {
0020     skb->dev = dsa_master_find_slave(dev, 0, port);
0021     if (!skb->dev)
0022         return NULL;
0023 
0024     pskb_trim_rcsum(skb, skb->len - len);
0025 
0026     dsa_default_offload_fwd_mark(skb);
0027 
0028     return skb;
0029 }
0030 
0031 /*
0032  * For Ingress (Host -> KSZ8795), 1 byte is added before FCS.
0033  * ---------------------------------------------------------------------------
0034  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag(1byte)|FCS(4bytes)
0035  * ---------------------------------------------------------------------------
0036  * tag : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
0037  *
0038  * For Egress (KSZ8795 -> Host), 1 byte is added before FCS.
0039  * ---------------------------------------------------------------------------
0040  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
0041  * ---------------------------------------------------------------------------
0042  * tag0 : zero-based value represents port
0043  *    (eg, 0x00=port1, 0x02=port3, 0x06=port7)
0044  */
0045 
0046 #define KSZ8795_TAIL_TAG_OVERRIDE   BIT(6)
0047 #define KSZ8795_TAIL_TAG_LOOKUP     BIT(7)
0048 
0049 static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
0050 {
0051     struct dsa_port *dp = dsa_slave_to_port(dev);
0052     u8 *tag;
0053     u8 *addr;
0054 
0055     if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
0056         return NULL;
0057 
0058     /* Tag encoding */
0059     tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
0060     addr = skb_mac_header(skb);
0061 
0062     *tag = 1 << dp->index;
0063     if (is_link_local_ether_addr(addr))
0064         *tag |= KSZ8795_TAIL_TAG_OVERRIDE;
0065 
0066     return skb;
0067 }
0068 
0069 static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev)
0070 {
0071     u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
0072 
0073     return ksz_common_rcv(skb, dev, tag[0] & 7, KSZ_EGRESS_TAG_LEN);
0074 }
0075 
0076 static const struct dsa_device_ops ksz8795_netdev_ops = {
0077     .name   = "ksz8795",
0078     .proto  = DSA_TAG_PROTO_KSZ8795,
0079     .xmit   = ksz8795_xmit,
0080     .rcv    = ksz8795_rcv,
0081     .needed_tailroom = KSZ_INGRESS_TAG_LEN,
0082 };
0083 
0084 DSA_TAG_DRIVER(ksz8795_netdev_ops);
0085 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ8795);
0086 
0087 /*
0088  * For Ingress (Host -> KSZ9477), 2 bytes are added before FCS.
0089  * ---------------------------------------------------------------------------
0090  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
0091  * ---------------------------------------------------------------------------
0092  * tag0 : Prioritization (not used now)
0093  * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
0094  *
0095  * For Egress (KSZ9477 -> Host), 1 byte is added before FCS.
0096  * ---------------------------------------------------------------------------
0097  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
0098  * ---------------------------------------------------------------------------
0099  * tag0 : zero-based value represents port
0100  *    (eg, 0x00=port1, 0x02=port3, 0x06=port7)
0101  */
0102 
0103 #define KSZ9477_INGRESS_TAG_LEN     2
0104 #define KSZ9477_PTP_TAG_LEN     4
0105 #define KSZ9477_PTP_TAG_INDICATION  0x80
0106 
0107 #define KSZ9477_TAIL_TAG_OVERRIDE   BIT(9)
0108 #define KSZ9477_TAIL_TAG_LOOKUP     BIT(10)
0109 
0110 static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
0111                     struct net_device *dev)
0112 {
0113     struct dsa_port *dp = dsa_slave_to_port(dev);
0114     __be16 *tag;
0115     u8 *addr;
0116     u16 val;
0117 
0118     if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
0119         return NULL;
0120 
0121     /* Tag encoding */
0122     tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN);
0123     addr = skb_mac_header(skb);
0124 
0125     val = BIT(dp->index);
0126 
0127     if (is_link_local_ether_addr(addr))
0128         val |= KSZ9477_TAIL_TAG_OVERRIDE;
0129 
0130     *tag = cpu_to_be16(val);
0131 
0132     return skb;
0133 }
0134 
0135 static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev)
0136 {
0137     /* Tag decoding */
0138     u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
0139     unsigned int port = tag[0] & 7;
0140     unsigned int len = KSZ_EGRESS_TAG_LEN;
0141 
0142     /* Extra 4-bytes PTP timestamp */
0143     if (tag[0] & KSZ9477_PTP_TAG_INDICATION)
0144         len += KSZ9477_PTP_TAG_LEN;
0145 
0146     return ksz_common_rcv(skb, dev, port, len);
0147 }
0148 
0149 static const struct dsa_device_ops ksz9477_netdev_ops = {
0150     .name   = "ksz9477",
0151     .proto  = DSA_TAG_PROTO_KSZ9477,
0152     .xmit   = ksz9477_xmit,
0153     .rcv    = ksz9477_rcv,
0154     .needed_tailroom = KSZ9477_INGRESS_TAG_LEN,
0155 };
0156 
0157 DSA_TAG_DRIVER(ksz9477_netdev_ops);
0158 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9477);
0159 
0160 #define KSZ9893_TAIL_TAG_OVERRIDE   BIT(5)
0161 #define KSZ9893_TAIL_TAG_LOOKUP     BIT(6)
0162 
0163 static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
0164                     struct net_device *dev)
0165 {
0166     struct dsa_port *dp = dsa_slave_to_port(dev);
0167     u8 *addr;
0168     u8 *tag;
0169 
0170     if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
0171         return NULL;
0172 
0173     /* Tag encoding */
0174     tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
0175     addr = skb_mac_header(skb);
0176 
0177     *tag = BIT(dp->index);
0178 
0179     if (is_link_local_ether_addr(addr))
0180         *tag |= KSZ9893_TAIL_TAG_OVERRIDE;
0181 
0182     return skb;
0183 }
0184 
0185 static const struct dsa_device_ops ksz9893_netdev_ops = {
0186     .name   = "ksz9893",
0187     .proto  = DSA_TAG_PROTO_KSZ9893,
0188     .xmit   = ksz9893_xmit,
0189     .rcv    = ksz9477_rcv,
0190     .needed_tailroom = KSZ_INGRESS_TAG_LEN,
0191 };
0192 
0193 DSA_TAG_DRIVER(ksz9893_netdev_ops);
0194 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893);
0195 
0196 /* For xmit, 2 bytes are added before FCS.
0197  * ---------------------------------------------------------------------------
0198  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
0199  * ---------------------------------------------------------------------------
0200  * tag0 : represents tag override, lookup and valid
0201  * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x80=port8)
0202  *
0203  * For rcv, 1 byte is added before FCS.
0204  * ---------------------------------------------------------------------------
0205  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
0206  * ---------------------------------------------------------------------------
0207  * tag0 : zero-based value represents port
0208  *    (eg, 0x00=port1, 0x02=port3, 0x07=port8)
0209  */
0210 #define LAN937X_EGRESS_TAG_LEN      2
0211 
0212 #define LAN937X_TAIL_TAG_BLOCKING_OVERRIDE  BIT(11)
0213 #define LAN937X_TAIL_TAG_LOOKUP         BIT(12)
0214 #define LAN937X_TAIL_TAG_VALID          BIT(13)
0215 #define LAN937X_TAIL_TAG_PORT_MASK      7
0216 
0217 static struct sk_buff *lan937x_xmit(struct sk_buff *skb,
0218                     struct net_device *dev)
0219 {
0220     struct dsa_port *dp = dsa_slave_to_port(dev);
0221     const struct ethhdr *hdr = eth_hdr(skb);
0222     __be16 *tag;
0223     u16 val;
0224 
0225     if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
0226         return NULL;
0227 
0228     tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN);
0229 
0230     val = BIT(dp->index);
0231 
0232     if (is_link_local_ether_addr(hdr->h_dest))
0233         val |= LAN937X_TAIL_TAG_BLOCKING_OVERRIDE;
0234 
0235     /* Tail tag valid bit - This bit should always be set by the CPU */
0236     val |= LAN937X_TAIL_TAG_VALID;
0237 
0238     put_unaligned_be16(val, tag);
0239 
0240     return skb;
0241 }
0242 
0243 static const struct dsa_device_ops lan937x_netdev_ops = {
0244     .name   = "lan937x",
0245     .proto  = DSA_TAG_PROTO_LAN937X,
0246     .xmit   = lan937x_xmit,
0247     .rcv    = ksz9477_rcv,
0248     .needed_tailroom = LAN937X_EGRESS_TAG_LEN,
0249 };
0250 
0251 DSA_TAG_DRIVER(lan937x_netdev_ops);
0252 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN937X);
0253 
0254 static struct dsa_tag_driver *dsa_tag_driver_array[] = {
0255     &DSA_TAG_DRIVER_NAME(ksz8795_netdev_ops),
0256     &DSA_TAG_DRIVER_NAME(ksz9477_netdev_ops),
0257     &DSA_TAG_DRIVER_NAME(ksz9893_netdev_ops),
0258     &DSA_TAG_DRIVER_NAME(lan937x_netdev_ops),
0259 };
0260 
0261 module_dsa_tag_drivers(dsa_tag_driver_array);
0262 
0263 MODULE_LICENSE("GPL");