| --- linux-5.4.77.orig/net/dsa/tag_mtk.c |
| +++ linux-5.4.77/net/dsa/tag_mtk.c |
| @@ -73,22 +73,28 @@ static struct sk_buff *mtk_tag_rcv(struc |
| bool is_multicast_skb = is_multicast_ether_addr(dest) && |
| !is_broadcast_ether_addr(dest); |
| |
| - if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN))) |
| - return NULL; |
| + if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) { |
| + hdr = ntohs(skb->vlan_proto); |
| + skb->vlan_proto = 0; |
| + skb->vlan_tci = 0; |
| + } else { |
| + if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN))) |
| + return NULL; |
| |
| - /* The MTK header is added by the switch between src addr |
| - * and ethertype at this point, skb->data points to 2 bytes |
| - * after src addr so header should be 2 bytes right before. |
| - */ |
| - phdr = (__be16 *)(skb->data - 2); |
| - hdr = ntohs(*phdr); |
| + /* The MTK header is added by the switch between src addr |
| + * and ethertype at this point, skb->data points to 2 bytes |
| + * after src addr so header should be 2 bytes right before. |
| + */ |
| + phdr = (__be16 *)(skb->data - 2); |
| + hdr = ntohs(*phdr); |
| |
| - /* Remove MTK tag and recalculate checksum. */ |
| - skb_pull_rcsum(skb, MTK_HDR_LEN); |
| + /* Remove MTK tag and recalculate checksum. */ |
| + skb_pull_rcsum(skb, MTK_HDR_LEN); |
| |
| - memmove(skb->data - ETH_HLEN, |
| - skb->data - ETH_HLEN - MTK_HDR_LEN, |
| - 2 * ETH_ALEN); |
| + memmove(skb->data - ETH_HLEN, |
| + skb->data - ETH_HLEN - MTK_HDR_LEN, |
| + 2 * ETH_ALEN); |
| + } |
| |
| /* Get source port information */ |
| port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK); |