All of lore.kernel.org
 help / color / mirror / Atom feed
From: Felix Fietkau <nbd@openwrt.org>
To: netdev@vger.kernel.org
Cc: zajec5@gmail.com, hauke@hauke-m.de
Subject: [PATCH v6 8/9] bgmac: fix DMA rx corruption
Date: Tue, 14 Apr 2015 01:42:16 +0200	[thread overview]
Message-ID: <1428968537-6181-8-git-send-email-nbd@openwrt.org> (raw)
In-Reply-To: <1428968537-6181-1-git-send-email-nbd@openwrt.org>

The driver needs to inform the hardware about the first invalid (not yet
filled) rx slot, by writing its DMA descriptor pointer offset to the
BGMAC_DMA_RX_INDEX register.

This register was set to a value exceeding the rx ring size, effectively
allowing the hardware constant access to the full ring, regardless of
which slots are initialized.

To fix this issue, always mark the last filled rx slot as invalid.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/ethernet/broadcom/bgmac.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index aad80a7..a07a62e 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -362,6 +362,16 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
 	return 0;
 }
 
+static void bgmac_dma_rx_update_index(struct bgmac *bgmac,
+				      struct bgmac_dma_ring *ring)
+{
+	dma_wmb();
+
+	bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
+		    ring->index_base +
+		    ring->end * sizeof(struct bgmac_dma_desc));
+}
+
 static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac,
 				    struct bgmac_dma_ring *ring, int desc_idx)
 {
@@ -380,6 +390,8 @@ static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac,
 	dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr));
 	dma_desc->ctl0 = cpu_to_le32(ctl0);
 	dma_desc->ctl1 = cpu_to_le32(ctl1);
+
+	ring->end = desc_idx;
 }
 
 static void bgmac_dma_rx_poison_buf(struct device *dma_dev,
@@ -407,9 +419,7 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
 	end_slot &= BGMAC_DMA_RX_STATDPTR;
 	end_slot /= sizeof(struct bgmac_dma_desc);
 
-	ring->end = end_slot;
-
-	while (ring->start != ring->end) {
+	while (ring->start != end_slot) {
 		struct device *dma_dev = bgmac->core->dma_dev;
 		struct bgmac_slot_info *slot = &ring->slots[ring->start];
 		struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET;
@@ -471,6 +481,8 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
 			break;
 	}
 
+	bgmac_dma_rx_update_index(bgmac, ring);
+
 	return handled;
 }
 
@@ -690,6 +702,8 @@ static int bgmac_dma_init(struct bgmac *bgmac)
 		if (ring->unaligned)
 			bgmac_dma_rx_enable(bgmac, ring);
 
+		ring->start = 0;
+		ring->end = 0;
 		for (j = 0; j < ring->num_slots; j++) {
 			err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
 			if (err)
@@ -698,12 +712,7 @@ static int bgmac_dma_init(struct bgmac *bgmac)
 			bgmac_dma_rx_setup_desc(bgmac, ring, j);
 		}
 
-		bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
-			    ring->index_base +
-			    ring->num_slots * sizeof(struct bgmac_dma_desc));
-
-		ring->start = 0;
-		ring->end = 0;
+		bgmac_dma_rx_update_index(bgmac, ring);
 	}
 
 	return 0;
-- 
2.2.2

  parent reply	other threads:[~2015-04-13 23:42 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-13 23:42 [PATCH v6 1/9] bgmac: simplify tx ring index handling Felix Fietkau
2015-04-13 23:42 ` [PATCH v6 2/9] bgmac: leave interrupts disabled as long as there is work to do Felix Fietkau
2015-04-14  5:40   ` Rafał Miłecki
2015-04-13 23:42 ` [PATCH v6 3/9] bgmac: set received skb headroom to NET_SKB_PAD Felix Fietkau
2015-04-13 23:42 ` [PATCH v6 4/9] bgmac: simplify/optimize rx DMA error handling Felix Fietkau
2015-04-14  5:55   ` Rafał Miłecki
2015-04-14  9:13     ` Felix Fietkau
2015-04-14  9:19       ` Rafał Miłecki
2015-04-14  9:26         ` Felix Fietkau
2015-04-14  9:32           ` Rafał Miłecki
2015-04-14  9:37           ` Rafał Miłecki
2015-04-13 23:42 ` [PATCH v6 5/9] bgmac: add check for oversized packets Felix Fietkau
2015-04-14  5:56   ` Rafał Miłecki
2015-04-13 23:42 ` [PATCH v6 6/9] bgmac: increase rx ring size from 511 to 512 Felix Fietkau
2015-04-14  5:57   ` Rafał Miłecki
2015-04-13 23:42 ` [PATCH v6 7/9] bgmac: simplify dma init/cleanup Felix Fietkau
2015-04-14  7:24   ` Rafał Miłecki
2015-04-13 23:42 ` Felix Fietkau [this message]
2015-04-13 23:42 ` [PATCH v6 9/9] bgmac: drop ring->num_slots Felix Fietkau
2015-04-14  6:38   ` Rafał Miłecki
2015-04-14  5:38 ` [PATCH v6 1/9] bgmac: simplify tx ring index handling Rafał Miłecki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1428968537-6181-8-git-send-email-nbd@openwrt.org \
    --to=nbd@openwrt.org \
    --cc=hauke@hauke-m.de \
    --cc=netdev@vger.kernel.org \
    --cc=zajec5@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.