diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-08 18:16:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-08 18:16:35 -0400 |
commit | 128e6ced247cda88f96fa9f2e4ba8b2c4a681560 (patch) | |
tree | 431e59010f5b22cf26eb5db29136dfeaba2fe0fa | |
parent | bafe00cc9297ca77b66e5c83e5e65e17c0c997c8 (diff) | |
parent | cb15f81beb1e2ad015d6e7aea2f9b49fdbda9d1a (diff) |
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
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 5 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 31 |
3 files changed, 28 insertions, 16 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ecccca35c6f4..d1c705b412c2 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) | |||
870 | *data = 0; | 870 | *data = 0; |
871 | 871 | ||
872 | /* Hook up test interrupt handler just for this test */ | 872 | /* Hook up test interrupt handler just for this test */ |
873 | if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { | 873 | if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name, |
874 | netdev)) { | ||
874 | shared_int = FALSE; | 875 | shared_int = FALSE; |
875 | } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, | 876 | } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, |
876 | netdev->name, netdev)){ | 877 | netdev->name, netdev)){ |
877 | *data = 1; | 878 | *data = 1; |
878 | return -1; | 879 | return -1; |
879 | } | 880 | } |
881 | DPRINTK(PROBE,INFO, "testing %s interrupt\n", | ||
882 | (shared_int ? "shared" : "unshared")); | ||
880 | 883 | ||
881 | /* Disable all the interrupts */ | 884 | /* Disable all the interrupts */ |
882 | E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); | 885 | E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ed15fcaedaf9..97e71a4fe8eb 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, | |||
3519 | buffer_info = &rx_ring->buffer_info[i]; | 3519 | buffer_info = &rx_ring->buffer_info[i]; |
3520 | 3520 | ||
3521 | while (rx_desc->status & E1000_RXD_STAT_DD) { | 3521 | while (rx_desc->status & E1000_RXD_STAT_DD) { |
3522 | struct sk_buff *skb, *next_skb; | 3522 | struct sk_buff *skb; |
3523 | u8 status; | 3523 | u8 status; |
3524 | #ifdef CONFIG_E1000_NAPI | 3524 | #ifdef CONFIG_E1000_NAPI |
3525 | if (*work_done >= work_to_do) | 3525 | if (*work_done >= work_to_do) |
@@ -3537,8 +3537,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3537 | prefetch(next_rxd); | 3537 | prefetch(next_rxd); |
3538 | 3538 | ||
3539 | next_buffer = &rx_ring->buffer_info[i]; | 3539 | next_buffer = &rx_ring->buffer_info[i]; |
3540 | next_skb = next_buffer->skb; | ||
3541 | prefetch(next_skb->data - NET_IP_ALIGN); | ||
3542 | 3540 | ||
3543 | cleaned = TRUE; | 3541 | cleaned = TRUE; |
3544 | cleaned_count++; | 3542 | cleaned_count++; |
@@ -3668,7 +3666,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3668 | struct e1000_buffer *buffer_info, *next_buffer; | 3666 | struct e1000_buffer *buffer_info, *next_buffer; |
3669 | struct e1000_ps_page *ps_page; | 3667 | struct e1000_ps_page *ps_page; |
3670 | struct e1000_ps_page_dma *ps_page_dma; | 3668 | struct e1000_ps_page_dma *ps_page_dma; |
3671 | struct sk_buff *skb, *next_skb; | 3669 | struct sk_buff *skb; |
3672 | unsigned int i, j; | 3670 | unsigned int i, j; |
3673 | uint32_t length, staterr; | 3671 | uint32_t length, staterr; |
3674 | int cleaned_count = 0; | 3672 | int cleaned_count = 0; |
@@ -3697,8 +3695,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3697 | prefetch(next_rxd); | 3695 | prefetch(next_rxd); |
3698 | 3696 | ||
3699 | next_buffer = &rx_ring->buffer_info[i]; | 3697 | next_buffer = &rx_ring->buffer_info[i]; |
3700 | next_skb = next_buffer->skb; | ||
3701 | prefetch(next_skb->data - NET_IP_ALIGN); | ||
3702 | 3698 | ||
3703 | cleaned = TRUE; | 3699 | cleaned = TRUE; |
3704 | cleaned_count++; | 3700 | cleaned_count++; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index bbecba02e697..d0318e525ba7 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c | |||
@@ -624,25 +624,28 @@ err_destroy_tx0: | |||
624 | static u16 generate_cookie(struct bcm43xx_dmaring *ring, | 624 | static u16 generate_cookie(struct bcm43xx_dmaring *ring, |
625 | int slot) | 625 | int slot) |
626 | { | 626 | { |
627 | u16 cookie = 0x0000; | 627 | u16 cookie = 0xF000; |
628 | 628 | ||
629 | /* Use the upper 4 bits of the cookie as | 629 | /* Use the upper 4 bits of the cookie as |
630 | * DMA controller ID and store the slot number | 630 | * DMA controller ID and store the slot number |
631 | * in the lower 12 bits | 631 | * in the lower 12 bits. |
632 | * Note that the cookie must never be 0, as this | ||
633 | * is a special value used in RX path. | ||
632 | */ | 634 | */ |
633 | switch (ring->mmio_base) { | 635 | switch (ring->mmio_base) { |
634 | default: | 636 | default: |
635 | assert(0); | 637 | assert(0); |
636 | case BCM43xx_MMIO_DMA1_BASE: | 638 | case BCM43xx_MMIO_DMA1_BASE: |
639 | cookie = 0xA000; | ||
637 | break; | 640 | break; |
638 | case BCM43xx_MMIO_DMA2_BASE: | 641 | case BCM43xx_MMIO_DMA2_BASE: |
639 | cookie = 0x1000; | 642 | cookie = 0xB000; |
640 | break; | 643 | break; |
641 | case BCM43xx_MMIO_DMA3_BASE: | 644 | case BCM43xx_MMIO_DMA3_BASE: |
642 | cookie = 0x2000; | 645 | cookie = 0xC000; |
643 | break; | 646 | break; |
644 | case BCM43xx_MMIO_DMA4_BASE: | 647 | case BCM43xx_MMIO_DMA4_BASE: |
645 | cookie = 0x3000; | 648 | cookie = 0xD000; |
646 | break; | 649 | break; |
647 | } | 650 | } |
648 | assert(((u16)slot & 0xF000) == 0x0000); | 651 | assert(((u16)slot & 0xF000) == 0x0000); |
@@ -660,16 +663,16 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm, | |||
660 | struct bcm43xx_dmaring *ring = NULL; | 663 | struct bcm43xx_dmaring *ring = NULL; |
661 | 664 | ||
662 | switch (cookie & 0xF000) { | 665 | switch (cookie & 0xF000) { |
663 | case 0x0000: | 666 | case 0xA000: |
664 | ring = dma->tx_ring0; | 667 | ring = dma->tx_ring0; |
665 | break; | 668 | break; |
666 | case 0x1000: | 669 | case 0xB000: |
667 | ring = dma->tx_ring1; | 670 | ring = dma->tx_ring1; |
668 | break; | 671 | break; |
669 | case 0x2000: | 672 | case 0xC000: |
670 | ring = dma->tx_ring2; | 673 | ring = dma->tx_ring2; |
671 | break; | 674 | break; |
672 | case 0x3000: | 675 | case 0xD000: |
673 | ring = dma->tx_ring3; | 676 | ring = dma->tx_ring3; |
674 | break; | 677 | break; |
675 | default: | 678 | default: |
@@ -839,8 +842,18 @@ static void dma_rx(struct bcm43xx_dmaring *ring, | |||
839 | /* We received an xmit status. */ | 842 | /* We received an xmit status. */ |
840 | struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; | 843 | struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; |
841 | struct bcm43xx_xmitstatus stat; | 844 | struct bcm43xx_xmitstatus stat; |
845 | int i = 0; | ||
842 | 846 | ||
843 | stat.cookie = le16_to_cpu(hw->cookie); | 847 | stat.cookie = le16_to_cpu(hw->cookie); |
848 | while (stat.cookie == 0) { | ||
849 | if (unlikely(++i >= 10000)) { | ||
850 | assert(0); | ||
851 | break; | ||
852 | } | ||
853 | udelay(2); | ||
854 | barrier(); | ||
855 | stat.cookie = le16_to_cpu(hw->cookie); | ||
856 | } | ||
844 | stat.flags = hw->flags; | 857 | stat.flags = hw->flags; |
845 | stat.cnt1 = hw->cnt1; | 858 | stat.cnt1 = hw->cnt1; |
846 | stat.cnt2 = hw->cnt2; | 859 | stat.cnt2 = hw->cnt2; |