On 30.11.2018 20:21, Anssi Hannula wrote:
> Bit RX_USED set to 0 in the address field allows the controller to write
> data to the receive buffer descriptor.
> 
> The driver does not ensure the ctrl field is ready (cleared) when the
> controller sees the RX_USED=0 written by the driver. The ctrl field might
> only be cleared after the controller has already updated it according to
> a newly received frame, causing the frame to be discarded in gem_rx() due
> to unexpected ctrl field contents.
> 
> A message is logged when the above scenario occurs:
> 
>   macb ff0b0000.ethernet eth0: not whole frame pointed by descriptor
> > Fix the issue by ensuring that when the controller sees RX_USED=0 the
> ctrl field is already cleared.
> 
> This issue was observed on a ZynqMP based system.
> 
> Signed-off-by: Anssi Hannula <anssi.hann...@bitwise.fi>
> Fixes: 4df95131ea80 ("net/macb: change RX path for GEM")
> Cc: Nicolas Ferre <nicolas.fe...@microchip.com>
> ---
>  drivers/net/ethernet/cadence/macb_main.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/cadence/macb_main.c 
> b/drivers/net/ethernet/cadence/macb_main.c
> index 0bc2aab7be40..430b7a0f5436 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -935,14 +935,19 @@ static void gem_rx_refill(struct macb_queue *queue)
>  
>                       if (entry == bp->rx_ring_size - 1)
>                               paddr |= MACB_BIT(RX_WRAP);
> -                     macb_set_addr(bp, desc, paddr);
>                       desc->ctrl = 0;
> +                     /* Setting addr clears RX_USED and allows reception,
> +                      * make sure ctrl is cleared first to avoid a race.
> +                      */
> +                     dma_wmb();

Same here as in patch 1/1 with regards to memory barrier.

> +                     macb_set_addr(bp, desc, paddr);
>  
>                       /* properly align Ethernet header */
>                       skb_reserve(skb, NET_IP_ALIGN);
>               } else {
> -                     desc->addr &= ~MACB_BIT(RX_USED);
>                       desc->ctrl = 0;
> +                     dma_wmb();

Ditto

> +                     desc->addr &= ~MACB_BIT(RX_USED);
>               }
>       }
>  
> 

Reply via email to