Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3de85a5 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-stmmac-fix-handling-of-oversized-frames'



Aaro Koskinen says:

====================
net: stmmac: fix handling of oversized frames

I accidentally had MTU size mismatch (9000 vs. 1500) in my network,
and I noticed I could kill a system using stmmac & 1500 MTU simply
by pinging it with "ping -s 2000 ...".

While testing a fix I encountered also some other issues that need fixing.

I have tested these only with enhanced descriptors, so the normal
descriptor changes need a careful review.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 288ac524 057a0c56
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -29,8 +29,10 @@
/* Specific functions used for Ring mode */

/* Enhanced descriptors */
static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end)
static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end,
					   int bfsize)
{
	if (bfsize == BUF_SIZE_16KiB)
		p->des1 |= cpu_to_le32((BUF_SIZE_8KiB
				<< ERDES1_BUFFER2_SIZE_SHIFT)
			   & ERDES1_BUFFER2_SIZE_MASK);
@@ -59,11 +61,15 @@ static inline void enh_set_tx_desc_len_on_ring(struct dma_desc *p, int len)
}

/* Normal descriptors */
static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end)
static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end, int bfsize)
{
	p->des1 |= cpu_to_le32(((BUF_SIZE_2KiB - 1)
				<< RDES1_BUFFER2_SIZE_SHIFT)
	if (bfsize >= BUF_SIZE_2KiB) {
		int bfsize2;

		bfsize2 = min(bfsize - BUF_SIZE_2KiB + 1, BUF_SIZE_2KiB - 1);
		p->des1 |= cpu_to_le32((bfsize2 << RDES1_BUFFER2_SIZE_SHIFT)
			    & RDES1_BUFFER2_SIZE_MASK);
	}

	if (end)
		p->des1 |= cpu_to_le32(RDES1_END_RING);
+1 −1
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, void *next_desc,
}

static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
				   int mode, int end)
				   int mode, int end, int bfsize)
{
	dwmac4_set_rx_owner(p, disable_rx_ic);
}
+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ static int dwxgmac2_get_rx_timestamp_status(void *desc, void *next_desc,
}

static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
				  int mode, int end)
				  int mode, int end, int bfsize)
{
	dwxgmac2_set_rx_owner(p, disable_rx_ic);
}
+16 −6
Original line number Diff line number Diff line
@@ -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++;
@@ -231,6 +236,7 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
	 * It doesn't match with the information reported into the databook.
	 * At any rate, we need to understand if the CSUM hw computation is ok
	 * and report this info to the upper layers. */
	if (likely(ret == good_frame))
		ret = enh_desc_coe_rdes0(!!(rdes0 & RDES0_IPC_CSUM_ERROR),
					 !!(rdes0 & RDES0_FRAME_TYPE),
					 !!(rdes0 & ERDES0_RX_MAC_ADDR));
@@ -259,15 +265,19 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
}

static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
				  int mode, int end)
				  int mode, int end, int bfsize)
{
	int bfsize1;

	p->des0 |= cpu_to_le32(RDES0_OWN);
	p->des1 |= cpu_to_le32(BUF_SIZE_8KiB & ERDES1_BUFFER1_SIZE_MASK);

	bfsize1 = min(bfsize, BUF_SIZE_8KiB);
	p->des1 |= cpu_to_le32(bfsize1 & ERDES1_BUFFER1_SIZE_MASK);

	if (mode == STMMAC_CHAIN_MODE)
		ehn_desc_rx_set_on_chain(p);
	else
		ehn_desc_rx_set_on_ring(p, end);
		ehn_desc_rx_set_on_ring(p, end, bfsize);

	if (disable_rx_ic)
		p->des1 |= cpu_to_le32(ERDES1_DISABLE_IC);
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ struct dma_extended_desc;
struct stmmac_desc_ops {
	/* DMA RX descriptor ring initialization */
	void (*init_rx_desc)(struct dma_desc *p, int disable_rx_ic, int mode,
			int end);
			int end, int bfsize);
	/* DMA TX descriptor ring initialization */
	void (*init_tx_desc)(struct dma_desc *p, int mode, int end);
	/* Invoked by the xmit function to prepare the tx descriptor */
Loading