aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-03-19 16:21:12 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-19 16:21:12 -0500
commit4a29cc2e503b33a1e96db4c3f9a94165f153f259 (patch)
tree74645b5ef3a92ad9857ed63d6446e2be0535060c
parentc7c694d196a39af6e644e24279953d04f30362db (diff)
[TG3]: 40-bit DMA workaround part 2
The 40-bit DMA workaround recently implemented for 5714, 5715, and 5780 needs to be expanded because there may be other tg3 devices behind the EPB Express to PCIX bridge in the 5780 class device. For example, some 4-port card or mother board designs have 5704 behind the 5714. All devices behind the EPB require the 40-bit DMA workaround. Thanks to Chris Elmquist again for reporting the problem and testing the patch. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tg3.c52
-rw-r--r--drivers/net/tg3.h1
-rw-r--r--include/linux/pci_ids.h1
3 files changed, 45 insertions, 9 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b8f1524da557..caf4102b54ce 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9552,12 +9552,36 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9552 } 9552 }
9553 } 9553 }
9554 9554
9555 /* Find msi capability. */ 9555 /* The EPB bridge inside 5714, 5715, and 5780 cannot support
9556 * DMA addresses > 40-bit. This bridge may have other additional
9557 * 57xx devices behind it in some 4-port NIC designs for example.
9558 * Any tg3 device found behind the bridge will also need the 40-bit
9559 * DMA workaround.
9560 */
9556 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 || 9561 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
9557 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { 9562 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
9558 tp->tg3_flags2 |= TG3_FLG2_5780_CLASS; 9563 tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
9564 tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
9559 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); 9565 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
9560 } 9566 }
9567 else {
9568 struct pci_dev *bridge = NULL;
9569
9570 do {
9571 bridge = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
9572 PCI_DEVICE_ID_SERVERWORKS_EPB,
9573 bridge);
9574 if (bridge && bridge->subordinate &&
9575 (bridge->subordinate->number <=
9576 tp->pdev->bus->number) &&
9577 (bridge->subordinate->subordinate >=
9578 tp->pdev->bus->number)) {
9579 tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
9580 pci_dev_put(bridge);
9581 break;
9582 }
9583 } while (bridge);
9584 }
9561 9585
9562 /* Initialize misc host control in PCI block. */ 9586 /* Initialize misc host control in PCI block. */
9563 tp->misc_host_ctrl |= (misc_ctrl_reg & 9587 tp->misc_host_ctrl |= (misc_ctrl_reg &
@@ -10303,7 +10327,14 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
10303 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { 10327 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
10304 u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); 10328 u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f);
10305 10329
10306 if (ccval == 0x6 || ccval == 0x7) 10330 /* If the 5704 is behind the EPB bridge, we can
10331 * do the less restrictive ONE_DMA workaround for
10332 * better performance.
10333 */
10334 if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) &&
10335 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
10336 tp->dma_rwctrl |= 0x8000;
10337 else if (ccval == 0x6 || ccval == 0x7)
10307 tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; 10338 tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
10308 10339
10309 /* Set bit 23 to enable PCIX hw bug fix */ 10340 /* Set bit 23 to enable PCIX hw bug fix */
@@ -10759,19 +10790,20 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
10759 goto err_out_iounmap; 10790 goto err_out_iounmap;
10760 } 10791 }
10761 10792
10762 /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit. 10793 /* The EPB bridge inside 5714, 5715, and 5780 and any
10794 * device behind the EPB cannot support DMA addresses > 40-bit.
10763 * On 64-bit systems with IOMMU, use 40-bit dma_mask. 10795 * On 64-bit systems with IOMMU, use 40-bit dma_mask.
10764 * On 64-bit systems without IOMMU, use 64-bit dma_mask and 10796 * On 64-bit systems without IOMMU, use 64-bit dma_mask and
10765 * do DMA address check in tg3_start_xmit(). 10797 * do DMA address check in tg3_start_xmit().
10766 */ 10798 */
10767 if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { 10799 if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
10800 persist_dma_mask = dma_mask = DMA_32BIT_MASK;
10801 else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
10768 persist_dma_mask = dma_mask = DMA_40BIT_MASK; 10802 persist_dma_mask = dma_mask = DMA_40BIT_MASK;
10769#ifdef CONFIG_HIGHMEM 10803#ifdef CONFIG_HIGHMEM
10770 dma_mask = DMA_64BIT_MASK; 10804 dma_mask = DMA_64BIT_MASK;
10771#endif 10805#endif
10772 } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788) 10806 } else
10773 persist_dma_mask = dma_mask = DMA_32BIT_MASK;
10774 else
10775 persist_dma_mask = dma_mask = DMA_64BIT_MASK; 10807 persist_dma_mask = dma_mask = DMA_64BIT_MASK;
10776 10808
10777 /* Configure DMA attributes. */ 10809 /* Configure DMA attributes. */
@@ -10908,8 +10940,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
10908 (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, 10940 (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
10909 (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, 10941 (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
10910 (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); 10942 (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
10911 printk(KERN_INFO "%s: dma_rwctrl[%08x]\n", 10943 printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
10912 dev->name, tp->dma_rwctrl); 10944 dev->name, tp->dma_rwctrl,
10945 (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
10946 (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
10913 10947
10914 return 0; 10948 return 0;
10915 10949
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 7f4b7f6ac40d..7e3b613afb29 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2163,6 +2163,7 @@ struct tg3 {
2163#define TG3_FLAG_10_100_ONLY 0x01000000 2163#define TG3_FLAG_10_100_ONLY 0x01000000
2164#define TG3_FLAG_PAUSE_AUTONEG 0x02000000 2164#define TG3_FLAG_PAUSE_AUTONEG 0x02000000
2165#define TG3_FLAG_IN_RESET_TASK 0x04000000 2165#define TG3_FLAG_IN_RESET_TASK 0x04000000
2166#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
2166#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 2167#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
2167#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 2168#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
2168#define TG3_FLAG_SPLIT_MODE 0x40000000 2169#define TG3_FLAG_SPLIT_MODE 0x40000000
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1709b5009d2e..751eea58bde8 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1365,6 +1365,7 @@
1365#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 1365#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008
1366#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 1366#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009
1367#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 1367#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
1368#define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103
1368#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 1369#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
1369#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 1370#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
1370#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 1371#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203