diff mbox series

[RFC,net-next,2/2] net: dsa: tag_mtk: handle VLAN tag insertion on TX

Message ID 20210825083832.2425886-3-dqfext@gmail.com (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series DSA slave with customise netdev features | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers success CCed 13 of 13 maintainers
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 68 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/header_inline success Link

Commit Message

Qingfang Deng Aug. 25, 2021, 8:38 a.m. UTC
Advertise TX VLAN offload features, and handle VLAN tag insertion in
the tag_xmit function.

Signed-off-by: DENG Qingfang <dqfext@gmail.com>
---
 net/dsa/tag_mtk.c | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

Comments

Vladimir Oltean Aug. 26, 2021, 12:03 a.m. UTC | #1
On Wed, Aug 25, 2021 at 04:38:31PM +0800, DENG Qingfang wrote:
> Advertise TX VLAN offload features, and handle VLAN tag insertion in
> the tag_xmit function.
> 
> Signed-off-by: DENG Qingfang <dqfext@gmail.com>
> ---
>  net/dsa/tag_mtk.c | 46 ++++++++++++++++++++++------------------------
>  1 file changed, 22 insertions(+), 24 deletions(-)
> 
> diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
> index 415d8ece242a..e407abefa06c 100644
> --- a/net/dsa/tag_mtk.c
> +++ b/net/dsa/tag_mtk.c
> @@ -22,7 +22,6 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
>  				    struct net_device *dev)
>  {
>  	struct dsa_port *dp = dsa_slave_to_port(dev);
> -	u8 xmit_tpid;
>  	u8 *mtk_tag;
>  
>  	/* Build the special tag after the MAC Source Address. If VLAN header
> @@ -31,33 +30,31 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
>  	 * the both special and VLAN tag at the same time and then look up VLAN
>  	 * table with VID.
>  	 */
> -	switch (skb->protocol) {
> -	case htons(ETH_P_8021Q):
> -		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100;
> -		break;
> -	case htons(ETH_P_8021AD):
> -		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8;
> -		break;
> -	default:
> -		xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
> -		skb_push(skb, MTK_HDR_LEN);
> -		dsa_alloc_etype_header(skb, MTK_HDR_LEN);
> -	}
> -

You cannot just remove the old code. Only things like 8021q uppers will
send packets with the VLAN in the hwaccel area.

If you have an application that puts the VLAN in the actual AF_PACKET
payload, like:

https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c

then you need to handle the VLAN being in the skb payload.
Qingfang Deng Aug. 26, 2021, 5:29 a.m. UTC | #2
On Thu, Aug 26, 2021 at 03:03:49AM +0300, Vladimir Oltean wrote:
> 
> You cannot just remove the old code. Only things like 8021q uppers will
> send packets with the VLAN in the hwaccel area.
> 
> If you have an application that puts the VLAN in the actual AF_PACKET
> payload, like:
> 
> https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c
> 
> then you need to handle the VLAN being in the skb payload.

I've actually tested this (only apply patch 2 without .features) and it
still worked.

The comment says the VLAN tag need to be combined with the special tag in
order to perform VLAN table lookup, so we can set its destination port
vector to all zeroes and the switch will forward it like a data frame
(TX forward offload), but as we allow multiple bridges which are either
VLAN-unaware or VLAN-aware with the same VID, there is no way to determine
the destination bridge unless we maintain some VLAN translation mapping.
Florian Fainelli Aug. 26, 2021, 11:37 a.m. UTC | #3
On 8/26/2021 7:29 AM, DENG Qingfang wrote:
> On Thu, Aug 26, 2021 at 03:03:49AM +0300, Vladimir Oltean wrote:
>>
>> You cannot just remove the old code. Only things like 8021q uppers will
>> send packets with the VLAN in the hwaccel area.
>>
>> If you have an application that puts the VLAN in the actual AF_PACKET
>> payload, like:
>>
>> https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c
>>
>> then you need to handle the VLAN being in the skb payload.
> 
> I've actually tested this (only apply patch 2 without .features) and it
> still worked.

OK and this works because now you always push a MTK_HDR_LEN tag which 
you were not doing before for VLAN-tagged frames, right?

You don't seem to be clearing mtk_tag[2] and mtk_tag[3] anymore, is that 
intended?

> 
> The comment says the VLAN tag need to be combined with the special tag in
> order to perform VLAN table lookup, so we can set its destination port
> vector to all zeroes and the switch will forward it like a data frame
> (TX forward offload), but as we allow multiple bridges which are either
> VLAN-unaware or VLAN-aware with the same VID, there is no way to determine
> the destination bridge unless we maintain some VLAN translation mapping.

There is no "bridge" on the other side from the CPU port's perspective 
on egress, only physical ports, so how does that comment apply?
Vladimir Oltean Aug. 26, 2021, 2:13 p.m. UTC | #4
On Thu, Aug 26, 2021 at 01:29:56PM +0800, DENG Qingfang wrote:
> On Thu, Aug 26, 2021 at 03:03:49AM +0300, Vladimir Oltean wrote:
> > 
> > You cannot just remove the old code. Only things like 8021q uppers will
> > send packets with the VLAN in the hwaccel area.
> > 
> > If you have an application that puts the VLAN in the actual AF_PACKET
> > payload, like:
> > 
> > https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c
> > 
> > then you need to handle the VLAN being in the skb payload.
> 
> I've actually tested this (only apply patch 2 without .features) and it
> still worked.
> 
> The comment says the VLAN tag need to be combined with the special tag in
> order to perform VLAN table lookup,

It does say this.

> so we can set its destination port vector to all zeroes and the switch
> will forward it like a data frame (TX forward offload),

And it does not say this. So this is supported after all with mt7530?
Are you looking to add support for that?

> but as we allow multiple bridges which are either VLAN-unaware or
> VLAN-aware with the same VID, there is no way to determine the
> destination bridge unless we maintain some VLAN translation mapping.

What does "VLAN translation mapping" mean, practically?
Other drivers which cannot remap VIDs to internal VLANs just restrict a
single VLAN-aware bridge, and potentially multiple VLAN-unaware ones.
Qingfang Deng Aug. 26, 2021, 3:27 p.m. UTC | #5
On Thu, Aug 26, 2021 at 05:13:26PM +0300, Vladimir Oltean wrote:
> On Thu, Aug 26, 2021 at 01:29:56PM +0800, DENG Qingfang wrote:
> > 
> > The comment says the VLAN tag need to be combined with the special tag in
> > order to perform VLAN table lookup,
> 
> It does say this.
> 
> > so we can set its destination port vector to all zeroes and the switch
> > will forward it like a data frame (TX forward offload),
> 
> And it does not say this. So this is supported after all with mt7530?
> Are you looking to add support for that?

I already run-tested that, it works, as long as there is only one bridge.

> 
> > but as we allow multiple bridges which are either VLAN-unaware or
> > VLAN-aware with the same VID, there is no way to determine the
> > destination bridge unless we maintain some VLAN translation mapping.
> 
> What does "VLAN translation mapping" mean, practically?

It's just VLAN remapping, as you stated below.

> Other drivers which cannot remap VIDs to internal VLANs just restrict a
> single VLAN-aware bridge, and potentially multiple VLAN-unaware ones.
diff mbox series

Patch

diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index 415d8ece242a..e407abefa06c 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -22,7 +22,6 @@  static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
 				    struct net_device *dev)
 {
 	struct dsa_port *dp = dsa_slave_to_port(dev);
-	u8 xmit_tpid;
 	u8 *mtk_tag;
 
 	/* Build the special tag after the MAC Source Address. If VLAN header
@@ -31,33 +30,31 @@  static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
 	 * the both special and VLAN tag at the same time and then look up VLAN
 	 * table with VID.
 	 */
-	switch (skb->protocol) {
-	case htons(ETH_P_8021Q):
-		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100;
-		break;
-	case htons(ETH_P_8021AD):
-		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8;
-		break;
-	default:
-		xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
-		skb_push(skb, MTK_HDR_LEN);
-		dsa_alloc_etype_header(skb, MTK_HDR_LEN);
-	}
-
+	skb_push(skb, MTK_HDR_LEN);
+	dsa_alloc_etype_header(skb, MTK_HDR_LEN);
 	mtk_tag = dsa_etype_header_pos_tx(skb);
 
-	/* Mark tag attribute on special tag insertion to notify hardware
-	 * whether that's a combined special tag with 802.1Q header.
-	 */
-	mtk_tag[0] = xmit_tpid;
-	mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
-
-	/* Tag control information is kept for 802.1Q */
-	if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) {
-		mtk_tag[2] = 0;
-		mtk_tag[3] = 0;
+	if (skb_vlan_tag_present(skb)) {
+		switch (skb->vlan_proto) {
+		case htons(ETH_P_8021Q):
+			mtk_tag[0] = MTK_HDR_XMIT_TAGGED_TPID_8100;
+			break;
+		case htons(ETH_P_8021AD):
+			mtk_tag[0] = MTK_HDR_XMIT_TAGGED_TPID_88A8;
+			break;
+		default:
+			return NULL;
+		}
+
+		((__be16 *)mtk_tag)[1] = htons(skb_vlan_tag_get(skb));
+		__vlan_hwaccel_clear_tag(skb);
+	} else {
+		mtk_tag[0] = MTK_HDR_XMIT_UNTAGGED;
+		((__be16 *)mtk_tag)[1] = 0;
 	}
 
+	mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
+
 	return skb;
 }
 
@@ -96,6 +93,7 @@  static const struct dsa_device_ops mtk_netdev_ops = {
 	.xmit		= mtk_tag_xmit,
 	.rcv		= mtk_tag_rcv,
 	.needed_headroom = MTK_HDR_LEN,
+	.features	= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX,
 };
 
 MODULE_LICENSE("GPL");