netfilter: add missing module descriptions
[linux-2.6-microblaze.git] / net / dsa / tag_gswip.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel / Lantiq GSWIP V2.0 PMAC tag support
4  *
5  * Copyright (C) 2017 - 2018 Hauke Mehrtens <hauke@hauke-m.de>
6  */
7
8 #include <linux/bitops.h>
9 #include <linux/etherdevice.h>
10 #include <linux/skbuff.h>
11 #include <net/dsa.h>
12
13 #include "tag.h"
14
15 #define GSWIP_NAME                      "gswip"
16
17 #define GSWIP_TX_HEADER_LEN             4
18
19 /* special tag in TX path header */
20 /* Byte 0 */
21 #define GSWIP_TX_SLPID_SHIFT            0       /* source port ID */
22 #define  GSWIP_TX_SLPID_CPU             2
23 #define  GSWIP_TX_SLPID_APP1            3
24 #define  GSWIP_TX_SLPID_APP2            4
25 #define  GSWIP_TX_SLPID_APP3            5
26 #define  GSWIP_TX_SLPID_APP4            6
27 #define  GSWIP_TX_SLPID_APP5            7
28
29 /* Byte 1 */
30 #define GSWIP_TX_CRCGEN_DIS             BIT(7)
31 #define GSWIP_TX_DPID_SHIFT             0       /* destination group ID */
32 #define  GSWIP_TX_DPID_ELAN             0
33 #define  GSWIP_TX_DPID_EWAN             1
34 #define  GSWIP_TX_DPID_CPU              2
35 #define  GSWIP_TX_DPID_APP1             3
36 #define  GSWIP_TX_DPID_APP2             4
37 #define  GSWIP_TX_DPID_APP3             5
38 #define  GSWIP_TX_DPID_APP4             6
39 #define  GSWIP_TX_DPID_APP5             7
40
41 /* Byte 2 */
42 #define GSWIP_TX_PORT_MAP_EN            BIT(7)
43 #define GSWIP_TX_PORT_MAP_SEL           BIT(6)
44 #define GSWIP_TX_LRN_DIS                BIT(5)
45 #define GSWIP_TX_CLASS_EN               BIT(4)
46 #define GSWIP_TX_CLASS_SHIFT            0
47 #define GSWIP_TX_CLASS_MASK             GENMASK(3, 0)
48
49 /* Byte 3 */
50 #define GSWIP_TX_DPID_EN                BIT(0)
51 #define GSWIP_TX_PORT_MAP_SHIFT         1
52 #define GSWIP_TX_PORT_MAP_MASK          GENMASK(6, 1)
53
54 #define GSWIP_RX_HEADER_LEN     8
55
56 /* special tag in RX path header */
57 /* Byte 7 */
58 #define GSWIP_RX_SPPID_SHIFT            4
59 #define GSWIP_RX_SPPID_MASK             GENMASK(6, 4)
60
61 static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
62                                       struct net_device *dev)
63 {
64         struct dsa_port *dp = dsa_user_to_port(dev);
65         u8 *gswip_tag;
66
67         skb_push(skb, GSWIP_TX_HEADER_LEN);
68
69         gswip_tag = skb->data;
70         gswip_tag[0] = GSWIP_TX_SLPID_CPU;
71         gswip_tag[1] = GSWIP_TX_DPID_ELAN;
72         gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
73         gswip_tag[3] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
74         gswip_tag[3] |= GSWIP_TX_DPID_EN;
75
76         return skb;
77 }
78
79 static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
80                                      struct net_device *dev)
81 {
82         int port;
83         u8 *gswip_tag;
84
85         if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
86                 return NULL;
87
88         gswip_tag = skb->data - ETH_HLEN;
89
90         /* Get source port information */
91         port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
92         skb->dev = dsa_conduit_find_user(dev, 0, port);
93         if (!skb->dev)
94                 return NULL;
95
96         /* remove GSWIP tag */
97         skb_pull_rcsum(skb, GSWIP_RX_HEADER_LEN);
98
99         return skb;
100 }
101
102 static const struct dsa_device_ops gswip_netdev_ops = {
103         .name = GSWIP_NAME,
104         .proto  = DSA_TAG_PROTO_GSWIP,
105         .xmit = gswip_tag_xmit,
106         .rcv = gswip_tag_rcv,
107         .needed_headroom = GSWIP_RX_HEADER_LEN,
108 };
109
110 MODULE_LICENSE("GPL");
111 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP, GSWIP_NAME);
112
113 module_dsa_tag_driver(gswip_netdev_ops);