diff options
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 85a392fab5cc..f83b41d4cb0e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -225,6 +225,7 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); | |||
225 | 225 | ||
226 | static int rx_copybreak = 200; | 226 | static int rx_copybreak = 200; |
227 | static int use_dac; | 227 | static int use_dac; |
228 | static int ignore_parity_err; | ||
228 | static struct { | 229 | static struct { |
229 | u32 msg_enable; | 230 | u32 msg_enable; |
230 | } debug = { -1 }; | 231 | } debug = { -1 }; |
@@ -470,6 +471,8 @@ module_param(use_dac, int, 0); | |||
470 | MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); | 471 | MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); |
471 | module_param_named(debug, debug.msg_enable, int, 0); | 472 | module_param_named(debug, debug.msg_enable, int, 0); |
472 | MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); | 473 | MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); |
474 | module_param_named(ignore_parity_err, ignore_parity_err, bool, 0); | ||
475 | MODULE_PARM_DESC(ignore_parity_err, "Ignore PCI parity error as target. Default: false"); | ||
473 | MODULE_LICENSE("GPL"); | 476 | MODULE_LICENSE("GPL"); |
474 | MODULE_VERSION(RTL8169_VERSION); | 477 | MODULE_VERSION(RTL8169_VERSION); |
475 | 478 | ||
@@ -1284,11 +1287,6 @@ static void rtl8169_hw_phy_config(struct net_device *dev) | |||
1284 | /* Shazam ! */ | 1287 | /* Shazam ! */ |
1285 | 1288 | ||
1286 | if (tp->mac_version == RTL_GIGA_MAC_VER_04) { | 1289 | if (tp->mac_version == RTL_GIGA_MAC_VER_04) { |
1287 | mdio_write(ioaddr, 31, 0x0001); | ||
1288 | mdio_write(ioaddr, 9, 0x273a); | ||
1289 | mdio_write(ioaddr, 14, 0x7bfb); | ||
1290 | mdio_write(ioaddr, 27, 0x841e); | ||
1291 | |||
1292 | mdio_write(ioaddr, 31, 0x0002); | 1290 | mdio_write(ioaddr, 31, 0x0002); |
1293 | mdio_write(ioaddr, 1, 0x90d0); | 1291 | mdio_write(ioaddr, 1, 0x90d0); |
1294 | mdio_write(ioaddr, 31, 0x0000); | 1292 | mdio_write(ioaddr, 31, 0x0000); |
@@ -1817,12 +1815,25 @@ static void rtl8169_hw_reset(void __iomem *ioaddr) | |||
1817 | RTL_R8(ChipCmd); | 1815 | RTL_R8(ChipCmd); |
1818 | } | 1816 | } |
1819 | 1817 | ||
1820 | static void | 1818 | static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp) |
1821 | rtl8169_hw_start(struct net_device *dev) | 1819 | { |
1820 | void __iomem *ioaddr = tp->mmio_addr; | ||
1821 | u32 cfg = rtl8169_rx_config; | ||
1822 | |||
1823 | cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); | ||
1824 | RTL_W32(RxConfig, cfg); | ||
1825 | |||
1826 | /* Set DMA burst size and Interframe Gap Time */ | ||
1827 | RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | | ||
1828 | (InterFrameGap << TxInterFrameGapShift)); | ||
1829 | } | ||
1830 | |||
1831 | static void rtl8169_hw_start(struct net_device *dev) | ||
1822 | { | 1832 | { |
1823 | struct rtl8169_private *tp = netdev_priv(dev); | 1833 | struct rtl8169_private *tp = netdev_priv(dev); |
1824 | void __iomem *ioaddr = tp->mmio_addr; | 1834 | void __iomem *ioaddr = tp->mmio_addr; |
1825 | struct pci_dev *pdev = tp->pci_dev; | 1835 | struct pci_dev *pdev = tp->pci_dev; |
1836 | u16 cmd; | ||
1826 | u32 i; | 1837 | u32 i; |
1827 | 1838 | ||
1828 | /* Soft reset the chip. */ | 1839 | /* Soft reset the chip. */ |
@@ -1835,6 +1846,11 @@ rtl8169_hw_start(struct net_device *dev) | |||
1835 | msleep_interruptible(1); | 1846 | msleep_interruptible(1); |
1836 | } | 1847 | } |
1837 | 1848 | ||
1849 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { | ||
1850 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); | ||
1851 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); | ||
1852 | } | ||
1853 | |||
1838 | if (tp->mac_version == RTL_GIGA_MAC_VER_13) { | 1854 | if (tp->mac_version == RTL_GIGA_MAC_VER_13) { |
1839 | pci_write_config_word(pdev, 0x68, 0x00); | 1855 | pci_write_config_word(pdev, 0x68, 0x00); |
1840 | pci_write_config_word(pdev, 0x69, 0x08); | 1856 | pci_write_config_word(pdev, 0x69, 0x08); |
@@ -1842,8 +1858,6 @@ rtl8169_hw_start(struct net_device *dev) | |||
1842 | 1858 | ||
1843 | /* Undocumented stuff. */ | 1859 | /* Undocumented stuff. */ |
1844 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { | 1860 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { |
1845 | u16 cmd; | ||
1846 | |||
1847 | /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ | 1861 | /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ |
1848 | if ((RTL_R8(Config2) & 0x07) & 0x01) | 1862 | if ((RTL_R8(Config2) & 0x07) & 0x01) |
1849 | RTL_W32(0x7c, 0x0007ffff); | 1863 | RTL_W32(0x7c, 0x0007ffff); |
@@ -1855,23 +1869,29 @@ rtl8169_hw_start(struct net_device *dev) | |||
1855 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | 1869 | pci_write_config_word(pdev, PCI_COMMAND, cmd); |
1856 | } | 1870 | } |
1857 | 1871 | ||
1858 | |||
1859 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 1872 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
1873 | if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || | ||
1874 | (tp->mac_version == RTL_GIGA_MAC_VER_02) || | ||
1875 | (tp->mac_version == RTL_GIGA_MAC_VER_03) || | ||
1876 | (tp->mac_version == RTL_GIGA_MAC_VER_04)) | ||
1877 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1878 | |||
1860 | RTL_W8(EarlyTxThres, EarlyTxThld); | 1879 | RTL_W8(EarlyTxThres, EarlyTxThld); |
1861 | 1880 | ||
1862 | /* Low hurts. Let's disable the filtering. */ | 1881 | /* Low hurts. Let's disable the filtering. */ |
1863 | RTL_W16(RxMaxSize, 16383); | 1882 | RTL_W16(RxMaxSize, 16383); |
1864 | 1883 | ||
1865 | /* Set Rx Config register */ | 1884 | if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || |
1866 | i = rtl8169_rx_config | | 1885 | (tp->mac_version == RTL_GIGA_MAC_VER_02) || |
1867 | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); | 1886 | (tp->mac_version == RTL_GIGA_MAC_VER_03) || |
1868 | RTL_W32(RxConfig, i); | 1887 | (tp->mac_version == RTL_GIGA_MAC_VER_04)) |
1888 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1889 | rtl8169_set_rx_tx_config_registers(tp); | ||
1869 | 1890 | ||
1870 | /* Set DMA burst size and Interframe Gap Time */ | 1891 | cmd = RTL_R16(CPlusCmd); |
1871 | RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | | 1892 | RTL_W16(CPlusCmd, cmd); |
1872 | (InterFrameGap << TxInterFrameGapShift)); | ||
1873 | 1893 | ||
1874 | tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW; | 1894 | tp->cp_cmd |= cmd | PCIMulRW; |
1875 | 1895 | ||
1876 | if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || | 1896 | if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || |
1877 | (tp->mac_version == RTL_GIGA_MAC_VER_03)) { | 1897 | (tp->mac_version == RTL_GIGA_MAC_VER_03)) { |
@@ -1897,7 +1917,15 @@ rtl8169_hw_start(struct net_device *dev) | |||
1897 | RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); | 1917 | RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); |
1898 | RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); | 1918 | RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); |
1899 | RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); | 1919 | RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); |
1900 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 1920 | |
1921 | if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && | ||
1922 | (tp->mac_version != RTL_GIGA_MAC_VER_02) && | ||
1923 | (tp->mac_version != RTL_GIGA_MAC_VER_03) && | ||
1924 | (tp->mac_version != RTL_GIGA_MAC_VER_04)) { | ||
1925 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1926 | rtl8169_set_rx_tx_config_registers(tp); | ||
1927 | } | ||
1928 | |||
1901 | RTL_W8(Cfg9346, Cfg9346_Lock); | 1929 | RTL_W8(Cfg9346, Cfg9346_Lock); |
1902 | 1930 | ||
1903 | /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ | 1931 | /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ |
@@ -1992,7 +2020,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, | |||
1992 | if (!skb) | 2020 | if (!skb) |
1993 | goto err_out; | 2021 | goto err_out; |
1994 | 2022 | ||
1995 | skb_reserve(skb, align); | 2023 | skb_reserve(skb, (align - 1) & (u32)skb->data); |
1996 | *sk_buff = skb; | 2024 | *sk_buff = skb; |
1997 | 2025 | ||
1998 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, | 2026 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, |
@@ -2355,12 +2383,17 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) | |||
2355 | /* | 2383 | /* |
2356 | * The recovery sequence below admits a very elaborated explanation: | 2384 | * The recovery sequence below admits a very elaborated explanation: |
2357 | * - it seems to work; | 2385 | * - it seems to work; |
2358 | * - I did not see what else could be done. | 2386 | * - I did not see what else could be done; |
2387 | * - it makes iop3xx happy. | ||
2359 | * | 2388 | * |
2360 | * Feel free to adjust to your needs. | 2389 | * Feel free to adjust to your needs. |
2361 | */ | 2390 | */ |
2362 | pci_write_config_word(pdev, PCI_COMMAND, | 2391 | if (ignore_parity_err) |
2363 | pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); | 2392 | pci_cmd &= ~PCI_COMMAND_PARITY; |
2393 | else | ||
2394 | pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; | ||
2395 | |||
2396 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
2364 | 2397 | ||
2365 | pci_write_config_word(pdev, PCI_STATUS, | 2398 | pci_write_config_word(pdev, PCI_STATUS, |
2366 | pci_status & (PCI_STATUS_DETECTED_PARITY | | 2399 | pci_status & (PCI_STATUS_DETECTED_PARITY | |
@@ -2374,10 +2407,11 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) | |||
2374 | tp->cp_cmd &= ~PCIDAC; | 2407 | tp->cp_cmd &= ~PCIDAC; |
2375 | RTL_W16(CPlusCmd, tp->cp_cmd); | 2408 | RTL_W16(CPlusCmd, tp->cp_cmd); |
2376 | dev->features &= ~NETIF_F_HIGHDMA; | 2409 | dev->features &= ~NETIF_F_HIGHDMA; |
2377 | rtl8169_schedule_work(dev, rtl8169_reinit_task); | ||
2378 | } | 2410 | } |
2379 | 2411 | ||
2380 | rtl8169_hw_reset(ioaddr); | 2412 | rtl8169_hw_reset(ioaddr); |
2413 | |||
2414 | rtl8169_schedule_work(dev, rtl8169_reinit_task); | ||
2381 | } | 2415 | } |
2382 | 2416 | ||
2383 | static void | 2417 | static void |
@@ -2457,7 +2491,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, | |||
2457 | 2491 | ||
2458 | skb = dev_alloc_skb(pkt_size + align); | 2492 | skb = dev_alloc_skb(pkt_size + align); |
2459 | if (skb) { | 2493 | if (skb) { |
2460 | skb_reserve(skb, align); | 2494 | skb_reserve(skb, (align - 1) & (u32)skb->data); |
2461 | eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); | 2495 | eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); |
2462 | *sk_buff = skb; | 2496 | *sk_buff = skb; |
2463 | rtl8169_mark_to_asic(desc, rx_buf_sz); | 2497 | rtl8169_mark_to_asic(desc, rx_buf_sz); |