gianfar: fix size of scatter-gathered frames
authorZefir Kurtisi <zefir.kurtisi@neratec.com>
Mon, 22 Aug 2016 13:58:12 +0000 (15:58 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 23 Aug 2016 23:49:00 +0000 (16:49 -0700)
commit6c389fc931bcda88940c809f752ada6d7799482c
tree761cdda1a17159704b8aad39b666c42cbbf5a31b
parentb323431bc017e9862870cbbac004774c769ee112
gianfar: fix size of scatter-gathered frames

The current scatter-gather logic in gianfar is flawed, since
it does not consider the eTSEC's RxBD 'Data Length' field is
context depening: for the last fragment it contains the full
frame size, while fragments contain the fragment size, which
equals the value written to register MRBLR.

This causes data corruption as soon as the hardware starts
to fragment receiving frames. As a result, the size of
fragmented frames is increased by
(nr_frags - 1) * MRBLR

We first noticed this issue working with DSA, where an ICMP
request sized 1472 bytes causes the scatter-gather logic to
kick in. The full Ethernet frame (1518) gets increased by
DSA (4), GMAC_FCB_LEN (8), and FSL_GIANFAR_DEV_HAS_TIMER
(priv->padding=8) to a total of 1538 octets, which is
fragmented by the hardware and reconstructed by the driver
to a 3074 octet frame.

This patch fixes the problem by adjusting the size of
the last fragment.

It was tested by setting MRBLR to different multiples of
64, proving correct scatter-gather operation on frames
with up to 9000 octets in size.

Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/gianfar.c