This source file includes following definitions.
- brcm_tag_xmit_ll
- brcm_tag_rcv_ll
- brcm_tag_xmit
- brcm_tag_rcv
- brcm_tag_xmit_prepend
- brcm_tag_rcv_prepend
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include <linux/etherdevice.h>
   9 #include <linux/list.h>
  10 #include <linux/slab.h>
  11 
  12 #include "dsa_priv.h"
  13 
  14 
  15 
  16 
  17 #define BRCM_TAG_LEN    4
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 #define BRCM_OPCODE_SHIFT       5
  27 #define BRCM_OPCODE_MASK        0x7
  28 
  29 
  30 
  31 #define BRCM_IG_TC_SHIFT        2
  32 #define BRCM_IG_TC_MASK         0x7
  33 
  34 #define BRCM_IG_TE_MASK         0x3
  35 #define BRCM_IG_TS_SHIFT        7
  36 
  37 #define BRCM_IG_DSTMAP2_MASK    1
  38 #define BRCM_IG_DSTMAP1_MASK    0xff
  39 
  40 
  41 
  42 
  43 #define BRCM_EG_CID_MASK        0xff
  44 
  45 
  46 #define BRCM_EG_RC_MASK         0xff
  47 #define  BRCM_EG_RC_RSVD        (3 << 6)
  48 #define  BRCM_EG_RC_EXCEPTION   (1 << 5)
  49 #define  BRCM_EG_RC_PROT_SNOOP  (1 << 4)
  50 #define  BRCM_EG_RC_PROT_TERM   (1 << 3)
  51 #define  BRCM_EG_RC_SWITCH      (1 << 2)
  52 #define  BRCM_EG_RC_MAC_LEARN   (1 << 1)
  53 #define  BRCM_EG_RC_MIRROR      (1 << 0)
  54 #define BRCM_EG_TC_SHIFT        5
  55 #define BRCM_EG_TC_MASK         0x7
  56 #define BRCM_EG_PID_MASK        0x1f
  57 
  58 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM) || \
  59         IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
  60 
  61 static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
  62                                         struct net_device *dev,
  63                                         unsigned int offset)
  64 {
  65         struct dsa_port *dp = dsa_slave_to_port(dev);
  66         u16 queue = skb_get_queue_mapping(skb);
  67         u8 *brcm_tag;
  68 
  69         if (skb_cow_head(skb, BRCM_TAG_LEN) < 0)
  70                 return NULL;
  71 
  72         
  73 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81         if (__skb_put_padto(skb, ETH_ZLEN + BRCM_TAG_LEN, false))
  82                 return NULL;
  83 
  84         skb_push(skb, BRCM_TAG_LEN);
  85 
  86         if (offset)
  87                 memmove(skb->data, skb->data + BRCM_TAG_LEN, offset);
  88 
  89         brcm_tag = skb->data + offset;
  90 
  91         
  92 
  93 
  94         brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) |
  95                        ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT);
  96         brcm_tag[1] = 0;
  97         brcm_tag[2] = 0;
  98         if (dp->index == 8)
  99                 brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
 100         brcm_tag[3] = (1 << dp->index) & BRCM_IG_DSTMAP1_MASK;
 101 
 102         
 103 
 104 
 105         skb_set_queue_mapping(skb, BRCM_TAG_SET_PORT_QUEUE(dp->index, queue));
 106 
 107         return skb;
 108 }
 109 
 110 static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
 111                                        struct net_device *dev,
 112                                        struct packet_type *pt,
 113                                        unsigned int offset)
 114 {
 115         int source_port;
 116         u8 *brcm_tag;
 117 
 118         if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN)))
 119                 return NULL;
 120 
 121         brcm_tag = skb->data - offset;
 122 
 123         
 124         if (unlikely((brcm_tag[0] >> BRCM_OPCODE_SHIFT) & BRCM_OPCODE_MASK))
 125                 return NULL;
 126 
 127         
 128 
 129 
 130         if (unlikely(brcm_tag[2] & BRCM_EG_RC_RSVD))
 131                 return NULL;
 132 
 133         
 134         source_port = brcm_tag[3] & BRCM_EG_PID_MASK;
 135 
 136         skb->dev = dsa_master_find_slave(dev, 0, source_port);
 137         if (!skb->dev)
 138                 return NULL;
 139 
 140         
 141         skb_pull_rcsum(skb, BRCM_TAG_LEN);
 142 
 143         skb->offload_fwd_mark = 1;
 144 
 145         return skb;
 146 }
 147 #endif
 148 
 149 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
 150 static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb,
 151                                      struct net_device *dev)
 152 {
 153         
 154         return brcm_tag_xmit_ll(skb, dev, 2 * ETH_ALEN);
 155 }
 156 
 157 
 158 static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
 159                                     struct packet_type *pt)
 160 {
 161         struct sk_buff *nskb;
 162 
 163         
 164         nskb = brcm_tag_rcv_ll(skb, dev, pt, 2);
 165         if (!nskb)
 166                 return nskb;
 167 
 168         
 169         memmove(nskb->data - ETH_HLEN,
 170                 nskb->data - ETH_HLEN - BRCM_TAG_LEN,
 171                 2 * ETH_ALEN);
 172 
 173         return nskb;
 174 }
 175 
 176 static const struct dsa_device_ops brcm_netdev_ops = {
 177         .name   = "brcm",
 178         .proto  = DSA_TAG_PROTO_BRCM,
 179         .xmit   = brcm_tag_xmit,
 180         .rcv    = brcm_tag_rcv,
 181         .overhead = BRCM_TAG_LEN,
 182 };
 183 
 184 DSA_TAG_DRIVER(brcm_netdev_ops);
 185 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
 186 #endif
 187 
 188 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
 189 static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
 190                                              struct net_device *dev)
 191 {
 192         
 193         return brcm_tag_xmit_ll(skb, dev, 0);
 194 }
 195 
 196 static struct sk_buff *brcm_tag_rcv_prepend(struct sk_buff *skb,
 197                                             struct net_device *dev,
 198                                             struct packet_type *pt)
 199 {
 200         
 201         return brcm_tag_rcv_ll(skb, dev, pt, ETH_HLEN);
 202 }
 203 
 204 static const struct dsa_device_ops brcm_prepend_netdev_ops = {
 205         .name   = "brcm-prepend",
 206         .proto  = DSA_TAG_PROTO_BRCM_PREPEND,
 207         .xmit   = brcm_tag_xmit_prepend,
 208         .rcv    = brcm_tag_rcv_prepend,
 209         .overhead = BRCM_TAG_LEN,
 210 };
 211 
 212 DSA_TAG_DRIVER(brcm_prepend_netdev_ops);
 213 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_PREPEND);
 214 #endif
 215 
 216 static struct dsa_tag_driver *dsa_tag_driver_array[] =  {
 217 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
 218         &DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
 219 #endif
 220 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
 221         &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
 222 #endif
 223 };
 224 
 225 module_dsa_tag_drivers(dsa_tag_driver_array);
 226 
 227 MODULE_LICENSE("GPL");