root/net/dsa/tag_gswip.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gswip_tag_xmit
  2. gswip_tag_rcv

   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 static const struct dsa_device_ops gswip_netdev_ops = {
 107         .name = "gswip",
 108         .proto  = DSA_TAG_PROTO_GSWIP,
 109         .xmit = gswip_tag_xmit,
 110         .rcv = gswip_tag_rcv,
 111         .overhead = GSWIP_RX_HEADER_LEN,
 112 };
 113 
 114 MODULE_LICENSE("GPL");
 115 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP);
 116 
 117 module_dsa_tag_driver(gswip_netdev_ops);

/* [<][>][^][v][top][bottom][index][help] */