On Mar 26, 2009, at 5:44 PM, Michael Buesch wrote: > On Tuesday 24 March 2009 19:57:33 Francesco Gringoli wrote: >> The bad thing is that sometimes a bad alignment is not resolved in a >> rate_idx = -1 as the first byte of the plcp (which is not actually >> the >> first since the pad was wrong) is mistakenly resolved to a valid >> encoding. > > I think this case is extremely rare and this is nothing we need to > worry about. > A checksum is no guarantee either that the frame really is not > corrupt. So > we already live with the assumption that there may be a bad frame of > one > million or something like that. Hi Michael,
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). 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))) { _______________________________________________ Bcm43xx-dev mailing list [email protected] https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
