mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-14 02:19:06 +04:00
qualcommax: qca_edma: refuse a frame before its preheader is pushed
The transmit routine prepends the 32-byte preheader and only then tests
whether the descriptor's slot still holds an uncompleted frame. A frame
refused there goes back to the qdisc already carrying the preheader, and
the requeue pushes a second one: the descriptor names a length that no
longer describes the frame, and the headroom the push consumed is gone.
Both refusals now precede the push, where the ring-full test already sat.
The slot test depends on nothing between the two points, so the accepted
path is unchanged.
Fixes: bdb0b722b7 ("qualcommax: add EDMA driver")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25084
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
1 parent
f53100d40e
commit
a9adfbf98f
1 file changed
+10
-6
@@ -589,6 +589,16 @@ static netdev_tx_t edma_ring_xmit(struct edma_priv *priv, struct net_device *net
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
/* Both refusals come before the preheader is pushed: the qdisc requeues
|
||||
* the frame as it was handed over, and a second push would prefix it
|
||||
* twice and hand the hardware a length that no longer describes it.
|
||||
*/
|
||||
idx = prod & (txdesc_ring->count - 1);
|
||||
if (unlikely(txdesc_ring->skb_store[idx])) {
|
||||
spin_unlock_bh(&priv->tx_lock);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
buf_len = skb_headlen(skb);
|
||||
|
||||
tag_info = skb_ext_find(skb, SKB_EXT_DSA_OOB);
|
||||
@@ -603,12 +613,6 @@ static netdev_tx_t edma_ring_xmit(struct edma_priv *priv, struct net_device *net
|
||||
|
||||
txph->dst_info = dst_info;
|
||||
|
||||
idx = prod & (txdesc_ring->count - 1);
|
||||
if (unlikely(txdesc_ring->skb_store[idx] != NULL)) {
|
||||
spin_unlock_bh(&priv->tx_lock);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
txdesc_ring->skb_store[idx] = skb;
|
||||
txph->opaque = idx;
|
||||
|
||||
|
||||
Reference in new issue
Block a user