]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: dsa: tag_sja1105: add compatibility with hwaccel VLAN tags
authorVladimir Oltean <vladimir.oltean@nxp.com>
Mon, 21 Sep 2020 00:10:31 +0000 (03:10 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 21 Sep 2020 02:01:34 +0000 (19:01 -0700)
Check whether there is any hwaccel VLAN tag on RX, and if there is,
treat it as the tag_8021q header.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dsa/tag_sja1105.c

index 9b4a4d719291b2ef22d896a37340eaff4308a6d0..3710f9daa46d4640231be0b71385b301d6e66230 100644 (file)
@@ -72,14 +72,21 @@ static inline bool sja1105_is_meta_frame(const struct sk_buff *skb)
 static bool sja1105_can_use_vlan_as_tags(const struct sk_buff *skb)
 {
        struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
+       u16 vlan_tci;
 
        if (hdr->h_vlan_proto == htons(ETH_P_SJA1105))
                return true;
 
-       if (hdr->h_vlan_proto != htons(ETH_P_8021Q))
+       if (hdr->h_vlan_proto != htons(ETH_P_8021Q) &&
+           !skb_vlan_tag_present(skb))
                return false;
 
-       return vid_is_dsa_8021q(ntohs(hdr->h_vlan_TCI) & VLAN_VID_MASK);
+       if (skb_vlan_tag_present(skb))
+               vlan_tci = skb_vlan_tag_get(skb);
+       else
+               vlan_tci = ntohs(hdr->h_vlan_TCI);
+
+       return vid_is_dsa_8021q(vlan_tci & VLAN_VID_MASK);
 }
 
 /* This is the first time the tagger sees the frame on RX.
@@ -283,7 +290,8 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 
        hdr = eth_hdr(skb);
        tpid = ntohs(hdr->h_proto);
-       is_tagged = (tpid == ETH_P_SJA1105 || tpid == ETH_P_8021Q);
+       is_tagged = (tpid == ETH_P_SJA1105 || tpid == ETH_P_8021Q ||
+                    skb_vlan_tag_present(skb));
        is_link_local = sja1105_is_link_local(skb);
        is_meta = sja1105_is_meta_frame(skb);
 
@@ -292,7 +300,12 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
        if (is_tagged) {
                /* Normal traffic path. */
                skb_push_rcsum(skb, ETH_HLEN);
-               __skb_vlan_pop(skb, &tci);
+               if (skb_vlan_tag_present(skb)) {
+                       tci = skb_vlan_tag_get(skb);
+                       __vlan_hwaccel_clear_tag(skb);
+               } else {
+                       __skb_vlan_pop(skb, &tci);
+               }
                skb_pull_rcsum(skb, ETH_HLEN);
                skb_reset_network_header(skb);
                skb_reset_transport_header(skb);