~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/dsa/tag_gswip.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 "dsa_priv.h"
 14 
 15 #define GSWIP_TX_HEADER_LEN             4
 16 
 17 /* special tag in TX path header */
 18 /* Byte 0 */
 19 #define GSWIP_TX_SLPID_SHIFT            0       /* source port ID */
 20 #define  GSWIP_TX_SLPID_CPU             2
 21 #define  GSWIP_TX_SLPID_APP1            3
 22 #define  GSWIP_TX_SLPID_APP2            4
 23 #define  GSWIP_TX_SLPID_APP3            5
 24 #define  GSWIP_TX_SLPID_APP4            6
 25 #define  GSWIP_TX_SLPID_APP5            7
 26 
 27 /* Byte 1 */
 28 #define GSWIP_TX_CRCGEN_DIS             BIT(7)
 29 #define GSWIP_TX_DPID_SHIFT             0       /* destination group ID */
 30 #define  GSWIP_TX_DPID_ELAN             0
 31 #define  GSWIP_TX_DPID_EWAN             1
 32 #define  GSWIP_TX_DPID_CPU              2
 33 #define  GSWIP_TX_DPID_APP1             3
 34 #define  GSWIP_TX_DPID_APP2             4
 35 #define  GSWIP_TX_DPID_APP3             5
 36 #define  GSWIP_TX_DPID_APP4             6
 37 #define  GSWIP_TX_DPID_APP5             7
 38 
 39 /* Byte 2 */
 40 #define GSWIP_TX_PORT_MAP_EN            BIT(7)
 41 #define GSWIP_TX_PORT_MAP_SEL           BIT(6)
 42 #define GSWIP_TX_LRN_DIS                BIT(5)
 43 #define GSWIP_TX_CLASS_EN               BIT(4)
 44 #define GSWIP_TX_CLASS_SHIFT            0
 45 #define GSWIP_TX_CLASS_MASK             GENMASK(3, 0)
 46 
 47 /* Byte 3 */
 48 #define GSWIP_TX_DPID_EN                BIT(0)
 49 #define GSWIP_TX_PORT_MAP_SHIFT         1
 50 #define GSWIP_TX_PORT_MAP_MASK          GENMASK(6, 1)
 51 
 52 #define GSWIP_RX_HEADER_LEN     8
 53 
 54 /* special tag in RX path header */
 55 /* Byte 7 */
 56 #define GSWIP_RX_SPPID_SHIFT            4
 57 #define GSWIP_RX_SPPID_MASK             GENMASK(6, 4)
 58 
 59 static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
 60                                       struct net_device *dev)
 61 {
 62         struct dsa_port *dp = dsa_slave_to_port(dev);
 63         int err;
 64         u8 *gswip_tag;
 65 
 66         err = skb_cow_head(skb, GSWIP_TX_HEADER_LEN);
 67         if (err)
 68                 return NULL;
 69 
 70         skb_push(skb, GSWIP_TX_HEADER_LEN);
 71 
 72         gswip_tag = skb->data;
 73         gswip_tag[0] = GSWIP_TX_SLPID_CPU;
 74         gswip_tag[1] = GSWIP_TX_DPID_ELAN;
 75         gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
 76         gswip_tag[3] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
 77         gswip_tag[3] |= GSWIP_TX_DPID_EN;
 78 
 79         return skb;
 80 }
 81 
 82 static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
 83                                      struct net_device *dev,
 84                                      struct packet_type *pt)
 85 {
 86         int port;
 87         u8 *gswip_tag;
 88 
 89         if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
 90                 return NULL;
 91 
 92         gswip_tag = skb->data - ETH_HLEN;
 93 
 94         /* Get source port information */
 95         port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
 96         skb->dev = dsa_master_find_slave(dev, 0, port);
 97         if (!skb->dev)
 98                 return NULL;
 99 
100         /* remove GSWIP tag */
101         skb_pull_rcsum(skb, GSWIP_RX_HEADER_LEN);
102 
103         return skb;
104 }
105 
106 const struct dsa_device_ops gswip_netdev_ops = {
107         .xmit = gswip_tag_xmit,
108         .rcv = gswip_tag_rcv,
109 };
110 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp