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

net: dsa: tag_ksz: add tag handling for Microchip LAN937x

The Microchip LAN937X switches have a tagging protocol which is
very similar to KSZ tagging. So that the implementation is added to
tag_ksz.c and reused common APIs

Signed-off-by: Prasanna Vengateshan <prasanna.vengateshan@microchip.com>
Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Prasanna Vengateshan and committed by
David S. Miller
092f8751 8926d94e

+63 -2
+2
include/net/dsa.h
··· 54 54 #define DSA_TAG_PROTO_RTL8_4_VALUE 24 55 55 #define DSA_TAG_PROTO_RTL8_4T_VALUE 25 56 56 #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26 57 + #define DSA_TAG_PROTO_LAN937X_VALUE 27 57 58 58 59 enum dsa_tag_protocol { 59 60 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, ··· 84 83 DSA_TAG_PROTO_RTL8_4 = DSA_TAG_PROTO_RTL8_4_VALUE, 85 84 DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE, 86 85 DSA_TAG_PROTO_RZN1_A5PSW = DSA_TAG_PROTO_RZN1_A5PSW_VALUE, 86 + DSA_TAG_PROTO_LAN937X = DSA_TAG_PROTO_LAN937X_VALUE, 87 87 }; 88 88 89 89 struct dsa_switch;
+2 -2
net/dsa/Kconfig
··· 87 87 Mediatek switches. 88 88 89 89 config NET_DSA_TAG_KSZ 90 - tristate "Tag driver for Microchip 8795/9477/9893 families of switches" 90 + tristate "Tag driver for Microchip 8795/937x/9477/9893 families of switches" 91 91 help 92 92 Say Y if you want to enable support for tagging frames for the 93 - Microchip 8795/9477/9893 families of switches. 93 + Microchip 8795/937x/9477/9893 families of switches. 94 94 95 95 config NET_DSA_TAG_OCELOT 96 96 tristate "Tag driver for Ocelot family of switches, using NPI port"
+59
net/dsa/tag_ksz.c
··· 193 193 DSA_TAG_DRIVER(ksz9893_netdev_ops); 194 194 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893); 195 195 196 + /* For xmit, 2 bytes are added before FCS. 197 + * --------------------------------------------------------------------------- 198 + * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) 199 + * --------------------------------------------------------------------------- 200 + * tag0 : represents tag override, lookup and valid 201 + * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x80=port8) 202 + * 203 + * For rcv, 1 byte is added before FCS. 204 + * --------------------------------------------------------------------------- 205 + * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes) 206 + * --------------------------------------------------------------------------- 207 + * tag0 : zero-based value represents port 208 + * (eg, 0x00=port1, 0x02=port3, 0x07=port8) 209 + */ 210 + #define LAN937X_EGRESS_TAG_LEN 2 211 + 212 + #define LAN937X_TAIL_TAG_BLOCKING_OVERRIDE BIT(11) 213 + #define LAN937X_TAIL_TAG_LOOKUP BIT(12) 214 + #define LAN937X_TAIL_TAG_VALID BIT(13) 215 + #define LAN937X_TAIL_TAG_PORT_MASK 7 216 + 217 + static struct sk_buff *lan937x_xmit(struct sk_buff *skb, 218 + struct net_device *dev) 219 + { 220 + struct dsa_port *dp = dsa_slave_to_port(dev); 221 + const struct ethhdr *hdr = eth_hdr(skb); 222 + __be16 *tag; 223 + u16 val; 224 + 225 + if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) 226 + return NULL; 227 + 228 + tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN); 229 + 230 + val = BIT(dp->index); 231 + 232 + if (is_link_local_ether_addr(hdr->h_dest)) 233 + val |= LAN937X_TAIL_TAG_BLOCKING_OVERRIDE; 234 + 235 + /* Tail tag valid bit - This bit should always be set by the CPU */ 236 + val |= LAN937X_TAIL_TAG_VALID; 237 + 238 + put_unaligned_be16(val, tag); 239 + 240 + return skb; 241 + } 242 + 243 + static const struct dsa_device_ops lan937x_netdev_ops = { 244 + .name = "lan937x", 245 + .proto = DSA_TAG_PROTO_LAN937X, 246 + .xmit = lan937x_xmit, 247 + .rcv = ksz9477_rcv, 248 + .needed_tailroom = LAN937X_EGRESS_TAG_LEN, 249 + }; 250 + 251 + DSA_TAG_DRIVER(lan937x_netdev_ops); 252 + MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN937X); 253 + 196 254 static struct dsa_tag_driver *dsa_tag_driver_array[] = { 197 255 &DSA_TAG_DRIVER_NAME(ksz8795_netdev_ops), 198 256 &DSA_TAG_DRIVER_NAME(ksz9477_netdev_ops), 199 257 &DSA_TAG_DRIVER_NAME(ksz9893_netdev_ops), 258 + &DSA_TAG_DRIVER_NAME(lan937x_netdev_ops), 200 259 }; 201 260 202 261 module_dsa_tag_drivers(dsa_tag_driver_array);