Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * XRS700x tag format handling
0004  * Copyright (c) 2008-2009 Marvell Semiconductor
0005  * Copyright (c) 2020 NovaTech LLC
0006  */
0007 
0008 #include <linux/bitops.h>
0009 
0010 #include "dsa_priv.h"
0011 
0012 static struct sk_buff *xrs700x_xmit(struct sk_buff *skb, struct net_device *dev)
0013 {
0014     struct dsa_port *partner, *dp = dsa_slave_to_port(dev);
0015     u8 *trailer;
0016 
0017     trailer = skb_put(skb, 1);
0018     trailer[0] = BIT(dp->index);
0019 
0020     if (dp->hsr_dev)
0021         dsa_hsr_foreach_port(partner, dp->ds, dp->hsr_dev)
0022             if (partner != dp)
0023                 trailer[0] |= BIT(partner->index);
0024 
0025     return skb;
0026 }
0027 
0028 static struct sk_buff *xrs700x_rcv(struct sk_buff *skb, struct net_device *dev)
0029 {
0030     int source_port;
0031     u8 *trailer;
0032 
0033     trailer = skb_tail_pointer(skb) - 1;
0034 
0035     source_port = ffs((int)trailer[0]) - 1;
0036 
0037     if (source_port < 0)
0038         return NULL;
0039 
0040     skb->dev = dsa_master_find_slave(dev, 0, source_port);
0041     if (!skb->dev)
0042         return NULL;
0043 
0044     if (pskb_trim_rcsum(skb, skb->len - 1))
0045         return NULL;
0046 
0047     /* Frame is forwarded by hardware, don't forward in software. */
0048     dsa_default_offload_fwd_mark(skb);
0049 
0050     return skb;
0051 }
0052 
0053 static const struct dsa_device_ops xrs700x_netdev_ops = {
0054     .name   = "xrs700x",
0055     .proto  = DSA_TAG_PROTO_XRS700X,
0056     .xmit   = xrs700x_xmit,
0057     .rcv    = xrs700x_rcv,
0058     .needed_tailroom = 1,
0059 };
0060 
0061 MODULE_LICENSE("GPL");
0062 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_XRS700X);
0063 
0064 module_dsa_tag_driver(xrs700x_netdev_ops);