* VBID - { VID[9], VID[5:4] }:
  *     Virtual bridge ID. If between 1 and 7, packet targets the broadcast
  *     domain of a bridge. If transmitted as zero, packet targets a single
- *     port. Field only valid on transmit, must be ignored on receive.
+ *     port.
  *
  * PORT - VID[3:0]:
  *     Index of switch port. Must be between 0 and 15.
 }
 EXPORT_SYMBOL_GPL(dsa_8021q_xmit);
 
-void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id)
+struct net_device *dsa_tag_8021q_find_port_by_vbid(struct net_device *master,
+                                                  int vbid)
+{
+       struct dsa_port *cpu_dp = master->dsa_ptr;
+       struct dsa_switch_tree *dst = cpu_dp->dst;
+       struct dsa_port *dp;
+
+       if (WARN_ON(!vbid))
+               return NULL;
+
+       dsa_tree_for_each_user_port(dp, dst) {
+               if (!dp->bridge)
+                       continue;
+
+               if (dp->stp_state != BR_STATE_LEARNING &&
+                   dp->stp_state != BR_STATE_FORWARDING)
+                       continue;
+
+               if (dp->cpu_dp != cpu_dp)
+                       continue;
+
+               if (dsa_port_bridge_num_get(dp) == vbid)
+                       return dp->slave;
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(dsa_tag_8021q_find_port_by_vbid);
+
+void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id,
+                  int *vbid)
 {
        u16 vid, tci;
 
 
        *source_port = dsa_8021q_rx_source_port(vid);
        *switch_id = dsa_8021q_rx_switch_id(vid);
+
+       if (vbid)
+               *vbid = dsa_tag_8021q_rx_vbid(vid);
+
        skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
 }
 EXPORT_SYMBOL_GPL(dsa_8021q_rcv);
 
  * packet.
  */
 static void sja1105_vlan_rcv(struct sk_buff *skb, int *source_port,
-                            int *switch_id, u16 *vid)
+                            int *switch_id, int *vbid, u16 *vid)
 {
        struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)skb_mac_header(skb);
        u16 vlan_tci;
        else
                vlan_tci = ntohs(hdr->h_vlan_TCI);
 
-       if (vid_is_dsa_8021q_rxvlan(vlan_tci & VLAN_VID_MASK))
-               return dsa_8021q_rcv(skb, source_port, switch_id);
+       if (vid_is_dsa_8021q(vlan_tci & VLAN_VID_MASK))
+               return dsa_8021q_rcv(skb, source_port, switch_id, vbid);
 
        /* Try our best with imprecise RX */
        *vid = vlan_tci & VLAN_VID_MASK;
 static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
                                   struct net_device *netdev)
 {
-       int source_port = -1, switch_id = -1;
+       int source_port = -1, switch_id = -1, vbid = -1;
        struct sja1105_meta meta = {0};
        struct ethhdr *hdr;
        bool is_link_local;
 
        if (sja1105_skb_has_tag_8021q(skb)) {
                /* Normal traffic path. */
-               sja1105_vlan_rcv(skb, &source_port, &switch_id, &vid);
+               sja1105_vlan_rcv(skb, &source_port, &switch_id, &vbid, &vid);
        } else if (is_link_local) {
                /* Management traffic path. Switch embeds the switch ID and
                 * port ID into bytes of the destination MAC, courtesy of
                return NULL;
        }
 
-       if (source_port == -1 || switch_id == -1)
+       if (vbid >= 1)
+               skb->dev = dsa_tag_8021q_find_port_by_vbid(netdev, vbid);
+       else if (source_port == -1 || switch_id == -1)
                skb->dev = dsa_find_designated_bridge_port_by_vid(netdev, vid);
        else
                skb->dev = dsa_master_find_slave(netdev, switch_id, source_port);
 static struct sk_buff *sja1110_rcv(struct sk_buff *skb,
                                   struct net_device *netdev)
 {
-       int source_port = -1, switch_id = -1;
+       int source_port = -1, switch_id = -1, vbid = -1;
        bool host_only = false;
        u16 vid = 0;
 
 
        /* Packets with in-band control extensions might still have RX VLANs */
        if (likely(sja1105_skb_has_tag_8021q(skb)))
-               sja1105_vlan_rcv(skb, &source_port, &switch_id, &vid);
+               sja1105_vlan_rcv(skb, &source_port, &switch_id, &vbid, &vid);
 
-       if (source_port == -1 || switch_id == -1)
+       if (vbid >= 1)
+               skb->dev = dsa_tag_8021q_find_port_by_vbid(netdev, vbid);
+       else if (source_port == -1 || switch_id == -1)
                skb->dev = dsa_find_designated_bridge_port_by_vid(netdev, vid);
        else
                skb->dev = dsa_master_find_slave(netdev, switch_id, source_port);