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

Reply via email to