On Thursday 26 March 2009 20:42:29 Francesco Gringoli wrote:
> I spent more time debugging this issue. I found something interesting:  
> when we ask the firmware to pass corrupted frames, it can happen  
> (actually it happens frequently if traffic is high) that the firmware  
> detects something was received even if the internal rx buffer is  
> completely empty while SPR_RXE_FRAMELEN is > 0. In this case, the  
> firmware jumps to push_frame_into_fifo anyway and raises a rx irq. The  
> kernel handles this dma event and b43 thinks that a frame has been  
> received, instead the dma buffer is filled with random data (sometimes  
> with data of a previous packet), at the end a skb with something that  
> was not a packet is passed to mac80211. This happens with both  
> original and open firmwares.
> 
> I wrote this patch so that b43 can understand if something was  
> actually transferred during the dma event: basically, it always fills  
> the plcp part of the dma buffer with impossible data, so if this  
> impossible data is still there after dma event this means that nothing  
> was transferred. This avoid fake packets to be feed into the rx queue  
> (e.g., for those interested in capturing corrupted frames).

Yes this is an interesting idea and a rather cheap workaround.
I think I will implement slightly different, however.

> Cheers,
> -FG
> 
> Signed-off-by: Francesco Gringoli <[email protected]>
> 
> Index: wireless-testing/drivers/net/wireless/b43/xmit.c
> ===================================================================
> --- drivers/net/wireless/b43/dma.c      2009-03-26 19:31:37.000000000  
> +0100
> +++ drivers/net/wireless/b43/dma.c      2009-03-26 20:08:34.000000000  
> +0100
> @@ -568,6 +568,7 @@
>          skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
>          if (unlikely(!skb))
>                  return -ENOMEM;
> +       memset(skb->data + ring->frameoffset, 0xff, 8);
>          dmaaddr = map_descbuffer(ring, skb->data, ring- 
>  >rx_buffersize, 0);
>          if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize,  
> 0)) {
>                  /* ugh. try to realloc in zone_dma */
> @@ -578,6 +579,7 @@
>                  skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
>                  if (unlikely(!skb))
>                          return -ENOMEM;
> +               memset(skb->data + ring->frameoffset, 0xff, 8);
>                  dmaaddr = map_descbuffer(ring, skb->data,
>                                           ring->rx_buffersize, 0);
>                  if (b43_dma_mapping_error(ring, dmaaddr, ring- 
>  >rx_buffersize, 0)) {
> --- drivers/net/wireless/b43/xmit.c     2009-03-26 19:41:53.000000000  
> +0100
> +++ drivers/net/wireless/b43/xmit.c     2009-03-26 20:08:16.000000000  
> +0100
> @@ -527,6 +527,7 @@
>          u16 chanid;
>          u16 phytype;
>          int padding;
> +       u8 *plcp_check;
> 
>          memset(&status, 0, sizeof(status));
> 
> @@ -560,6 +561,17 @@
>                  goto drop;
>          }
>          plcp = (struct b43_plcp_hdr6 *)(skb->data + padding);
> +       plcp_check = (u8*) plcp;
> +       if(plcp_check[0] == 0xff &&
> +               plcp_check[1] == 0xff &&
> +               plcp_check[2] == 0xff &&
> +               plcp_check[3] == 0xff &&
> +               plcp_check[4] == 0xff &&
> +               plcp_check[5] == 0xff) {
> +               b43dbg(dev->wl, "RX: no packet received?\n");
> +               goto drop;
> +       }
> +
>          skb_pull(skb, sizeof(struct b43_plcp_hdr6) + padding);
>          /* The skb contains the Wireless Header + payload data now */
>          if (unlikely(skb->len < (2 + 2 + 6 /*minimum hdr */  +  
> FCS_LEN))) {
> 
> 
> 



-- 
Greetings, Michael.
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to