Andy,
Please try the patch below to see what we can learn from the DMA descriptor
errors. Some of this code is temporary, but there are also some statements that
will probably become permanent.
Please post any messages that result.
Larry
Index: wireless-testing/drivers/net/wireless/b43/dma.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/dma.c
+++ wireless-testing/drivers/net/wireless/b43/dma.c
@@ -46,6 +46,8 @@
* into separate slots. */
#define TX_SLOTS_PER_FRAME 2
+int dma_point = 0;
+struct b43_dmadesc_generic dma_desc_save[20];
/* 32bit DMA ops. */
static
@@ -190,6 +192,12 @@ static void op64_fill_descriptor(struct
desc->dma64.control1 = cpu_to_le32(ctl1);
desc->dma64.address_low = cpu_to_le32(addrlo);
desc->dma64.address_high = cpu_to_le32(addrhi);
+ dma_desc_save[dma_point].dma64.control0 = desc->dma64.control0;
+ dma_desc_save[dma_point].dma64.control1 = desc->dma64.control1;
+ dma_desc_save[dma_point].dma64.address_low = desc->dma64.address_low;
+ dma_desc_save[dma_point].dma64.address_high = desc->dma64.address_high;
+ if (++dma_point >= 20)
+ dma_point = 0;
}
static void op64_poke_tx(struct b43_dmaring *ring, int slot)
@@ -1216,8 +1224,11 @@ static int dma_tx_fragment(struct b43_dm
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
/* create a bounce buffer in zone_dma on mapping failure. */
if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
+ printk(KERN_INFO "b43: Using bounce buffer\n");
bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb) {
+ b43warn(ring->dev->wl, "Bounce buffer allocation "
+ "failed\n");
ring->current_slot = old_top_slot;
ring->used_slots = old_used_slots;
err = -ENOMEM;
@@ -1236,6 +1247,8 @@ static int dma_tx_fragment(struct b43_dm
meta->skb = skb;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
+ b43warn(ring->dev->wl, "DMA mapping error for bounce "
+ "buffer\n");
ring->current_slot = old_top_slot;
ring->used_slots = old_used_slots;
err = -EIO;
@@ -1620,6 +1633,25 @@ void b43_dma_tx_resume(struct b43_wldev
b43_power_saving_ctl_bits(dev, 0);
}
+void b43_dump_desc_buffer(void)
+{
+ /* dump the descriptor buffer once */
+ int i, j = dma_point;
+ static int once = 0;
+
+ if (once)
+ return;
+ printk(KERN_INFO "b43: Dump of last 20 DMA descriptors\n");
+ for (i = 0; i < 20; i++) {
+ if (--j < 0)
+ j = 19;
+ printk(KERN_INFO "b43: Descr. %2d: 0x%x 0x%X 0x%X 0x%X\n", i,
+ dma_desc_save[j].dma64.control0,
dma_desc_save[j].dma64.control1,
+ dma_desc_save[j].dma64.address_low,
dma_desc_save[j].dma64.address_high);
+ }
+ once++;
+}
+
#ifdef CONFIG_B43_PIO
static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type,
u16 mmio_base, bool enable)
Index: wireless-testing/drivers/net/wireless/b43/dma.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/dma.h
+++ wireless-testing/drivers/net/wireless/b43/dma.h
@@ -287,4 +287,5 @@ void b43_dma_rx(struct b43_dmaring *ring
void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
unsigned int engine_index, bool enable);
+void b43_dump_desc_buffer(void);
#endif /* B43_DMA_H_ */
Index: wireless-testing/drivers/net/wireless/b43/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/main.c
+++ wireless-testing/drivers/net/wireless/b43/main.c
@@ -1785,6 +1785,7 @@ static void b43_do_interrupt_thread(stru
dma_reason[2], dma_reason[3],
dma_reason[4], dma_reason[5]);
b43_controller_restart(dev, "DMA error");
+ b43_dump_desc_buffer();
return;
}
if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev