forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: dsa: add a second tagger for Ocelot switches based on tag_8021q
There are use cases for which the existing tagger, based on the NPI (Node Processor Interface) functionality, is insufficient. Namely: - Frames injected through the NPI port bypass the frame analyzer, so no source address learning is performed, no TSN stream classification, etc. - Flow control is not functional over an NPI port (PAUSE frames are encapsulated in the same Extraction Frame Header as all other frames) - There can be at most one NPI port configured for an Ocelot switch. But in NXP LS1028A and T1040 there are two Ethernet CPU ports. The non-NPI port is currently either disabled, or operated as a plain user port (albeit an internally-facing one). Having the ability to configure the two CPU ports symmetrically could pave the way for e.g. creating a LAG between them, to increase bandwidth seamlessly for the system. So there is a desire to have an alternative to the NPI mode. This change keeps the default tagger for the Seville and Felix switches as "ocelot", but it can be changed via the following device attribute: echo ocelot-8021q > /sys/class/<dsa-master>/dsa/tagging Signed-off-by: Vladimir Oltean <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
- Loading branch information
1 parent
adb3dcc
commit 7c83a7c
Showing
6 changed files
with
92 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright 2020-2021 NXP Semiconductors | ||
* | ||
* An implementation of the software-defined tag_8021q.c tagger format, which | ||
* also preserves full functionality under a vlan_filtering bridge. It does | ||
* this by using the TCAM engines for: | ||
* - pushing the RX VLAN as a second, outer tag, on egress towards the CPU port | ||
* - redirecting towards the correct front port based on TX VLAN and popping | ||
* that on egress | ||
*/ | ||
#include <linux/dsa/8021q.h> | ||
#include "dsa_priv.h" | ||
|
||
static struct sk_buff *ocelot_xmit(struct sk_buff *skb, | ||
struct net_device *netdev) | ||
{ | ||
struct dsa_port *dp = dsa_slave_to_port(netdev); | ||
u16 tx_vid = dsa_8021q_tx_vid(dp->ds, dp->index); | ||
u16 queue_mapping = skb_get_queue_mapping(skb); | ||
u8 pcp = netdev_txq_to_tc(netdev, queue_mapping); | ||
|
||
return dsa_8021q_xmit(skb, netdev, ETH_P_8021Q, | ||
((pcp << VLAN_PRIO_SHIFT) | tx_vid)); | ||
} | ||
|
||
static struct sk_buff *ocelot_rcv(struct sk_buff *skb, | ||
struct net_device *netdev, | ||
struct packet_type *pt) | ||
{ | ||
int src_port, switch_id, qos_class; | ||
u16 vid, tci; | ||
|
||
skb_push_rcsum(skb, ETH_HLEN); | ||
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); | ||
|
||
vid = tci & VLAN_VID_MASK; | ||
src_port = dsa_8021q_rx_source_port(vid); | ||
switch_id = dsa_8021q_rx_switch_id(vid); | ||
qos_class = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; | ||
|
||
skb->dev = dsa_master_find_slave(netdev, switch_id, src_port); | ||
if (!skb->dev) | ||
return NULL; | ||
|
||
skb->offload_fwd_mark = 1; | ||
skb->priority = qos_class; | ||
|
||
return skb; | ||
} | ||
|
||
static const struct dsa_device_ops ocelot_8021q_netdev_ops = { | ||
.name = "ocelot-8021q", | ||
.proto = DSA_TAG_PROTO_OCELOT_8021Q, | ||
.xmit = ocelot_xmit, | ||
.rcv = ocelot_rcv, | ||
.overhead = VLAN_HLEN, | ||
}; | ||
|
||
MODULE_LICENSE("GPL v2"); | ||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OCELOT_8021Q); | ||
|
||
module_dsa_tag_driver(ocelot_8021q_netdev_ops); |