net: ethernet: mtk_eth_soc: allow TX checksum offload with a tag_8021q DSA tagger - #210
Open
meehien wants to merge 1 commit into
Open
net: ethernet: mtk_eth_soc: allow TX checksum offload with a tag_8021q DSA tagger#210meehien wants to merge 1 commit into
meehien wants to merge 1 commit into
Conversation
…q DSA tagger mtk_fix_features() clears NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM on any conduit whose DSA tag protocol is not DSA_TAG_PROTO_MTK. The test is a proxy for "framing the GDM transmit checksum engine cannot parse": the engine is programmed with a single descriptor bit and no header offsets, so it has to find the L3 and L4 headers itself, and a tagger that pushes an opaque header in front of them hides them from it. The proxy is too coarse. DSA_TAG_PROTO_MXL862_8021Q pushes nothing opaque - mxl862_8021q_xmit() calls dsa_8021q_xmit(), which inserts a real 802.1Q header with vlan_insert_tag(), and declares needed_headroom = VLAN_HLEN. What reaches the GDM is an ordinary VLAN tagged Ethernet frame, and the parser handles those already: the same hardware inserts a VLAN tag on its own via TX_DMA_INS_VLAN and TX_DMA_INS_VLAN_V2, which it could not place correctly if it could not locate the tag. On a BPI-R4 Pro the effect is large. The MxL86252C conduit is the only egress path for the 10G port, so every TCP segment leaving that port is checksummed by the CPU. Single stream iperf3 over a direct 10G link between two MT7988A boards: R4 Pro -> R4, checksum denied by this test 3.16 Gbit/s R4 -> R4 Pro, checksum offloaded 4.64 Gbit/s R4 -> R4 Pro, checksum disabled by hand 3.09 Gbit/s R4 Pro -> R4, with this patch 4.65 Gbit/s The third row is the control: with the offload removed from the direction that had it, both directions agree to within 2%, so the whole difference is this test and not the extra DSA hop. The fourth is the result. Correctness was checked on the receiver over 5.42 GB, roughly 3.9M segments carrying a hardware computed checksum behind an inserted 802.1Q tag: zero TCP retransmissions and TcpInCsumErrors unchanged at zero. A misparsed header offset would produce a wrong checksum, which the receiver discards and the sender retransmits, so neither counter could have stayed at zero had the engine failed to skip the tag. Replace non_mtk_uses_dsa(), which had no other callers, with a predicate named for the property actually being tested, and let a tag_8021q based tagger keep the offload. Signed-off-by: Mihai Ordean <research@mihaiordean.com>
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mtk_fix_features() refuses TX checksum offload on any DSA conduit whose tag protocol isn't DSA_TAG_PROTO_MTK. That's a proxy for "framing the GDM checksum engine can't parse" — the engine gets a single descriptor bit and no header offsets, so it has to locate the L3/L4 headers itself, and an opaque prepended tag hides them.
The proxy is too broad. A tag_8021q tagger prepends nothing opaque: dsa_8021q_xmit() inserts a real 802.1Q header via vlan_insert_tag(), so the GDM sees an ordinary VLAN-tagged Ethernet frame. The parser already handles those — the same hardware inserts VLAN tags itself via TX_DMA_INS_VLAN(_V2).
This replaces non_mtk_uses_dsa() (no other callers) with a predicate named for the property being tested, and exempts DSA_TAG_PROTO_MXL862_8021Q.
On a BPI-R4 Pro the MxL86252C conduit is the only egress path for the 10G port, so the restriction forces a software checksum on every segment leaving it. Single-stream iperf3 over a direct 10G link between two MT7988A boards: 3.16 → 4.65 Gbit/s, matching the opposite direction, which had the offload all along. Control: disabling the offload by hand on the fast side drops it to 3.09, so the gap is this test and not the extra DSA hop.
Validated over 5.42 GB (~3.9M segments) with zero TCP retransmissions and TcpInCsumErrors unchanged at zero on the receiver — a miss-parsed offset would produce a bad checksum, which the receiver discards and the sender retransmits.