summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAaro Koskinen <aaro.koskinen@nokia.com>2019-03-27 22:35:39 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-08 07:21:48 +0200
commitf86c1d3f10a2c280a9ff9fe0a90943659f768742 (patch)
tree2a0b3dd22f6f35d29e6f31d12894025f80d2da0c /drivers/net
parent0ab012e3df48e163f644f88e0d1110b9c21286d5 (diff)
downloadlinux-stable-f86c1d3f10a2c280a9ff9fe0a90943659f768742.tar.gz
linux-stable-f86c1d3f10a2c280a9ff9fe0a90943659f768742.tar.bz2
linux-stable-f86c1d3f10a2c280a9ff9fe0a90943659f768742.zip
net: stmmac: fix dropping of multi-descriptor RX frames
[ Upstream commit 8ac0c24fe1c256af6644caf3d311029440ec2fbd ] Packets without the last descriptor set should be dropped early. If we receive a frame larger than the DMA buffer, the HW will continue using the next descriptor. Driver mistakes these as individual frames, and sometimes a truncated frame (without the LD set) may look like a valid packet. This fixes a strange issue where the system replies to 4098-byte ping although the MTU/DMA buffer size is set to 4096, and yet at the same time it's logging an oversized packet. Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/enh_desc.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index c42ef6c729c0..5202d6ad7919 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -201,6 +201,11 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
if (unlikely(rdes0 & RDES0_OWN))
return dma_own;
+ if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
+ stats->rx_length_errors++;
+ return discard_frame;
+ }
+
if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) {
if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) {
x->rx_desc++;