net: dsa: lan9303: calculate offload_fwd_mark from tag
authorEgil Hjelmeland <privat@egil-hjelmeland.no>
Mon, 13 Nov 2017 13:25:25 +0000 (14:25 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 14 Nov 2017 12:47:48 +0000 (21:47 +0900)
The lan9303 set bits in the host CPU tag indicating if a ingress frame
is a trapped IGMP or STP frame. Use these bits to calculate
skb->offload_fwd_mark more efficiently.

Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dsa/tag_lan9303.c

index b8c5e52b2eff94406a4621f47412c92b65538e14..548c00254c0728412f159b0857d58ab61b370106 100644 (file)
 #define LAN9303_TAG_LEN 4
 # define LAN9303_TAG_TX_USE_ALR BIT(3)
 # define LAN9303_TAG_TX_STP_OVERRIDE BIT(4)
+# define LAN9303_TAG_RX_IGMP BIT(3)
+# define LAN9303_TAG_RX_STP BIT(4)
+# define LAN9303_TAG_RX_TRAPPED_TO_CPU (LAN9303_TAG_RX_IGMP | \
+                                       LAN9303_TAG_RX_STP)
 
 /* Decide whether to transmit using ALR lookup, or transmit directly to
  * port using tag. ALR learning is performed only when using ALR lookup.
@@ -91,9 +95,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
        u16 *lan9303_tag;
+       u16 lan9303_tag1;
        unsigned int source_port;
-       u16 ether_type_nw;
-       u8 ip_protocol;
 
        if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) {
                dev_warn_ratelimited(&dev->dev,
@@ -114,7 +117,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
                return NULL;
        }
 
-       source_port = ntohs(lan9303_tag[1]) & 0x3;
+       lan9303_tag1 = ntohs(lan9303_tag[1]);
+       source_port = lan9303_tag1 & 0x3;
 
        skb->dev = dsa_master_find_slave(dev, 0, source_port);
        if (!skb->dev) {
@@ -128,19 +132,7 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
        skb_pull_rcsum(skb, 2 + 2);
        memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
                2 * ETH_ALEN);
-       skb->offload_fwd_mark = !ether_addr_equal(skb->data - ETH_HLEN,
-                                                 eth_stp_addr);
-
-       /* We also need IGMP packets to have skb->offload_fwd_mark = 0.
-        * Solving this for all conceivable situations would add more cost to
-        * every packet. Instead we handle just the common case:
-        * No VLAN tag + Ethernet II framing.
-        * Test least probable term first.
-        */
-       ether_type_nw = lan9303_tag[2];
-       ip_protocol = *(skb->data + 9);
-       if (ip_protocol == IPPROTO_IGMP && ether_type_nw == htons(ETH_P_IP))
-               skb->offload_fwd_mark = 0;
+       skb->offload_fwd_mark = !(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU);
 
        return skb;
 }