From ea9a7719597e81a119a155178eabfc941eef11cc Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 4 Jun 2006 02:20:42 +0200 Subject: [PATCH] bcm43xx: add DMA rx poll workaround to DMA4 Also add the Poll RX DMA Memory workaround to the DMA4 (xmitstatus) path. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 31 +++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index bbecba02e69775..d0318e525ba767 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c @@ -624,25 +624,28 @@ err_destroy_tx0: static u16 generate_cookie(struct bcm43xx_dmaring *ring, int slot) { - u16 cookie = 0x0000; + u16 cookie = 0xF000; /* Use the upper 4 bits of the cookie as * DMA controller ID and store the slot number - * in the lower 12 bits + * in the lower 12 bits. + * Note that the cookie must never be 0, as this + * is a special value used in RX path. */ switch (ring->mmio_base) { default: assert(0); case BCM43xx_MMIO_DMA1_BASE: + cookie = 0xA000; break; case BCM43xx_MMIO_DMA2_BASE: - cookie = 0x1000; + cookie = 0xB000; break; case BCM43xx_MMIO_DMA3_BASE: - cookie = 0x2000; + cookie = 0xC000; break; case BCM43xx_MMIO_DMA4_BASE: - cookie = 0x3000; + cookie = 0xD000; break; } assert(((u16)slot & 0xF000) == 0x0000); @@ -660,16 +663,16 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm, struct bcm43xx_dmaring *ring = NULL; switch (cookie & 0xF000) { - case 0x0000: + case 0xA000: ring = dma->tx_ring0; break; - case 0x1000: + case 0xB000: ring = dma->tx_ring1; break; - case 0x2000: + case 0xC000: ring = dma->tx_ring2; break; - case 0x3000: + case 0xD000: ring = dma->tx_ring3; break; default: @@ -839,8 +842,18 @@ static void dma_rx(struct bcm43xx_dmaring *ring, /* We received an xmit status. */ struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; struct bcm43xx_xmitstatus stat; + int i = 0; stat.cookie = le16_to_cpu(hw->cookie); + while (stat.cookie == 0) { + if (unlikely(++i >= 10000)) { + assert(0); + break; + } + udelay(2); + barrier(); + stat.cookie = le16_to_cpu(hw->cookie); + } stat.flags = hw->flags; stat.cnt1 = hw->cnt1; stat.cnt2 = hw->cnt2; -- cgit 1.2.3-korg From b9b6e78b11de295ef073271979355d5fab71b877 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 8 Jun 2006 09:28:38 -0700 Subject: e1000: fix ethtool test irq alloc as "probe" New code added in 2.6.17 caused setup_irq to print a warning when running ethtool -t eth0 offline. This test marks the request_irq call made by this test as a "probe" to see if the interrupt is shared or not. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_ethtool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ecccca35c6f4db..d1c705b412c272 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -870,13 +870,16 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) *data = 0; /* Hook up test interrupt handler just for this test */ - if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { + if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name, + netdev)) { shared_int = FALSE; } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){ *data = 1; return -1; } + DPRINTK(PROBE,INFO, "testing %s interrupt\n", + (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); -- cgit 1.2.3-korg From 24f476eeecba66524af3f95e31ac208eea99e617 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 8 Jun 2006 09:28:47 -0700 Subject: e1000: remove risky prefetch on next_skb->data It was brought to our attention that the prefetches break e1000 traffic on xscale/arm architectures. Remove them for now. We'll let them stay in mm for a while, or find a better solution to enable. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ed15fcaedaf90a..97e71a4fe8eb70 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3519,7 +3519,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info = &rx_ring->buffer_info[i]; while (rx_desc->status & E1000_RXD_STAT_DD) { - struct sk_buff *skb, *next_skb; + struct sk_buff *skb; u8 status; #ifdef CONFIG_E1000_NAPI if (*work_done >= work_to_do) @@ -3537,8 +3537,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, prefetch(next_rxd); next_buffer = &rx_ring->buffer_info[i]; - next_skb = next_buffer->skb; - prefetch(next_skb->data - NET_IP_ALIGN); cleaned = TRUE; cleaned_count++; @@ -3668,7 +3666,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info, *next_buffer; struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *skb, *next_skb; + struct sk_buff *skb; unsigned int i, j; uint32_t length, staterr; int cleaned_count = 0; @@ -3697,8 +3695,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, prefetch(next_rxd); next_buffer = &rx_ring->buffer_info[i]; - next_skb = next_buffer->skb; - prefetch(next_skb->data - NET_IP_ALIGN); cleaned = TRUE; cleaned_count++; -- cgit 1.2.3-korg