return ntohs(eth_hdr(skb)->h_proto) == ETH_P_SJA1110;
}
-/* Returns true for imprecise RX and sets the @vid.
- * Returns false for precise RX and sets @source_port and @switch_id.
+/* If the VLAN in the packet is a tag_8021q one, set @source_port and
+ * @switch_id and strip the header. Otherwise set @vid and keep it in the
+ * packet.
*/
-static bool sja1105_vlan_rcv(struct sk_buff *skb, int *source_port,
+static void sja1105_vlan_rcv(struct sk_buff *skb, int *source_port,
int *switch_id, u16 *vid)
{
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)skb_mac_header(skb);
else
vlan_tci = ntohs(hdr->h_vlan_TCI);
- if (vid_is_dsa_8021q_rxvlan(vlan_tci & VLAN_VID_MASK)) {
- dsa_8021q_rcv(skb, source_port, switch_id);
- return false;
- }
+ if (vid_is_dsa_8021q_rxvlan(vlan_tci & VLAN_VID_MASK))
+ return dsa_8021q_rcv(skb, source_port, switch_id);
/* Try our best with imprecise RX */
*vid = vlan_tci & VLAN_VID_MASK;
-
- return true;
}
static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
{
int source_port = -1, switch_id = -1;
struct sja1105_meta meta = {0};
- bool imprecise_rx = false;
struct ethhdr *hdr;
bool is_link_local;
bool is_meta;
if (sja1105_skb_has_tag_8021q(skb)) {
/* Normal traffic path. */
- imprecise_rx = sja1105_vlan_rcv(skb, &source_port, &switch_id,
- &vid);
+ sja1105_vlan_rcv(skb, &source_port, &switch_id, &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 (imprecise_rx)
+ 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);
struct packet_type *pt)
{
int source_port = -1, switch_id = -1;
- bool imprecise_rx = false;
u16 vid;
skb->offload_fwd_mark = 1;
/* Packets with in-band control extensions might still have RX VLANs */
if (likely(sja1105_skb_has_tag_8021q(skb)))
- imprecise_rx = sja1105_vlan_rcv(skb, &source_port, &switch_id,
- &vid);
+ sja1105_vlan_rcv(skb, &source_port, &switch_id, &vid);
- if (imprecise_rx)
+ 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);