0001
0002
0003
0004
0005 #include <linux/dsa/lan9303.h>
0006 #include <linux/etherdevice.h>
0007 #include <linux/list.h>
0008 #include <linux/slab.h>
0009
0010 #include "dsa_priv.h"
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #define LAN9303_TAG_LEN 4
0034 # define LAN9303_TAG_TX_USE_ALR BIT(3)
0035 # define LAN9303_TAG_TX_STP_OVERRIDE BIT(4)
0036 # define LAN9303_TAG_RX_IGMP BIT(3)
0037 # define LAN9303_TAG_RX_STP BIT(4)
0038 # define LAN9303_TAG_RX_TRAPPED_TO_CPU (LAN9303_TAG_RX_IGMP | \
0039 LAN9303_TAG_RX_STP)
0040
0041
0042
0043
0044
0045
0046
0047
0048 static int lan9303_xmit_use_arl(struct dsa_port *dp, u8 *dest_addr)
0049 {
0050 struct lan9303 *chip = dp->ds->priv;
0051
0052 return chip->is_bridged && !is_multicast_ether_addr(dest_addr);
0053 }
0054
0055 static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev)
0056 {
0057 struct dsa_port *dp = dsa_slave_to_port(dev);
0058 __be16 *lan9303_tag;
0059 u16 tag;
0060
0061
0062 skb_push(skb, LAN9303_TAG_LEN);
0063
0064
0065 dsa_alloc_etype_header(skb, LAN9303_TAG_LEN);
0066
0067 lan9303_tag = dsa_etype_header_pos_tx(skb);
0068
0069 tag = lan9303_xmit_use_arl(dp, skb->data) ?
0070 LAN9303_TAG_TX_USE_ALR :
0071 dp->index | LAN9303_TAG_TX_STP_OVERRIDE;
0072 lan9303_tag[0] = htons(ETH_P_8021Q);
0073 lan9303_tag[1] = htons(tag);
0074
0075 return skb;
0076 }
0077
0078 static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev)
0079 {
0080 u16 lan9303_tag1;
0081 unsigned int source_port;
0082
0083 if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) {
0084 dev_warn_ratelimited(&dev->dev,
0085 "Dropping packet, cannot pull\n");
0086 return NULL;
0087 }
0088
0089 if (skb_vlan_tag_present(skb)) {
0090 lan9303_tag1 = skb_vlan_tag_get(skb);
0091 __vlan_hwaccel_clear_tag(skb);
0092 } else {
0093 skb_push_rcsum(skb, ETH_HLEN);
0094 __skb_vlan_pop(skb, &lan9303_tag1);
0095 skb_pull_rcsum(skb, ETH_HLEN);
0096 }
0097
0098 source_port = lan9303_tag1 & 0x3;
0099
0100 skb->dev = dsa_master_find_slave(dev, 0, source_port);
0101 if (!skb->dev) {
0102 dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n");
0103 return NULL;
0104 }
0105
0106 if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
0107 dsa_default_offload_fwd_mark(skb);
0108
0109 return skb;
0110 }
0111
0112 static const struct dsa_device_ops lan9303_netdev_ops = {
0113 .name = "lan9303",
0114 .proto = DSA_TAG_PROTO_LAN9303,
0115 .xmit = lan9303_xmit,
0116 .rcv = lan9303_rcv,
0117 .needed_headroom = LAN9303_TAG_LEN,
0118 };
0119
0120 MODULE_LICENSE("GPL");
0121 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN9303);
0122
0123 module_dsa_tag_driver(lan9303_netdev_ops);