* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 16:37 [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable Rohan G Thomas via B4 Relay
@ 2025-11-25 17:15 ` Maxime Chevallier
2025-11-25 18:03 ` Maxime Chevallier
2025-11-25 18:05 ` Maxime Chevallier
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Maxime Chevallier @ 2025-11-25 17:15 UTC (permalink / raw)
To: rohan.g.thomas, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue
Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Matthew Gerlach
Hi Rohan,
On 25/11/2025 17:37, Rohan G Thomas via B4 Relay wrote:
> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>
> In Store and Forward mode, flushing frames when the receive buffer is
> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
> in buffering of a few frames in the FIFO without triggering Rx DMA
> from transferring the data to the system memory until another packet
> is received. Once the issue happens, for a ping request, the packet is
> forwarded to the system memory only after we receive another packet
> and hece we observe a latency equivalent to the ping interval.
>
> 64 bytes from 192.168.2.100: seq=1 ttl=64 time=1000.344 ms
>
> Also, we can observe constant gmacgrp_debug register value of
> 0x00000120, which indicates "Reading frame data".
>
> The issue is not reproducible after disabling frame flushing when Rx
> buffer is unavailable. But in that case, the Rx DMA enters a suspend
> state due to buffer unavailability. To resume operation, software
> must write to the receive_poll_demand register after adding new
> descriptors, which reactivates the Rx DMA.
>
> This issue is observed in the socfpga platforms which has dwmac1000 IP
> like Arria 10, Cyclone V and Agilex 7. Issue is reproducible after
> running iperf3 server at the DUT for UDP lower packet sizes.
>
> Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
> Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
Should this be a fix ?
Can you elaborate on how to reproduce this ? I've given this a try on
CycloneV and I can't see any difference in the ping results and iperf3
results.
From the DUT, I've tried :
- iperf3 -c 192.168.X.X -u -b 0 -l 64
- iperf3 -c 192.168.X.X -u -b 0 -l 64 -R
- iperf3 -c 192.168.X.X
- iperf3 -c 192.168.X.X -R
I'm reading the same results with and without the patch
I've done ping tests as well, the latency seems to be the same with and
without this patch, at around 0.193ms RTT.
I'm not familiar with the SF_DMA_MODE though, any thing special to do to
enter that mode ?
Thanks,
Maxime
> ---
> drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 5 +++--
> drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
> drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 5 +++++
> drivers/net/ethernet/stmicro/stmmac/hwif.h | 3 +++
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++
> 5 files changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
> index 6d9b8fac3c6d0fd76733ab4a1a8cce2420fa40b4..5877fec9f6c30ed18cdcf5398816e444e0bd0091 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
> @@ -135,10 +135,10 @@ static void dwmac1000_dma_operation_mode_rx(struct stmmac_priv *priv,
>
> if (mode == SF_DMA_MODE) {
> pr_debug("GMAC: enable RX store and forward mode\n");
> - csr6 |= DMA_CONTROL_RSF;
> + csr6 |= DMA_CONTROL_RSF | DMA_CONTROL_DFF;
> } else {
> pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
> - csr6 &= ~DMA_CONTROL_RSF;
> + csr6 &= ~(DMA_CONTROL_RSF | DMA_CONTROL_DFF);
> csr6 &= DMA_CONTROL_TC_RX_MASK;
> if (mode <= 32)
> csr6 |= DMA_CONTROL_RTC_32;
> @@ -262,6 +262,7 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
> .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
> .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
> .enable_dma_transmission = dwmac_enable_dma_transmission,
> + .enable_dma_reception = dwmac_enable_dma_reception,
> .enable_dma_irq = dwmac_enable_dma_irq,
> .disable_dma_irq = dwmac_disable_dma_irq,
> .start_tx = dwmac_dma_start_tx,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> index d1c149f7a3dd9e472b237101666e11878707f0f2..054ecb20ce3f68bce5da3efaf36acf33e430d3f0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> @@ -169,6 +169,7 @@ static inline u32 dma_chan_base_addr(u32 base, u32 chan)
> #define NUM_DWMAC4_DMA_REGS 27
>
> void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan);
> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan);
> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx);
> void dwmac_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> index 467f1a05747ecf0be5b9f3392cd3d2049d676c21..97a803d68e3a2f120beaa7c3254748cf404236df 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> @@ -33,6 +33,11 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan)
> writel(1, ioaddr + DMA_CHAN_XMT_POLL_DEMAND(chan));
> }
>
> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan)
> +{
> + writel(1, ioaddr + DMA_CHAN_RCV_POLL_DEMAND(chan));
> +}
> +
> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx)
> {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> index f257ce4b6c66e0bbd3180d54ac7f5be934153a6b..df6e8a567b1f646f83effbb38d8e53441a6f6150 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> @@ -201,6 +201,7 @@ struct stmmac_dma_ops {
> void (*dma_diagnostic_fr)(struct stmmac_extra_stats *x,
> void __iomem *ioaddr);
> void (*enable_dma_transmission)(void __iomem *ioaddr, u32 chan);
> + void (*enable_dma_reception)(void __iomem *ioaddr, u32 chan);
> void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx);
> void (*disable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
> @@ -261,6 +262,8 @@ struct stmmac_dma_ops {
> stmmac_do_void_callback(__priv, dma, dma_diagnostic_fr, __args)
> #define stmmac_enable_dma_transmission(__priv, __args...) \
> stmmac_do_void_callback(__priv, dma, enable_dma_transmission, __args)
> +#define stmmac_enable_dma_reception(__priv, __args...) \
> + stmmac_do_void_callback(__priv, dma, enable_dma_reception, __args)
> #define stmmac_enable_dma_irq(__priv, __args...) \
> stmmac_do_void_callback(__priv, dma, enable_dma_irq, __priv, __args)
> #define stmmac_disable_dma_irq(__priv, __args...) \
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 6cacedb2c9b3fefdd4c9ec8ba98d389443d21ebd..1ecca60baf74286da7f156b4c3c835b3cbabf1ba 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4973,6 +4973,8 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
> rx_q->rx_tail_addr = rx_q->dma_rx_phy +
> (rx_q->dirty_rx * sizeof(struct dma_desc));
> stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue);
> + /* Wake up Rx DMA from the suspend state if required */
> + stmmac_enable_dma_reception(priv, priv->ioaddr, queue);
> }
>
> static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv,
>
> ---
> base-commit: e3daf0e7fe9758613bec324fd606ed9caa187f74
> change-id: 20251125-a10_ext_fix-5951805b9906
>
> Best regards,
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 17:15 ` Maxime Chevallier
@ 2025-11-25 18:03 ` Maxime Chevallier
2025-11-26 6:07 ` G Thomas, Rohan
0 siblings, 1 reply; 8+ messages in thread
From: Maxime Chevallier @ 2025-11-25 18:03 UTC (permalink / raw)
To: rohan.g.thomas, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue
Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Matthew Gerlach
On 25/11/2025 18:15, Maxime Chevallier wrote:
> Hi Rohan,
>
> On 25/11/2025 17:37, Rohan G Thomas via B4 Relay wrote:
>> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>>
>> In Store and Forward mode, flushing frames when the receive buffer is
>> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
>> in buffering of a few frames in the FIFO without triggering Rx DMA
>> from transferring the data to the system memory until another packet
>> is received. Once the issue happens, for a ping request, the packet is
>> forwarded to the system memory only after we receive another packet
>> and hece we observe a latency equivalent to the ping interval.
>>
>> 64 bytes from 192.168.2.100: seq=1 ttl=64 time=1000.344 ms
>>
>> Also, we can observe constant gmacgrp_debug register value of
>> 0x00000120, which indicates "Reading frame data".
>>
>> The issue is not reproducible after disabling frame flushing when Rx
>> buffer is unavailable. But in that case, the Rx DMA enters a suspend
>> state due to buffer unavailability. To resume operation, software
>> must write to the receive_poll_demand register after adding new
>> descriptors, which reactivates the Rx DMA.
>>
>> This issue is observed in the socfpga platforms which has dwmac1000 IP
>> like Arria 10, Cyclone V and Agilex 7. Issue is reproducible after
>> running iperf3 server at the DUT for UDP lower packet sizes.
>>
>> Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
>> Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
>
> Should this be a fix ?
>
> Can you elaborate on how to reproduce this ? I've given this a try on
> CycloneV and I can't see any difference in the ping results and iperf3
> results.
>
> From the DUT, I've tried :
> - iperf3 -c 192.168.X.X -u -b 0 -l 64
> - iperf3 -c 192.168.X.X -u -b 0 -l 64 -R
Ah ! my iperf3 peer wasn't sending packets hard enough. I switched to a
more powerful LP and I can now see the huge latencies by doing :
1 - ping the CycloneV from test machine :
PING 192.168.2.41 (192.168.2.41) 56(84) bytes of data.
64 bytes from 192.168.2.41: icmp_seq=1 ttl=64 time=0.387 ms
64 bytes from 192.168.2.41: icmp_seq=2 ttl=64 time=0.196 ms
64 bytes from 192.168.2.41: icmp_seq=3 ttl=64 time=0.193 ms
64 bytes from 192.168.2.41: icmp_seq=4 ttl=64 time=0.207 ms
2 - on cycloneV, Run iperf3 -c 192.168.X.X -u -b 0 -l 64 -R
3 - Re-ping :
PING 192.168.2.41 (192.168.2.41) 56(84) bytes of data.
64 bytes from 192.168.2.41: icmp_seq=1 ttl=64 time=1022 ms
64 bytes from 192.168.2.41: icmp_seq=2 ttl=64 time=1024 ms
64 bytes from 192.168.2.41: icmp_seq=3 ttl=64 time=1024 ms
This behaviour disapears after your patch :)
Maxime
> - iperf3 -c 192.168.X.X
> - iperf3 -c 192.168.X.X -R
>
> I'm reading the same results with and without the patch
>
> I've done ping tests as well, the latency seems to be the same with and
> without this patch, at around 0.193ms RTT.
>
> I'm not familiar with the SF_DMA_MODE though, any thing special to do to
> enter that mode ?
>
> Thanks,
>
> Maxime
>
>> ---
>> drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 5 +++--
>> drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
>> drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 5 +++++
>> drivers/net/ethernet/stmicro/stmmac/hwif.h | 3 +++
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++
>> 5 files changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
>> index 6d9b8fac3c6d0fd76733ab4a1a8cce2420fa40b4..5877fec9f6c30ed18cdcf5398816e444e0bd0091 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
>> @@ -135,10 +135,10 @@ static void dwmac1000_dma_operation_mode_rx(struct stmmac_priv *priv,
>>
>> if (mode == SF_DMA_MODE) {
>> pr_debug("GMAC: enable RX store and forward mode\n");
>> - csr6 |= DMA_CONTROL_RSF;
>> + csr6 |= DMA_CONTROL_RSF | DMA_CONTROL_DFF;
>> } else {
>> pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
>> - csr6 &= ~DMA_CONTROL_RSF;
>> + csr6 &= ~(DMA_CONTROL_RSF | DMA_CONTROL_DFF);
>> csr6 &= DMA_CONTROL_TC_RX_MASK;
>> if (mode <= 32)
>> csr6 |= DMA_CONTROL_RTC_32;
>> @@ -262,6 +262,7 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
>> .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
>> .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
>> .enable_dma_transmission = dwmac_enable_dma_transmission,
>> + .enable_dma_reception = dwmac_enable_dma_reception,
>> .enable_dma_irq = dwmac_enable_dma_irq,
>> .disable_dma_irq = dwmac_disable_dma_irq,
>> .start_tx = dwmac_dma_start_tx,
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
>> index d1c149f7a3dd9e472b237101666e11878707f0f2..054ecb20ce3f68bce5da3efaf36acf33e430d3f0 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
>> @@ -169,6 +169,7 @@ static inline u32 dma_chan_base_addr(u32 base, u32 chan)
>> #define NUM_DWMAC4_DMA_REGS 27
>>
>> void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan);
>> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan);
>> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
>> u32 chan, bool rx, bool tx);
>> void dwmac_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
>> index 467f1a05747ecf0be5b9f3392cd3d2049d676c21..97a803d68e3a2f120beaa7c3254748cf404236df 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
>> @@ -33,6 +33,11 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan)
>> writel(1, ioaddr + DMA_CHAN_XMT_POLL_DEMAND(chan));
>> }
>>
>> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan)
>> +{
>> + writel(1, ioaddr + DMA_CHAN_RCV_POLL_DEMAND(chan));
>> +}
>> +
>> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
>> u32 chan, bool rx, bool tx)
>> {
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
>> index f257ce4b6c66e0bbd3180d54ac7f5be934153a6b..df6e8a567b1f646f83effbb38d8e53441a6f6150 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
>> @@ -201,6 +201,7 @@ struct stmmac_dma_ops {
>> void (*dma_diagnostic_fr)(struct stmmac_extra_stats *x,
>> void __iomem *ioaddr);
>> void (*enable_dma_transmission)(void __iomem *ioaddr, u32 chan);
>> + void (*enable_dma_reception)(void __iomem *ioaddr, u32 chan);
>> void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
>> u32 chan, bool rx, bool tx);
>> void (*disable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
>> @@ -261,6 +262,8 @@ struct stmmac_dma_ops {
>> stmmac_do_void_callback(__priv, dma, dma_diagnostic_fr, __args)
>> #define stmmac_enable_dma_transmission(__priv, __args...) \
>> stmmac_do_void_callback(__priv, dma, enable_dma_transmission, __args)
>> +#define stmmac_enable_dma_reception(__priv, __args...) \
>> + stmmac_do_void_callback(__priv, dma, enable_dma_reception, __args)
>> #define stmmac_enable_dma_irq(__priv, __args...) \
>> stmmac_do_void_callback(__priv, dma, enable_dma_irq, __priv, __args)
>> #define stmmac_disable_dma_irq(__priv, __args...) \
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index 6cacedb2c9b3fefdd4c9ec8ba98d389443d21ebd..1ecca60baf74286da7f156b4c3c835b3cbabf1ba 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -4973,6 +4973,8 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
>> rx_q->rx_tail_addr = rx_q->dma_rx_phy +
>> (rx_q->dirty_rx * sizeof(struct dma_desc));
>> stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue);
>> + /* Wake up Rx DMA from the suspend state if required */
>> + stmmac_enable_dma_reception(priv, priv->ioaddr, queue);
>> }
>>
>> static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv,
>>
>> ---
>> base-commit: e3daf0e7fe9758613bec324fd606ed9caa187f74
>> change-id: 20251125-a10_ext_fix-5951805b9906
>>
>> Best regards,
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 18:03 ` Maxime Chevallier
@ 2025-11-26 6:07 ` G Thomas, Rohan
0 siblings, 0 replies; 8+ messages in thread
From: G Thomas, Rohan @ 2025-11-26 6:07 UTC (permalink / raw)
To: Maxime Chevallier, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue
Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Matthew Gerlach
Hi Maxime,
On 11/25/2025 11:33 PM, Maxime Chevallier wrote:
>
>
> On 25/11/2025 18:15, Maxime Chevallier wrote:
>> Hi Rohan,
>>
>> On 25/11/2025 17:37, Rohan G Thomas via B4 Relay wrote:
>>> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>>>
>>> In Store and Forward mode, flushing frames when the receive buffer is
>>> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
>>> in buffering of a few frames in the FIFO without triggering Rx DMA
>>> from transferring the data to the system memory until another packet
>>> is received. Once the issue happens, for a ping request, the packet is
>>> forwarded to the system memory only after we receive another packet
>>> and hece we observe a latency equivalent to the ping interval.
>>>
>>> 64 bytes from 192.168.2.100: seq=1 ttl=64 time=1000.344 ms
>>>
>>> Also, we can observe constant gmacgrp_debug register value of
>>> 0x00000120, which indicates "Reading frame data".
>>>
>>> The issue is not reproducible after disabling frame flushing when Rx
>>> buffer is unavailable. But in that case, the Rx DMA enters a suspend
>>> state due to buffer unavailability. To resume operation, software
>>> must write to the receive_poll_demand register after adding new
>>> descriptors, which reactivates the Rx DMA.
>>>
>>> This issue is observed in the socfpga platforms which has dwmac1000 IP
>>> like Arria 10, Cyclone V and Agilex 7. Issue is reproducible after
>>> running iperf3 server at the DUT for UDP lower packet sizes.
>>>
>>> Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
>>> Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
>>
>> Should this be a fix ?
>>
>> Can you elaborate on how to reproduce this ? I've given this a try on
>> CycloneV and I can't see any difference in the ping results and iperf3
>> results.
>>
>> From the DUT, I've tried :
>> - iperf3 -c 192.168.X.X -u -b 0 -l 64
>> - iperf3 -c 192.168.X.X -u -b 0 -l 64 -R
>
> Ah ! my iperf3 peer wasn't sending packets hard enough. I switched to a
> more powerful LP and I can now see the huge latencies by doing :
>
> 1 - ping the CycloneV from test machine :
>
> PING 192.168.2.41 (192.168.2.41) 56(84) bytes of data.
> 64 bytes from 192.168.2.41: icmp_seq=1 ttl=64 time=0.387 ms
> 64 bytes from 192.168.2.41: icmp_seq=2 ttl=64 time=0.196 ms
> 64 bytes from 192.168.2.41: icmp_seq=3 ttl=64 time=0.193 ms
> 64 bytes from 192.168.2.41: icmp_seq=4 ttl=64 time=0.207 ms
>
> 2 - on cycloneV, Run iperf3 -c 192.168.X.X -u -b 0 -l 64 -R
>
> 3 - Re-ping :
>
> PING 192.168.2.41 (192.168.2.41) 56(84) bytes of data.
> 64 bytes from 192.168.2.41: icmp_seq=1 ttl=64 time=1022 ms
> 64 bytes from 192.168.2.41: icmp_seq=2 ttl=64 time=1024 ms
> 64 bytes from 192.168.2.41: icmp_seq=3 ttl=64 time=1024 ms
>
>
> This behaviour disapears after your patch :)
>
> Maxime
>
Thanks for testing the patch.
Yes, this is the scenario adressed with the patch. By default driver
configures for SF_DMA_MODE and issue is reproducible when we stress the
mac with Rx Buffer Unavailable scenarios repeatedly.
>
>> - iperf3 -c 192.168.X.X
>> - iperf3 -c 192.168.X.X -R
>>
>> I'm reading the same results with and without the patch
>>
>> I've done ping tests as well, the latency seems to be the same with and
>> without this patch, at around 0.193ms RTT.
>>
>> I'm not familiar with the SF_DMA_MODE though, any thing special to do to
>> enter that mode ?
>>
>> Thanks,
>>
>> Maxime
>>
>>> ---
>>> drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 5 +++--
>>> drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
>>> drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 5 +++++
>>> drivers/net/ethernet/stmicro/stmmac/hwif.h | 3 +++
>>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++
>>> 5 files changed, 14 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
>>> index 6d9b8fac3c6d0fd76733ab4a1a8cce2420fa40b4..5877fec9f6c30ed18cdcf5398816e444e0bd0091 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
>>> @@ -135,10 +135,10 @@ static void dwmac1000_dma_operation_mode_rx(struct stmmac_priv *priv,
>>>
>>> if (mode == SF_DMA_MODE) {
>>> pr_debug("GMAC: enable RX store and forward mode\n");
>>> - csr6 |= DMA_CONTROL_RSF;
>>> + csr6 |= DMA_CONTROL_RSF | DMA_CONTROL_DFF;
>>> } else {
>>> pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
>>> - csr6 &= ~DMA_CONTROL_RSF;
>>> + csr6 &= ~(DMA_CONTROL_RSF | DMA_CONTROL_DFF);
>>> csr6 &= DMA_CONTROL_TC_RX_MASK;
>>> if (mode <= 32)
>>> csr6 |= DMA_CONTROL_RTC_32;
>>> @@ -262,6 +262,7 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
>>> .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
>>> .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
>>> .enable_dma_transmission = dwmac_enable_dma_transmission,
>>> + .enable_dma_reception = dwmac_enable_dma_reception,
>>> .enable_dma_irq = dwmac_enable_dma_irq,
>>> .disable_dma_irq = dwmac_disable_dma_irq,
>>> .start_tx = dwmac_dma_start_tx,
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
>>> index d1c149f7a3dd9e472b237101666e11878707f0f2..054ecb20ce3f68bce5da3efaf36acf33e430d3f0 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
>>> @@ -169,6 +169,7 @@ static inline u32 dma_chan_base_addr(u32 base, u32 chan)
>>> #define NUM_DWMAC4_DMA_REGS 27
>>>
>>> void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan);
>>> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan);
>>> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
>>> u32 chan, bool rx, bool tx);
>>> void dwmac_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
>>> index 467f1a05747ecf0be5b9f3392cd3d2049d676c21..97a803d68e3a2f120beaa7c3254748cf404236df 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
>>> @@ -33,6 +33,11 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan)
>>> writel(1, ioaddr + DMA_CHAN_XMT_POLL_DEMAND(chan));
>>> }
>>>
>>> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan)
>>> +{
>>> + writel(1, ioaddr + DMA_CHAN_RCV_POLL_DEMAND(chan));
>>> +}
>>> +
>>> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
>>> u32 chan, bool rx, bool tx)
>>> {
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
>>> index f257ce4b6c66e0bbd3180d54ac7f5be934153a6b..df6e8a567b1f646f83effbb38d8e53441a6f6150 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
>>> @@ -201,6 +201,7 @@ struct stmmac_dma_ops {
>>> void (*dma_diagnostic_fr)(struct stmmac_extra_stats *x,
>>> void __iomem *ioaddr);
>>> void (*enable_dma_transmission)(void __iomem *ioaddr, u32 chan);
>>> + void (*enable_dma_reception)(void __iomem *ioaddr, u32 chan);
>>> void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
>>> u32 chan, bool rx, bool tx);
>>> void (*disable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
>>> @@ -261,6 +262,8 @@ struct stmmac_dma_ops {
>>> stmmac_do_void_callback(__priv, dma, dma_diagnostic_fr, __args)
>>> #define stmmac_enable_dma_transmission(__priv, __args...) \
>>> stmmac_do_void_callback(__priv, dma, enable_dma_transmission, __args)
>>> +#define stmmac_enable_dma_reception(__priv, __args...) \
>>> + stmmac_do_void_callback(__priv, dma, enable_dma_reception, __args)
>>> #define stmmac_enable_dma_irq(__priv, __args...) \
>>> stmmac_do_void_callback(__priv, dma, enable_dma_irq, __priv, __args)
>>> #define stmmac_disable_dma_irq(__priv, __args...) \
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> index 6cacedb2c9b3fefdd4c9ec8ba98d389443d21ebd..1ecca60baf74286da7f156b4c3c835b3cbabf1ba 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> @@ -4973,6 +4973,8 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
>>> rx_q->rx_tail_addr = rx_q->dma_rx_phy +
>>> (rx_q->dirty_rx * sizeof(struct dma_desc));
>>> stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue);
>>> + /* Wake up Rx DMA from the suspend state if required */
>>> + stmmac_enable_dma_reception(priv, priv->ioaddr, queue);
>>> }
>>>
>>> static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv,
>>>
>>> ---
>>> base-commit: e3daf0e7fe9758613bec324fd606ed9caa187f74
>>> change-id: 20251125-a10_ext_fix-5951805b9906
>>>
>>> Best regards,
>>
>>
>
Best Regards,
Rohan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 16:37 [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable Rohan G Thomas via B4 Relay
2025-11-25 17:15 ` Maxime Chevallier
@ 2025-11-25 18:05 ` Maxime Chevallier
2025-11-25 23:46 ` Russell King (Oracle)
2025-11-27 12:10 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: Maxime Chevallier @ 2025-11-25 18:05 UTC (permalink / raw)
To: rohan.g.thomas, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue
Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Matthew Gerlach
Hi,
On 25/11/2025 17:37, Rohan G Thomas via B4 Relay wrote:
> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>
> In Store and Forward mode, flushing frames when the receive buffer is
> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
> in buffering of a few frames in the FIFO without triggering Rx DMA
> from transferring the data to the system memory until another packet
> is received. Once the issue happens, for a ping request, the packet is
> forwarded to the system memory only after we receive another packet
> and hece we observe a latency equivalent to the ping interval.
>
> 64 bytes from 192.168.2.100: seq=1 ttl=64 time=1000.344 ms
>
> Also, we can observe constant gmacgrp_debug register value of
> 0x00000120, which indicates "Reading frame data".
>
> The issue is not reproducible after disabling frame flushing when Rx
> buffer is unavailable. But in that case, the Rx DMA enters a suspend
> state due to buffer unavailability. To resume operation, software
> must write to the receive_poll_demand register after adding new
> descriptors, which reactivates the Rx DMA.
>
> This issue is observed in the socfpga platforms which has dwmac1000 IP
> like Arria 10, Cyclone V and Agilex 7. Issue is reproducible after
> running iperf3 server at the DUT for UDP lower packet sizes.
>
> Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
> Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
I'll let others comment on the correctness of the dwmac1000 part, but
still :
Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Maxime
> ---
> drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 5 +++--
> drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
> drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 5 +++++
> drivers/net/ethernet/stmicro/stmmac/hwif.h | 3 +++
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++
> 5 files changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
> index 6d9b8fac3c6d0fd76733ab4a1a8cce2420fa40b4..5877fec9f6c30ed18cdcf5398816e444e0bd0091 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
> @@ -135,10 +135,10 @@ static void dwmac1000_dma_operation_mode_rx(struct stmmac_priv *priv,
>
> if (mode == SF_DMA_MODE) {
> pr_debug("GMAC: enable RX store and forward mode\n");
> - csr6 |= DMA_CONTROL_RSF;
> + csr6 |= DMA_CONTROL_RSF | DMA_CONTROL_DFF;
> } else {
> pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
> - csr6 &= ~DMA_CONTROL_RSF;
> + csr6 &= ~(DMA_CONTROL_RSF | DMA_CONTROL_DFF);
> csr6 &= DMA_CONTROL_TC_RX_MASK;
> if (mode <= 32)
> csr6 |= DMA_CONTROL_RTC_32;
> @@ -262,6 +262,7 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
> .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
> .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
> .enable_dma_transmission = dwmac_enable_dma_transmission,
> + .enable_dma_reception = dwmac_enable_dma_reception,
> .enable_dma_irq = dwmac_enable_dma_irq,
> .disable_dma_irq = dwmac_disable_dma_irq,
> .start_tx = dwmac_dma_start_tx,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> index d1c149f7a3dd9e472b237101666e11878707f0f2..054ecb20ce3f68bce5da3efaf36acf33e430d3f0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> @@ -169,6 +169,7 @@ static inline u32 dma_chan_base_addr(u32 base, u32 chan)
> #define NUM_DWMAC4_DMA_REGS 27
>
> void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan);
> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan);
> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx);
> void dwmac_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> index 467f1a05747ecf0be5b9f3392cd3d2049d676c21..97a803d68e3a2f120beaa7c3254748cf404236df 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> @@ -33,6 +33,11 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr, u32 chan)
> writel(1, ioaddr + DMA_CHAN_XMT_POLL_DEMAND(chan));
> }
>
> +void dwmac_enable_dma_reception(void __iomem *ioaddr, u32 chan)
> +{
> + writel(1, ioaddr + DMA_CHAN_RCV_POLL_DEMAND(chan));
> +}
> +
> void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx)
> {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> index f257ce4b6c66e0bbd3180d54ac7f5be934153a6b..df6e8a567b1f646f83effbb38d8e53441a6f6150 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> @@ -201,6 +201,7 @@ struct stmmac_dma_ops {
> void (*dma_diagnostic_fr)(struct stmmac_extra_stats *x,
> void __iomem *ioaddr);
> void (*enable_dma_transmission)(void __iomem *ioaddr, u32 chan);
> + void (*enable_dma_reception)(void __iomem *ioaddr, u32 chan);
> void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx);
> void (*disable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
> @@ -261,6 +262,8 @@ struct stmmac_dma_ops {
> stmmac_do_void_callback(__priv, dma, dma_diagnostic_fr, __args)
> #define stmmac_enable_dma_transmission(__priv, __args...) \
> stmmac_do_void_callback(__priv, dma, enable_dma_transmission, __args)
> +#define stmmac_enable_dma_reception(__priv, __args...) \
> + stmmac_do_void_callback(__priv, dma, enable_dma_reception, __args)
> #define stmmac_enable_dma_irq(__priv, __args...) \
> stmmac_do_void_callback(__priv, dma, enable_dma_irq, __priv, __args)
> #define stmmac_disable_dma_irq(__priv, __args...) \
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 6cacedb2c9b3fefdd4c9ec8ba98d389443d21ebd..1ecca60baf74286da7f156b4c3c835b3cbabf1ba 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4973,6 +4973,8 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
> rx_q->rx_tail_addr = rx_q->dma_rx_phy +
> (rx_q->dirty_rx * sizeof(struct dma_desc));
> stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue);
> + /* Wake up Rx DMA from the suspend state if required */
> + stmmac_enable_dma_reception(priv, priv->ioaddr, queue);
> }
>
> static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv,
>
> ---
> base-commit: e3daf0e7fe9758613bec324fd606ed9caa187f74
> change-id: 20251125-a10_ext_fix-5951805b9906
>
> Best regards,
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 16:37 [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable Rohan G Thomas via B4 Relay
2025-11-25 17:15 ` Maxime Chevallier
2025-11-25 18:05 ` Maxime Chevallier
@ 2025-11-25 23:46 ` Russell King (Oracle)
2025-11-26 6:08 ` G Thomas, Rohan
2025-11-27 12:10 ` patchwork-bot+netdevbpf
3 siblings, 1 reply; 8+ messages in thread
From: Russell King (Oracle) @ 2025-11-25 23:46 UTC (permalink / raw)
To: rohan.g.thomas
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Maxime Coquelin, Alexandre Torgue, Maxime Chevallier,
netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Matthew Gerlach
On Wed, Nov 26, 2025 at 12:37:12AM +0800, Rohan G Thomas via B4 Relay wrote:
> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>
> In Store and Forward mode, flushing frames when the receive buffer is
> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
> in buffering of a few frames in the FIFO without triggering Rx DMA
> from transferring the data to the system memory until another packet
> is received. Once the issue happens, for a ping request, the packet is
> forwarded to the system memory only after we receive another packet
> and hece we observe a latency equivalent to the ping interval.
>
> 64 bytes from 192.168.2.100: seq=1 ttl=64 time=1000.344 ms
>
> Also, we can observe constant gmacgrp_debug register value of
> 0x00000120, which indicates "Reading frame data".
>
> The issue is not reproducible after disabling frame flushing when Rx
> buffer is unavailable. But in that case, the Rx DMA enters a suspend
> state due to buffer unavailability. To resume operation, software
> must write to the receive_poll_demand register after adding new
> descriptors, which reactivates the Rx DMA.
This seems like a sensible writeup, which all seems to make sense,
even though the databook I have seems vague on the effect of the
DFF bit.
> This issue is observed in the socfpga platforms which has dwmac1000 IP
> like Arria 10, Cyclone V and Agilex 7. Issue is reproducible after
> running iperf3 server at the DUT for UDP lower packet sizes.
>
> Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
> Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
Given the above, that Maxime has also tested it which shows a net
benefit, and I've looked through this, even though I can't positively
say it's correct due to the databook vagueness:
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Thanks!
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 23:46 ` Russell King (Oracle)
@ 2025-11-26 6:08 ` G Thomas, Rohan
0 siblings, 0 replies; 8+ messages in thread
From: G Thomas, Rohan @ 2025-11-26 6:08 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Maxime Coquelin, Alexandre Torgue, Maxime Chevallier,
netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Matthew Gerlach
Hi Russell,
On 11/26/2025 5:16 AM, Russell King (Oracle) wrote:
> On Wed, Nov 26, 2025 at 12:37:12AM +0800, Rohan G Thomas via B4 Relay wrote:
>> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>>
>> In Store and Forward mode, flushing frames when the receive buffer is
>> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
>> in buffering of a few frames in the FIFO without triggering Rx DMA
>> from transferring the data to the system memory until another packet
>> is received. Once the issue happens, for a ping request, the packet is
>> forwarded to the system memory only after we receive another packet
>> and hece we observe a latency equivalent to the ping interval.
>>
>> 64 bytes from 192.168.2.100: seq=1 ttl=64 time=1000.344 ms
>>
>> Also, we can observe constant gmacgrp_debug register value of
>> 0x00000120, which indicates "Reading frame data".
>>
>> The issue is not reproducible after disabling frame flushing when Rx
>> buffer is unavailable. But in that case, the Rx DMA enters a suspend
>> state due to buffer unavailability. To resume operation, software
>> must write to the receive_poll_demand register after adding new
>> descriptors, which reactivates the Rx DMA.
>
>
> This seems like a sensible writeup, which all seems to make sense,
> even though the databook I have seems vague on the effect of the
> DFF bit.
>
>> This issue is observed in the socfpga platforms which has dwmac1000 IP
>> like Arria 10, Cyclone V and Agilex 7. Issue is reproducible after
>> running iperf3 server at the DUT for UDP lower packet sizes.
>>
>> Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
>> Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
>
> Given the above, that Maxime has also tested it which shows a net
> benefit, and I've looked through this, even though I can't positively
> say it's correct due to the databook vagueness:
>
> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
>
> Thanks!
>
Thanks for reviewing the patch.
Best Regards,
Rohan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
2025-11-25 16:37 [PATCH net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable Rohan G Thomas via B4 Relay
` (2 preceding siblings ...)
2025-11-25 23:46 ` Russell King (Oracle)
@ 2025-11-27 12:10 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-11-27 12:10 UTC (permalink / raw)
To: G, Thomas, Rohan
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, mcoquelin.stm32,
alexandre.torgue, maxime.chevallier, netdev, linux-stm32,
linux-arm-kernel, linux-kernel, matthew.gerlach
Hello:
This patch was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Wed, 26 Nov 2025 00:37:12 +0800 you wrote:
> From: Rohan G Thomas <rohan.g.thomas@altera.com>
>
> In Store and Forward mode, flushing frames when the receive buffer is
> unavailable, can cause the MTL Rx FIFO to go out of sync. This results
> in buffering of a few frames in the FIFO without triggering Rx DMA
> from transferring the data to the system memory until another packet
> is received. Once the issue happens, for a ping request, the packet is
> forwarded to the system memory only after we receive another packet
> and hece we observe a latency equivalent to the ping interval.
>
> [...]
Here is the summary with links:
- [net-next] net: stmmac: dwmac: Disable flushing frames on Rx Buffer Unavailable
https://git.kernel.org/netdev/net-next/c/45d100ee0d6e
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread