Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002 /*
0003  * net/dsa/tag_hellcreek.c - Hirschmann Hellcreek switch tag format handling
0004  *
0005  * Copyright (C) 2019,2020 Linutronix GmbH
0006  * Author Kurt Kanzenbach <kurt@linutronix.de>
0007  *
0008  * Based on tag_ksz.c.
0009  */
0010 
0011 #include <linux/skbuff.h>
0012 #include <net/dsa.h>
0013 
0014 #include "dsa_priv.h"
0015 
0016 #define HELLCREEK_TAG_LEN   1
0017 
0018 static struct sk_buff *hellcreek_xmit(struct sk_buff *skb,
0019                       struct net_device *dev)
0020 {
0021     struct dsa_port *dp = dsa_slave_to_port(dev);
0022     u8 *tag;
0023 
0024     /* Calculate checksums (if required) before adding the trailer tag to
0025      * avoid including it in calculations. That would lead to wrong
0026      * checksums after the switch strips the tag.
0027      */
0028     if (skb->ip_summed == CHECKSUM_PARTIAL &&
0029         skb_checksum_help(skb))
0030         return NULL;
0031 
0032     /* Tag encoding */
0033     tag  = skb_put(skb, HELLCREEK_TAG_LEN);
0034     *tag = BIT(dp->index);
0035 
0036     return skb;
0037 }
0038 
0039 static struct sk_buff *hellcreek_rcv(struct sk_buff *skb,
0040                      struct net_device *dev)
0041 {
0042     /* Tag decoding */
0043     u8 *tag = skb_tail_pointer(skb) - HELLCREEK_TAG_LEN;
0044     unsigned int port = tag[0] & 0x03;
0045 
0046     skb->dev = dsa_master_find_slave(dev, 0, port);
0047     if (!skb->dev) {
0048         netdev_warn_once(dev, "Failed to get source port: %d\n", port);
0049         return NULL;
0050     }
0051 
0052     pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN);
0053 
0054     dsa_default_offload_fwd_mark(skb);
0055 
0056     return skb;
0057 }
0058 
0059 static const struct dsa_device_ops hellcreek_netdev_ops = {
0060     .name     = "hellcreek",
0061     .proto    = DSA_TAG_PROTO_HELLCREEK,
0062     .xmit     = hellcreek_xmit,
0063     .rcv      = hellcreek_rcv,
0064     .needed_tailroom = HELLCREEK_TAG_LEN,
0065 };
0066 
0067 MODULE_LICENSE("Dual MIT/GPL");
0068 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_HELLCREEK);
0069 
0070 module_dsa_tag_driver(hellcreek_netdev_ops);