blob: 6b105845986feddd3c494941232e468e4a8056f6 [file] [log] [blame]
--- 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);