0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitops.h>
0009 #include <linux/etherdevice.h>
0010 #include <linux/skbuff.h>
0011 #include <net/dsa.h>
0012
0013 #include "dsa_priv.h"
0014
0015 #define GSWIP_TX_HEADER_LEN 4
0016
0017
0018
0019 #define GSWIP_TX_SLPID_SHIFT 0
0020 #define GSWIP_TX_SLPID_CPU 2
0021 #define GSWIP_TX_SLPID_APP1 3
0022 #define GSWIP_TX_SLPID_APP2 4
0023 #define GSWIP_TX_SLPID_APP3 5
0024 #define GSWIP_TX_SLPID_APP4 6
0025 #define GSWIP_TX_SLPID_APP5 7
0026
0027
0028 #define GSWIP_TX_CRCGEN_DIS BIT(7)
0029 #define GSWIP_TX_DPID_SHIFT 0
0030 #define GSWIP_TX_DPID_ELAN 0
0031 #define GSWIP_TX_DPID_EWAN 1
0032 #define GSWIP_TX_DPID_CPU 2
0033 #define GSWIP_TX_DPID_APP1 3
0034 #define GSWIP_TX_DPID_APP2 4
0035 #define GSWIP_TX_DPID_APP3 5
0036 #define GSWIP_TX_DPID_APP4 6
0037 #define GSWIP_TX_DPID_APP5 7
0038
0039
0040 #define GSWIP_TX_PORT_MAP_EN BIT(7)
0041 #define GSWIP_TX_PORT_MAP_SEL BIT(6)
0042 #define GSWIP_TX_LRN_DIS BIT(5)
0043 #define GSWIP_TX_CLASS_EN BIT(4)
0044 #define GSWIP_TX_CLASS_SHIFT 0
0045 #define GSWIP_TX_CLASS_MASK GENMASK(3, 0)
0046
0047
0048 #define GSWIP_TX_DPID_EN BIT(0)
0049 #define GSWIP_TX_PORT_MAP_SHIFT 1
0050 #define GSWIP_TX_PORT_MAP_MASK GENMASK(6, 1)
0051
0052 #define GSWIP_RX_HEADER_LEN 8
0053
0054
0055
0056 #define GSWIP_RX_SPPID_SHIFT 4
0057 #define GSWIP_RX_SPPID_MASK GENMASK(6, 4)
0058
0059 static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
0060 struct net_device *dev)
0061 {
0062 struct dsa_port *dp = dsa_slave_to_port(dev);
0063 u8 *gswip_tag;
0064
0065 skb_push(skb, GSWIP_TX_HEADER_LEN);
0066
0067 gswip_tag = skb->data;
0068 gswip_tag[0] = GSWIP_TX_SLPID_CPU;
0069 gswip_tag[1] = GSWIP_TX_DPID_ELAN;
0070 gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
0071 gswip_tag[3] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
0072 gswip_tag[3] |= GSWIP_TX_DPID_EN;
0073
0074 return skb;
0075 }
0076
0077 static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
0078 struct net_device *dev)
0079 {
0080 int port;
0081 u8 *gswip_tag;
0082
0083 if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
0084 return NULL;
0085
0086 gswip_tag = skb->data - ETH_HLEN;
0087
0088
0089 port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
0090 skb->dev = dsa_master_find_slave(dev, 0, port);
0091 if (!skb->dev)
0092 return NULL;
0093
0094
0095 skb_pull_rcsum(skb, GSWIP_RX_HEADER_LEN);
0096
0097 return skb;
0098 }
0099
0100 static const struct dsa_device_ops gswip_netdev_ops = {
0101 .name = "gswip",
0102 .proto = DSA_TAG_PROTO_GSWIP,
0103 .xmit = gswip_tag_xmit,
0104 .rcv = gswip_tag_rcv,
0105 .needed_headroom = GSWIP_RX_HEADER_LEN,
0106 };
0107
0108 MODULE_LICENSE("GPL");
0109 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP);
0110
0111 module_dsa_tag_driver(gswip_netdev_ops);