Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
  e1000: remove risky prefetch on next_skb->data
  e1000: fix ethtool test irq alloc as "probe"
  [PATCH] bcm43xx: add DMA rx poll workaround to DMA4
This commit is contained in:
Linus Torvalds 2006-06-08 15:16:35 -07:00
commit 128e6ced24
3 changed files with 28 additions and 16 deletions

View file

@ -870,13 +870,16 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
*data = 0; *data = 0;
/* Hook up test interrupt handler just for this test */ /* 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; shared_int = FALSE;
} else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ,
netdev->name, netdev)){ netdev->name, netdev)){
*data = 1; *data = 1;
return -1; return -1;
} }
DPRINTK(PROBE,INFO, "testing %s interrupt\n",
(shared_int ? "shared" : "unshared"));
/* Disable all the interrupts */ /* Disable all the interrupts */
E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);

View file

@ -3519,7 +3519,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
buffer_info = &rx_ring->buffer_info[i]; buffer_info = &rx_ring->buffer_info[i];
while (rx_desc->status & E1000_RXD_STAT_DD) { while (rx_desc->status & E1000_RXD_STAT_DD) {
struct sk_buff *skb, *next_skb; struct sk_buff *skb;
u8 status; u8 status;
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
if (*work_done >= work_to_do) if (*work_done >= work_to_do)
@ -3537,8 +3537,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
prefetch(next_rxd); prefetch(next_rxd);
next_buffer = &rx_ring->buffer_info[i]; next_buffer = &rx_ring->buffer_info[i];
next_skb = next_buffer->skb;
prefetch(next_skb->data - NET_IP_ALIGN);
cleaned = TRUE; cleaned = TRUE;
cleaned_count++; cleaned_count++;
@ -3668,7 +3666,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info, *next_buffer; struct e1000_buffer *buffer_info, *next_buffer;
struct e1000_ps_page *ps_page; struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma; struct e1000_ps_page_dma *ps_page_dma;
struct sk_buff *skb, *next_skb; struct sk_buff *skb;
unsigned int i, j; unsigned int i, j;
uint32_t length, staterr; uint32_t length, staterr;
int cleaned_count = 0; int cleaned_count = 0;
@ -3697,8 +3695,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
prefetch(next_rxd); prefetch(next_rxd);
next_buffer = &rx_ring->buffer_info[i]; next_buffer = &rx_ring->buffer_info[i];
next_skb = next_buffer->skb;
prefetch(next_skb->data - NET_IP_ALIGN);
cleaned = TRUE; cleaned = TRUE;
cleaned_count++; cleaned_count++;

View file

@ -624,25 +624,28 @@ err_destroy_tx0:
static u16 generate_cookie(struct bcm43xx_dmaring *ring, static u16 generate_cookie(struct bcm43xx_dmaring *ring,
int slot) int slot)
{ {
u16 cookie = 0x0000; u16 cookie = 0xF000;
/* Use the upper 4 bits of the cookie as /* Use the upper 4 bits of the cookie as
* DMA controller ID and store the slot number * 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) { switch (ring->mmio_base) {
default: default:
assert(0); assert(0);
case BCM43xx_MMIO_DMA1_BASE: case BCM43xx_MMIO_DMA1_BASE:
cookie = 0xA000;
break; break;
case BCM43xx_MMIO_DMA2_BASE: case BCM43xx_MMIO_DMA2_BASE:
cookie = 0x1000; cookie = 0xB000;
break; break;
case BCM43xx_MMIO_DMA3_BASE: case BCM43xx_MMIO_DMA3_BASE:
cookie = 0x2000; cookie = 0xC000;
break; break;
case BCM43xx_MMIO_DMA4_BASE: case BCM43xx_MMIO_DMA4_BASE:
cookie = 0x3000; cookie = 0xD000;
break; break;
} }
assert(((u16)slot & 0xF000) == 0x0000); assert(((u16)slot & 0xF000) == 0x0000);
@ -660,16 +663,16 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
struct bcm43xx_dmaring *ring = NULL; struct bcm43xx_dmaring *ring = NULL;
switch (cookie & 0xF000) { switch (cookie & 0xF000) {
case 0x0000: case 0xA000:
ring = dma->tx_ring0; ring = dma->tx_ring0;
break; break;
case 0x1000: case 0xB000:
ring = dma->tx_ring1; ring = dma->tx_ring1;
break; break;
case 0x2000: case 0xC000:
ring = dma->tx_ring2; ring = dma->tx_ring2;
break; break;
case 0x3000: case 0xD000:
ring = dma->tx_ring3; ring = dma->tx_ring3;
break; break;
default: default:
@ -839,8 +842,18 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
/* We received an xmit status. */ /* We received an xmit status. */
struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
struct bcm43xx_xmitstatus stat; struct bcm43xx_xmitstatus stat;
int i = 0;
stat.cookie = le16_to_cpu(hw->cookie); 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.flags = hw->flags;
stat.cnt1 = hw->cnt1; stat.cnt1 = hw->cnt1;
stat.cnt2 = hw->cnt2; stat.cnt2 = hw->cnt2;