summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-04-10 10:43:56 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:34:38 +0300
commit95abad53e336074aed686ad64f37281ae1114e61 (patch)
tree766ce567bc2152c32d4abc850cc67c9a0aadab17
parentb7f24fb3203e66c18e6e166bb6afdc37d010ca0c (diff)
downloadlinux-95abad53e336074aed686ad64f37281ae1114e61.tar.gz
linux-95abad53e336074aed686ad64f37281ae1114e61.zip
net: stmmac: vlan: Enable VLAN Tags Insertion Offload in TSO
The commit 041cc86b3653 ("net: stmmac: Enable TSO on VLANs") stated that the TSO feature was malfunction on DW QoS Eth and DW XGMAC for the VLAN tagged frames. In particular the commit log claims that the very first TCP segment is VLAN tagged, but the proceeding ones aren't. This hasn't been confirmed at least on a DW XGMAC 2.11a device. All the transferred TCP/IPv4 segments are VLAN tagged. Moreover the blamed commit stated that it enabled TSO for VLANs while it actually disabled it. Instead the driver now just inserts the VLAN TPID/TCI fields to the payload. It's also strange to see that the HW-accelerated VLAN IDs were actually specified for the TSO SKBs since before that commit the NETIF_F_TSO flag had been cleared for the VLAN interfaces. All of that makes me thinking that if there was a problem it has been purely investigated. Revert the change until the actually broken hardware is met. Fixes: 041cc86b3653 ("net: stmmac: Enable TSO on VLANs") Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0c963a4601f4..f120c64a8bf3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4609,9 +4609,9 @@ static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue)
*/
static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
{
+ bool has_vlan, set_ic, is_last_segment, drop = false;
struct dma_desc *desc, *first, *mss_desc = NULL;
struct stmmac_priv *priv = netdev_priv(dev);
- bool set_ic, is_last_segment, drop = false;
unsigned int first_entry, tx_packets;
struct stmmac_txq_stats *txq_stats;
netdev_tx_t ret = NETDEV_TX_OK;
@@ -4622,19 +4622,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
u8 proto_hdr_len, hdr;
dma_addr_t des;
- /* Always insert VLAN tag to SKB payload for TSO frames.
- *
- * Never insert VLAN tag by HW, since segments split by
- * TSO engine will be un-tagged by mistake.
- */
- if (skb_vlan_tag_present(skb)) {
- skb = __vlan_hwaccel_push_inside(skb);
- if (unlikely(!skb)) {
- priv->xstats.tx_dropped++;
- return NETDEV_TX_OK;
- }
- }
-
nfrags = skb_shinfo(skb)->nr_frags;
queue = skb_get_queue_mapping(skb);
@@ -4685,6 +4672,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
skb->data_len);
}
+ has_vlan = stmmac_vlan_insert(priv, skb, tx_q);
+
first_entry = tx_q->cur_tx;
WARN_ON(tx_q->tx_skbuff[first_entry]);
@@ -4694,6 +4683,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
desc = &tx_q->dma_tx[first_entry];
first = desc;
+ if (has_vlan)
+ stmmac_set_desc_vlan(priv, first, STMMAC_VLAN_INSERT);
+
/* first descriptor: fill Headers on Buf1 */
des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
DMA_TO_DEVICE);