1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * net/dsa/tag_ksz.c - Microchip KSZ Switch tag format handling 4 * Copyright (c) 2017 Microchip Technology 5 */ 6 7 #include <linux/etherdevice.h> 8 #include <linux/list.h> 9 #include <linux/slab.h> 10 #include <net/dsa.h> 11 #include "dsa_priv.h" 12 13 /* Typically only one byte is used for tail tag. */ 14 #define KSZ_EGRESS_TAG_LEN 1 15 #define KSZ_INGRESS_TAG_LEN 1 16 17 static struct sk_buff *ksz_common_rcv(struct sk_buff *skb, 18 struct net_device *dev, 19 unsigned int port, unsigned int len) 20 { 21 skb->dev = dsa_master_find_slave(dev, 0, port); 22 if (!skb->dev) 23 return NULL; 24 25 pskb_trim_rcsum(skb, skb->len - len); 26 27 skb->offload_fwd_mark = true; 28 29 return skb; 30 } 31 32 /* 33 * For Ingress (Host -> KSZ8795), 1 byte is added before FCS. 34 * --------------------------------------------------------------------------- 35 * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag(1byte)|FCS(4bytes) 36 * --------------------------------------------------------------------------- 37 * tag : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5) 38 * 39 * For Egress (KSZ8795 -> Host), 1 byte is added before FCS. 40 * --------------------------------------------------------------------------- 41 * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes) 42 * --------------------------------------------------------------------------- 43 * tag0 : zero-based value represents port 44 * (eg, 0x00=port1, 0x02=port3, 0x06=port7) 45 */ 46 47 #define KSZ8795_TAIL_TAG_OVERRIDE BIT(6) 48 #define KSZ8795_TAIL_TAG_LOOKUP BIT(7) 49 50 static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev) 51 { 52 struct dsa_port *dp = dsa_slave_to_port(dev); 53 u8 *tag; 54 u8 *addr; 55 56 if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) 57 return NULL; 58 59 /* Tag encoding */ 60 tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); 61 addr = skb_mac_header(skb); 62 63 *tag = 1 << dp->index; 64 if (is_link_local_ether_addr(addr)) 65 *tag |= KSZ8795_TAIL_TAG_OVERRIDE; 66 67 return skb; 68 } 69 70 static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev, 71 struct packet_type *pt) 72 { 73 u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; 74 75 return ksz_common_rcv(skb, dev, tag[0] & 7, KSZ_EGRESS_TAG_LEN); 76 } 77 78 static const struct dsa_device_ops ksz8795_netdev_ops = { 79 .name = "ksz8795", 80 .proto = DSA_TAG_PROTO_KSZ8795, 81 .xmit = ksz8795_xmit, 82 .rcv = ksz8795_rcv, 83 .needed_tailroom = KSZ_INGRESS_TAG_LEN, 84 }; 85 86 DSA_TAG_DRIVER(ksz8795_netdev_ops); 87 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ8795); 88 89 /* 90 * For Ingress (Host -> KSZ9477), 2 bytes are added before FCS. 91 * --------------------------------------------------------------------------- 92 * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) 93 * --------------------------------------------------------------------------- 94 * tag0 : Prioritization (not used now) 95 * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5) 96 * 97 * For Egress (KSZ9477 -> Host), 1 byte is added before FCS. 98 * --------------------------------------------------------------------------- 99 * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes) 100 * --------------------------------------------------------------------------- 101 * tag0 : zero-based value represents port 102 * (eg, 0x00=port1, 0x02=port3, 0x06=port7) 103 */ 104 105 #define KSZ9477_INGRESS_TAG_LEN 2 106 #define KSZ9477_PTP_TAG_LEN 4 107 #define KSZ9477_PTP_TAG_INDICATION 0x80 108 109 #define KSZ9477_TAIL_TAG_OVERRIDE BIT(9) 110 #define KSZ9477_TAIL_TAG_LOOKUP BIT(10) 111 112 static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, 113 struct net_device *dev) 114 { 115 struct dsa_port *dp = dsa_slave_to_port(dev); 116 __be16 *tag; 117 u8 *addr; 118 u16 val; 119 120 if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) 121 return NULL; 122 123 /* Tag encoding */ 124 tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); 125 addr = skb_mac_header(skb); 126 127 val = BIT(dp->index); 128 129 if (is_link_local_ether_addr(addr)) 130 val |= KSZ9477_TAIL_TAG_OVERRIDE; 131 132 *tag = cpu_to_be16(val); 133 134 return skb; 135 } 136 137 static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev, 138 struct packet_type *pt) 139 { 140 /* Tag decoding */ 141 u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; 142 unsigned int port = tag[0] & 7; 143 unsigned int len = KSZ_EGRESS_TAG_LEN; 144 145 /* Extra 4-bytes PTP timestamp */ 146 if (tag[0] & KSZ9477_PTP_TAG_INDICATION) 147 len += KSZ9477_PTP_TAG_LEN; 148 149 return ksz_common_rcv(skb, dev, port, len); 150 } 151 152 static const struct dsa_device_ops ksz9477_netdev_ops = { 153 .name = "ksz9477", 154 .proto = DSA_TAG_PROTO_KSZ9477, 155 .xmit = ksz9477_xmit, 156 .rcv = ksz9477_rcv, 157 .needed_tailroom = KSZ9477_INGRESS_TAG_LEN, 158 }; 159 160 DSA_TAG_DRIVER(ksz9477_netdev_ops); 161 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9477); 162 163 #define KSZ9893_TAIL_TAG_OVERRIDE BIT(5) 164 #define KSZ9893_TAIL_TAG_LOOKUP BIT(6) 165 166 static struct sk_buff *ksz9893_xmit(struct sk_buff *skb, 167 struct net_device *dev) 168 { 169 struct dsa_port *dp = dsa_slave_to_port(dev); 170 u8 *addr; 171 u8 *tag; 172 173 if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) 174 return NULL; 175 176 /* Tag encoding */ 177 tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); 178 addr = skb_mac_header(skb); 179 180 *tag = BIT(dp->index); 181 182 if (is_link_local_ether_addr(addr)) 183 *tag |= KSZ9893_TAIL_TAG_OVERRIDE; 184 185 return skb; 186 } 187 188 static const struct dsa_device_ops ksz9893_netdev_ops = { 189 .name = "ksz9893", 190 .proto = DSA_TAG_PROTO_KSZ9893, 191 .xmit = ksz9893_xmit, 192 .rcv = ksz9477_rcv, 193 .needed_tailroom = KSZ_INGRESS_TAG_LEN, 194 }; 195 196 DSA_TAG_DRIVER(ksz9893_netdev_ops); 197 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893); 198 199 static struct dsa_tag_driver *dsa_tag_driver_array[] = { 200 &DSA_TAG_DRIVER_NAME(ksz8795_netdev_ops), 201 &DSA_TAG_DRIVER_NAME(ksz9477_netdev_ops), 202 &DSA_TAG_DRIVER_NAME(ksz9893_netdev_ops), 203 }; 204 205 module_dsa_tag_drivers(dsa_tag_driver_array); 206 207 MODULE_LICENSE("GPL"); 208