Hi Rafał: ---------------------------------------- > From: [email protected] > To: [email protected]; [email protected] > Date: Thu, 3 Apr 2014 19:26:48 +0200 > Subject: [OpenWrt-Devel] [PATCH] kernel: bgmac: rework patch checking packet > length > > This bgmac patch was an attempt to fix/workaround bug reported in > https://dev.openwrt.org/ticket/7198 noticed on WNR3500L. > Patch assumed length reported by the hardware was 0 and was trying to > read it until getting a different value. This was actually the opposite. > Lenghts were some invalid & huge values that resulted in skb_over_panic. > For example: > skbuff: skb_over_panic: text:83b21074 len:57222 (...) > skbuff: skb_over_panic: text:87af1024 len:43226 (...) > skbuff: skb_over_panic: text:87af5024 len:8739 (...) > > So instead of that not-working patch checking for 0, write a new one > checking for huge values. In case something like that happens, dump > hardware state and drop the packet. >
It seems like it should be checking the returned "flags" in the dma header for an overflow error (the GPL sources for RT-N16 include such a check). Nathan > Signed-off-by: Rafał Miłecki <[email protected]> > --- > .../775-bgmac-check-length-of-received-frame.patch | 50 +++++++++++----------- > 1 file changed, 24 insertions(+), 26 deletions(-) > > diff --git > a/target/linux/generic/patches-3.10/775-bgmac-check-length-of-received-frame.patch > > b/target/linux/generic/patches-3.10/775-bgmac-check-length-of-received-frame.patch > index f708e7d..c3d63b6 100644 > --- > a/target/linux/generic/patches-3.10/775-bgmac-check-length-of-received-frame.patch > +++ > b/target/linux/generic/patches-3.10/775-bgmac-check-length-of-received-frame.patch > @@ -9,33 +9,31 @@ Subject: [PATCH] bgmac: check length of received frame > > --- a/drivers/net/ethernet/broadcom/bgmac.c > +++ b/drivers/net/ethernet/broadcom/bgmac.c > -@@ -349,6 +349,7 @@ static int bgmac_dma_rx_read(struct bgma > - struct sk_buff *skb = slot->skb; > - struct bgmac_rx_header *rx; > - u16 len, flags; > -+ int count; > - > - /* Unmap buffer to make it accessible to the CPU */ > - dma_sync_single_for_cpu(dma_dev, slot->dma_addr, > -@@ -357,6 +358,12 @@ static int bgmac_dma_rx_read(struct bgma > - /* Get info from the header */ > - rx = (struct bgmac_rx_header *)skb->data; > - len = le16_to_cpu(rx->len); > -+ for (count = 0; count < 200; count++) { > -+ len = le16_to_cpu(rx->len); > -+ if (len) > -+ break; > -+ udelay(1); > -+ } > - flags = le16_to_cpu(rx->flags); > - > - do { > -@@ -364,7 +371,7 @@ static int bgmac_dma_rx_read(struct bgma > +@@ -363,6 +363,27 @@ static int bgmac_dma_rx_read(struct bgma > + dma_addr_t old_dma_addr = slot->dma_addr; > int err; > > ++ if (len> BGMAC_RX_MAX_FRAME_SIZE) { > ++ struct bgmac_dma_desc *dma_desc = ring->cpu_base + ring->start; > ++ > ++ bgmac_err(bgmac, "Hardware reported invalid packet length %d for slot > %d!\n", len, ring->start); > ++ bgmac_err(bgmac, "flags: 0x%04X\n", flags); > ++ bgmac_err(bgmac, "ctl0: 0x%08X\tctl1: 0x%08X\n", > le32_to_cpu(dma_desc->ctl0), le32_to_cpu(dma_desc->ctl1)); > ++ > ++ bgmac_err(bgmac, " BGMAC_DMA_RX_CTL: 0x%08X\n", bgmac_read(bgmac, > ring->mmio_base + BGMAC_DMA_RX_CTL)); > ++ bgmac_err(bgmac, " BGMAC_DMA_RX_INDEX: 0x%08X\n", bgmac_read(bgmac, > ring->mmio_base + BGMAC_DMA_RX_INDEX)); > ++ bgmac_err(bgmac, "BGMAC_DMA_RX_RINGLO: 0x%08X\n", bgmac_read(bgmac, > ring->mmio_base + BGMAC_DMA_RX_RINGLO)); > ++ bgmac_err(bgmac, "BGMAC_DMA_RX_RINGHI: 0x%08X\n", bgmac_read(bgmac, > ring->mmio_base + BGMAC_DMA_RX_RINGHI)); > ++ bgmac_err(bgmac, "BGMAC_DMA_RX_STATUS: 0x%08X\n", bgmac_read(bgmac, > ring->mmio_base + BGMAC_DMA_RX_STATUS)); > ++ bgmac_err(bgmac, " BGMAC_DMA_RX_ERROR: 0x%08X\n", bgmac_read(bgmac, > ring->mmio_base + BGMAC_DMA_RX_ERROR)); > ++ > ++ dma_sync_single_for_device(dma_dev, > ++ slot->dma_addr, > ++ BGMAC_RX_BUF_SIZE, > ++ DMA_FROM_DEVICE); > ++ break; > ++ } > ++ > /* Check for poison and drop or pass the packet */ > -- if (len == 0xdead && flags == 0xbeef) { > -+ if (!len || (len == 0xdead && flags == 0xbeef)) { > + if (len == 0xdead && flags == 0xbeef) { > bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", > - ring->start); > - dma_sync_single_for_device(dma_dev, > -- > 1.8.4.5 > _______________________________________________ > openwrt-devel mailing list > [email protected] > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel > _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
