Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[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>

authored by

Michael Chan and committed by
David S. Miller
4a29cc2e c7c694d1

+45 -9
+43 -9
drivers/net/tg3.c
··· 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 9561 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 || 9557 9562 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { 9558 9563 tp->tg3_flags2 |= TG3_FLG2_5780_CLASS; 9564 + tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG; 9559 9565 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); 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); 9560 9584 } 9561 9585 9562 9586 /* Initialize misc host control in PCI block. */ ··· 10327 10303 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { 10328 10304 u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); 10329 10305 10330 - if (ccval == 0x6 || ccval == 0x7) 10306 + /* If the 5704 is behind the EPB bridge, we can 10307 + * do the less restrictive ONE_DMA workaround for 10308 + * better performance. 10309 + */ 10310 + if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) && 10311 + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) 10312 + tp->dma_rwctrl |= 0x8000; 10313 + else if (ccval == 0x6 || ccval == 0x7) 10331 10314 tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; 10332 10315 10333 10316 /* Set bit 23 to enable PCIX hw bug fix */ ··· 10790 10759 goto err_out_iounmap; 10791 10760 } 10792 10761 10793 - /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit. 10762 + /* The EPB bridge inside 5714, 5715, and 5780 and any 10763 + * device behind the EPB cannot support DMA addresses > 40-bit. 10794 10764 * On 64-bit systems with IOMMU, use 40-bit dma_mask. 10795 10765 * On 64-bit systems without IOMMU, use 64-bit dma_mask and 10796 10766 * do DMA address check in tg3_start_xmit(). 10797 10767 */ 10798 - if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { 10768 + if (tp->tg3_flags2 & TG3_FLG2_IS_5788) 10769 + persist_dma_mask = dma_mask = DMA_32BIT_MASK; 10770 + else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) { 10799 10771 persist_dma_mask = dma_mask = DMA_40BIT_MASK; 10800 10772 #ifdef CONFIG_HIGHMEM 10801 10773 dma_mask = DMA_64BIT_MASK; 10802 10774 #endif 10803 - } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788) 10804 - persist_dma_mask = dma_mask = DMA_32BIT_MASK; 10805 - else 10775 + } else 10806 10776 persist_dma_mask = dma_mask = DMA_64BIT_MASK; 10807 10777 10808 10778 /* Configure DMA attributes. */ ··· 10940 10908 (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, 10941 10909 (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, 10942 10910 (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); 10943 - printk(KERN_INFO "%s: dma_rwctrl[%08x]\n", 10944 - dev->name, tp->dma_rwctrl); 10911 + printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", 10912 + dev->name, tp->dma_rwctrl, 10913 + (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : 10914 + (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); 10945 10915 10946 10916 return 0; 10947 10917
+1
drivers/net/tg3.h
··· 2163 2163 #define TG3_FLAG_10_100_ONLY 0x01000000 2164 2164 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 2165 2165 #define TG3_FLAG_IN_RESET_TASK 0x04000000 2166 + #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 2166 2167 #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 2167 2168 #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 2168 2169 #define TG3_FLAG_SPLIT_MODE 0x40000000
+1
include/linux/pci_ids.h
··· 1365 1365 #define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 1366 1366 #define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 1367 1367 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 1368 + #define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103 1368 1369 #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 1369 1370 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 1370 1371 #define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203