aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-03-06 22:28:35 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-06 22:28:35 -0500
commit72f2afb8a6858edd9335cd158eb21053a0c2c39a (patch)
tree1cc6884bf4e48822423d23d68d7b2699cd2e68fd /drivers/net
parentd11d9b2dd2c43dd99a491df8a83ae28401db0044 (diff)
[TG3]: Add DMA address workaround
Add DMA workaround for chips that do not support full 64-bit DMA addresses. 5714, 5715, and 5780 chips only support DMA addresses less than 40 bits. On 64-bit systems with IOMMU, set the dma_mask to 40-bit so that pci_map_xxx() calls will map the DMA address below 40 bits if necessary. On 64-bit systems without IOMMU, set the dma_mask to 64-bit and check for DMA addresses exceeding the limit in tg3_start_xmit(). 5788 only supports 32-bit DMA so need to set the mask appropriately also. Thanks to Chris Elmquist at SGI for reporting and helping to debug the problem on 5714. Thanks to David Miller for explaining the HIGHMEM and DMA stuff. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/tg3.c87
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 */
3536static 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
3535static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); 3548static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
3536 3549
3537static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, 3550/* Workaround 4GB and 40-bit hardware DMA bugs. */
3551static 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