diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-07 13:29:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-07 13:29:54 -0500 |
commit | d0b004840bd3b5ff2f2a0ad14fa0bd43349f5175 (patch) | |
tree | af56a2cb903690076c1ceab2371d2aa9f2670dae | |
parent | d19e9974084b4024abcfcfc9d8676c90d26994bb (diff) | |
parent | 72f2afb8a6858edd9335cd158eb21053a0c2c39a (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
[TG3]: Add DMA address workaround
-rw-r--r-- | drivers/net/tg3.c | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e8e92c853e89..15545620ab0e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -3532,9 +3532,23 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) | |||
3532 | (base + len + 8 < base)); | 3532 | (base + len + 8 < base)); |
3533 | } | 3533 | } |
3534 | 3534 | ||
3535 | /* Test for DMA addresses > 40-bit */ | ||
3536 | static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, | ||
3537 | int len) | ||
3538 | { | ||
3539 | #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) | ||
3540 | if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) | ||
3541 | return (((u64) mapping + len) > DMA_40BIT_MASK); | ||
3542 | return 0; | ||
3543 | #else | ||
3544 | return 0; | ||
3545 | #endif | ||
3546 | } | ||
3547 | |||
3535 | static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); | 3548 | static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); |
3536 | 3549 | ||
3537 | static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, | 3550 | /* Workaround 4GB and 40-bit hardware DMA bugs. */ |
3551 | static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, | ||
3538 | u32 last_plus_one, u32 *start, | 3552 | u32 last_plus_one, u32 *start, |
3539 | u32 base_flags, u32 mss) | 3553 | u32 base_flags, u32 mss) |
3540 | { | 3554 | { |
@@ -3742,6 +3756,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3742 | if (tg3_4g_overflow_test(mapping, len)) | 3756 | if (tg3_4g_overflow_test(mapping, len)) |
3743 | would_hit_hwbug = 1; | 3757 | would_hit_hwbug = 1; |
3744 | 3758 | ||
3759 | if (tg3_40bit_overflow_test(tp, mapping, len)) | ||
3760 | would_hit_hwbug = 1; | ||
3761 | |||
3745 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) | 3762 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) |
3746 | tg3_set_txd(tp, entry, mapping, len, | 3763 | tg3_set_txd(tp, entry, mapping, len, |
3747 | base_flags, (i == last)|(mss << 1)); | 3764 | base_flags, (i == last)|(mss << 1)); |
@@ -3763,7 +3780,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3763 | /* If the workaround fails due to memory/mapping | 3780 | /* If the workaround fails due to memory/mapping |
3764 | * failure, silently drop this packet. | 3781 | * failure, silently drop this packet. |
3765 | */ | 3782 | */ |
3766 | if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one, | 3783 | if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one, |
3767 | &start, base_flags, mss)) | 3784 | &start, base_flags, mss)) |
3768 | goto out_unlock; | 3785 | goto out_unlock; |
3769 | 3786 | ||
@@ -10608,8 +10625,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10608 | unsigned long tg3reg_base, tg3reg_len; | 10625 | unsigned long tg3reg_base, tg3reg_len; |
10609 | struct net_device *dev; | 10626 | struct net_device *dev; |
10610 | struct tg3 *tp; | 10627 | struct tg3 *tp; |
10611 | int i, err, pci_using_dac, pm_cap; | 10628 | int i, err, pm_cap; |
10612 | char str[40]; | 10629 | char str[40]; |
10630 | u64 dma_mask, persist_dma_mask; | ||
10613 | 10631 | ||
10614 | if (tg3_version_printed++ == 0) | 10632 | if (tg3_version_printed++ == 0) |
10615 | printk(KERN_INFO "%s", version); | 10633 | printk(KERN_INFO "%s", version); |
@@ -10646,26 +10664,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10646 | goto err_out_free_res; | 10664 | goto err_out_free_res; |
10647 | } | 10665 | } |
10648 | 10666 | ||
10649 | /* Configure DMA attributes. */ | ||
10650 | err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); | ||
10651 | if (!err) { | ||
10652 | pci_using_dac = 1; | ||
10653 | err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | ||
10654 | if (err < 0) { | ||
10655 | printk(KERN_ERR PFX "Unable to obtain 64 bit DMA " | ||
10656 | "for consistent allocations\n"); | ||
10657 | goto err_out_free_res; | ||
10658 | } | ||
10659 | } else { | ||
10660 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
10661 | if (err) { | ||
10662 | printk(KERN_ERR PFX "No usable DMA configuration, " | ||
10663 | "aborting.\n"); | ||
10664 | goto err_out_free_res; | ||
10665 | } | ||
10666 | pci_using_dac = 0; | ||
10667 | } | ||
10668 | |||
10669 | tg3reg_base = pci_resource_start(pdev, 0); | 10667 | tg3reg_base = pci_resource_start(pdev, 0); |
10670 | tg3reg_len = pci_resource_len(pdev, 0); | 10668 | tg3reg_len = pci_resource_len(pdev, 0); |
10671 | 10669 | ||
@@ -10679,8 +10677,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10679 | SET_MODULE_OWNER(dev); | 10677 | SET_MODULE_OWNER(dev); |
10680 | SET_NETDEV_DEV(dev, &pdev->dev); | 10678 | SET_NETDEV_DEV(dev, &pdev->dev); |
10681 | 10679 | ||
10682 | if (pci_using_dac) | ||
10683 | dev->features |= NETIF_F_HIGHDMA; | ||
10684 | dev->features |= NETIF_F_LLTX; | 10680 | dev->features |= NETIF_F_LLTX; |
10685 | #if TG3_VLAN_TAG_USED | 10681 | #if TG3_VLAN_TAG_USED |
10686 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 10682 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
@@ -10765,6 +10761,44 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10765 | goto err_out_iounmap; | 10761 | goto err_out_iounmap; |
10766 | } | 10762 | } |
10767 | 10763 | ||
10764 | /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit. | ||
10765 | * On 64-bit systems with IOMMU, use 40-bit dma_mask. | ||
10766 | * On 64-bit systems without IOMMU, use 64-bit dma_mask and | ||
10767 | * do DMA address check in tg3_start_xmit(). | ||
10768 | */ | ||
10769 | if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { | ||
10770 | persist_dma_mask = dma_mask = DMA_40BIT_MASK; | ||
10771 | #ifdef CONFIG_HIGHMEM | ||
10772 | dma_mask = DMA_64BIT_MASK; | ||
10773 | #endif | ||
10774 | } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788) | ||
10775 | persist_dma_mask = dma_mask = DMA_32BIT_MASK; | ||
10776 | else | ||
10777 | persist_dma_mask = dma_mask = DMA_64BIT_MASK; | ||
10778 | |||
10779 | /* Configure DMA attributes. */ | ||
10780 | if (dma_mask > DMA_32BIT_MASK) { | ||
10781 | err = pci_set_dma_mask(pdev, dma_mask); | ||
10782 | if (!err) { | ||
10783 | dev->features |= NETIF_F_HIGHDMA; | ||
10784 | err = pci_set_consistent_dma_mask(pdev, | ||
10785 | persist_dma_mask); | ||
10786 | if (err < 0) { | ||
10787 | printk(KERN_ERR PFX "Unable to obtain 64 bit " | ||
10788 | "DMA for consistent allocations\n"); | ||
10789 | goto err_out_iounmap; | ||
10790 | } | ||
10791 | } | ||
10792 | } | ||
10793 | if (err || dma_mask == DMA_32BIT_MASK) { | ||
10794 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
10795 | if (err) { | ||
10796 | printk(KERN_ERR PFX "No usable DMA configuration, " | ||
10797 | "aborting.\n"); | ||
10798 | goto err_out_iounmap; | ||
10799 | } | ||
10800 | } | ||
10801 | |||
10768 | tg3_init_bufmgr_config(tp); | 10802 | tg3_init_bufmgr_config(tp); |
10769 | 10803 | ||
10770 | #if TG3_TSO_SUPPORT != 0 | 10804 | #if TG3_TSO_SUPPORT != 0 |
@@ -10833,9 +10867,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10833 | } else | 10867 | } else |
10834 | tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; | 10868 | tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; |
10835 | 10869 | ||
10836 | if (tp->tg3_flags2 & TG3_FLG2_IS_5788) | ||
10837 | dev->features &= ~NETIF_F_HIGHDMA; | ||
10838 | |||
10839 | /* flow control autonegotiation is default behavior */ | 10870 | /* flow control autonegotiation is default behavior */ |
10840 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; | 10871 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; |
10841 | 10872 | ||