0001
0002
0003
0004
0005
0006
0007 #include <linux/bitfield.h>
0008 #include <linux/etherdevice.h>
0009
0010 #include "dsa_priv.h"
0011
0012 #define AR9331_HDR_LEN 2
0013 #define AR9331_HDR_VERSION 1
0014
0015 #define AR9331_HDR_VERSION_MASK GENMASK(15, 14)
0016 #define AR9331_HDR_PRIORITY_MASK GENMASK(13, 12)
0017 #define AR9331_HDR_TYPE_MASK GENMASK(10, 8)
0018 #define AR9331_HDR_BROADCAST BIT(7)
0019 #define AR9331_HDR_FROM_CPU BIT(6)
0020
0021
0022
0023
0024 #define AR9331_HDR_RESERVED_MASK GENMASK(5, 4)
0025 #define AR9331_HDR_PORT_NUM_MASK GENMASK(3, 0)
0026
0027 static struct sk_buff *ar9331_tag_xmit(struct sk_buff *skb,
0028 struct net_device *dev)
0029 {
0030 struct dsa_port *dp = dsa_slave_to_port(dev);
0031 __le16 *phdr;
0032 u16 hdr;
0033
0034 phdr = skb_push(skb, AR9331_HDR_LEN);
0035
0036 hdr = FIELD_PREP(AR9331_HDR_VERSION_MASK, AR9331_HDR_VERSION);
0037 hdr |= AR9331_HDR_FROM_CPU | dp->index;
0038
0039 hdr |= AR9331_HDR_RESERVED_MASK;
0040
0041 phdr[0] = cpu_to_le16(hdr);
0042
0043 return skb;
0044 }
0045
0046 static struct sk_buff *ar9331_tag_rcv(struct sk_buff *skb,
0047 struct net_device *ndev)
0048 {
0049 u8 ver, port;
0050 u16 hdr;
0051
0052 if (unlikely(!pskb_may_pull(skb, AR9331_HDR_LEN)))
0053 return NULL;
0054
0055 hdr = le16_to_cpu(*(__le16 *)skb_mac_header(skb));
0056
0057 ver = FIELD_GET(AR9331_HDR_VERSION_MASK, hdr);
0058 if (unlikely(ver != AR9331_HDR_VERSION)) {
0059 netdev_warn_once(ndev, "%s:%i wrong header version 0x%2x\n",
0060 __func__, __LINE__, hdr);
0061 return NULL;
0062 }
0063
0064 if (unlikely(hdr & AR9331_HDR_FROM_CPU)) {
0065 netdev_warn_once(ndev, "%s:%i packet should not be from cpu 0x%2x\n",
0066 __func__, __LINE__, hdr);
0067 return NULL;
0068 }
0069
0070 skb_pull_rcsum(skb, AR9331_HDR_LEN);
0071
0072
0073 port = FIELD_GET(AR9331_HDR_PORT_NUM_MASK, hdr);
0074
0075 skb->dev = dsa_master_find_slave(ndev, 0, port);
0076 if (!skb->dev)
0077 return NULL;
0078
0079 return skb;
0080 }
0081
0082 static const struct dsa_device_ops ar9331_netdev_ops = {
0083 .name = "ar9331",
0084 .proto = DSA_TAG_PROTO_AR9331,
0085 .xmit = ar9331_tag_xmit,
0086 .rcv = ar9331_tag_rcv,
0087 .needed_headroom = AR9331_HDR_LEN,
0088 };
0089
0090 MODULE_LICENSE("GPL v2");
0091 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_AR9331);
0092 module_dsa_tag_driver(ar9331_netdev_ops);