diff options
-rw-r--r-- | drivers/net/r8169.c | 90 |
1 files changed, 55 insertions, 35 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index eb793fa4611c..0d2aeb84510f 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -156,6 +156,7 @@ enum mac_version { | |||
156 | RTL_GIGA_MAC_VER_03 = 0x03, // 8110S | 156 | RTL_GIGA_MAC_VER_03 = 0x03, // 8110S |
157 | RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB | 157 | RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB |
158 | RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd | 158 | RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd |
159 | RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe | ||
159 | RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb | 160 | RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb |
160 | RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf | 161 | RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf |
161 | RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec | 162 | RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec |
@@ -185,6 +186,7 @@ static const struct { | |||
185 | _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S | 186 | _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S |
186 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB | 187 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB |
187 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd | 188 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd |
189 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe | ||
188 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E | 190 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E |
189 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E | 191 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E |
190 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 | 192 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 |
@@ -328,6 +330,10 @@ enum RTL8169_register_content { | |||
328 | /* Config1 register p.24 */ | 330 | /* Config1 register p.24 */ |
329 | PMEnable = (1 << 0), /* Power Management Enable */ | 331 | PMEnable = (1 << 0), /* Power Management Enable */ |
330 | 332 | ||
333 | /* Config2 register p. 25 */ | ||
334 | PCI_Clock_66MHz = 0x01, | ||
335 | PCI_Clock_33MHz = 0x00, | ||
336 | |||
331 | /* Config3 register p.25 */ | 337 | /* Config3 register p.25 */ |
332 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ | 338 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ |
333 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ | 339 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ |
@@ -1169,6 +1175,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io | |||
1169 | { 0x34000000, RTL_GIGA_MAC_VER_13 }, | 1175 | { 0x34000000, RTL_GIGA_MAC_VER_13 }, |
1170 | { 0x30800000, RTL_GIGA_MAC_VER_14 }, | 1176 | { 0x30800000, RTL_GIGA_MAC_VER_14 }, |
1171 | { 0x30000000, RTL_GIGA_MAC_VER_11 }, | 1177 | { 0x30000000, RTL_GIGA_MAC_VER_11 }, |
1178 | { 0x98000000, RTL_GIGA_MAC_VER_06 }, | ||
1172 | { 0x18000000, RTL_GIGA_MAC_VER_05 }, | 1179 | { 0x18000000, RTL_GIGA_MAC_VER_05 }, |
1173 | { 0x10000000, RTL_GIGA_MAC_VER_04 }, | 1180 | { 0x10000000, RTL_GIGA_MAC_VER_04 }, |
1174 | { 0x04000000, RTL_GIGA_MAC_VER_03 }, | 1181 | { 0x04000000, RTL_GIGA_MAC_VER_03 }, |
@@ -1177,7 +1184,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io | |||
1177 | }, *p = mac_info; | 1184 | }, *p = mac_info; |
1178 | u32 reg; | 1185 | u32 reg; |
1179 | 1186 | ||
1180 | reg = RTL_R32(TxConfig) & 0x7c800000; | 1187 | reg = RTL_R32(TxConfig) & 0xfc800000; |
1181 | while ((reg & p->mask) != p->mask) | 1188 | while ((reg & p->mask) != p->mask) |
1182 | p++; | 1189 | p++; |
1183 | tp->mac_version = p->mac_version; | 1190 | tp->mac_version = p->mac_version; |
@@ -1425,10 +1432,10 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) | |||
1425 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); | 1432 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); |
1426 | RTL_W8(0x82, 0x01); | 1433 | RTL_W8(0x82, 0x01); |
1427 | 1434 | ||
1428 | if (tp->mac_version < RTL_GIGA_MAC_VER_03) { | 1435 | pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); |
1429 | dprintk("Set PCI Latency=0x40\n"); | 1436 | |
1430 | pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); | 1437 | if (tp->mac_version <= RTL_GIGA_MAC_VER_06) |
1431 | } | 1438 | pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); |
1432 | 1439 | ||
1433 | if (tp->mac_version == RTL_GIGA_MAC_VER_02) { | 1440 | if (tp->mac_version == RTL_GIGA_MAC_VER_02) { |
1434 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); | 1441 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); |
@@ -1844,9 +1851,6 @@ static void rtl_hw_start(struct net_device *dev) | |||
1844 | 1851 | ||
1845 | tp->hw_start(dev); | 1852 | tp->hw_start(dev); |
1846 | 1853 | ||
1847 | /* Enable all known interrupts by setting the interrupt mask. */ | ||
1848 | RTL_W16(IntrMask, rtl8169_intr_mask); | ||
1849 | |||
1850 | netif_start_queue(dev); | 1854 | netif_start_queue(dev); |
1851 | } | 1855 | } |
1852 | 1856 | ||
@@ -1880,31 +1884,41 @@ static void rtl_set_rx_max_size(void __iomem *ioaddr) | |||
1880 | RTL_W16(RxMaxSize, 16383); | 1884 | RTL_W16(RxMaxSize, 16383); |
1881 | } | 1885 | } |
1882 | 1886 | ||
1887 | static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) | ||
1888 | { | ||
1889 | struct { | ||
1890 | u32 mac_version; | ||
1891 | u32 clk; | ||
1892 | u32 val; | ||
1893 | } cfg2_info [] = { | ||
1894 | { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd | ||
1895 | { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, | ||
1896 | { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe | ||
1897 | { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } | ||
1898 | }, *p = cfg2_info; | ||
1899 | unsigned int i; | ||
1900 | u32 clk; | ||
1901 | |||
1902 | clk = RTL_R8(Config2) & PCI_Clock_66MHz; | ||
1903 | for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) { | ||
1904 | if ((p->mac_version == mac_version) && (p->clk == clk)) { | ||
1905 | RTL_W32(0x7c, p->val); | ||
1906 | break; | ||
1907 | } | ||
1908 | } | ||
1909 | } | ||
1910 | |||
1883 | static void rtl_hw_start_8169(struct net_device *dev) | 1911 | static void rtl_hw_start_8169(struct net_device *dev) |
1884 | { | 1912 | { |
1885 | struct rtl8169_private *tp = netdev_priv(dev); | 1913 | struct rtl8169_private *tp = netdev_priv(dev); |
1886 | void __iomem *ioaddr = tp->mmio_addr; | 1914 | void __iomem *ioaddr = tp->mmio_addr; |
1887 | struct pci_dev *pdev = tp->pci_dev; | 1915 | struct pci_dev *pdev = tp->pci_dev; |
1888 | u16 cmd; | ||
1889 | 1916 | ||
1890 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { | 1917 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { |
1891 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); | 1918 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); |
1892 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); | 1919 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); |
1893 | } | 1920 | } |
1894 | 1921 | ||
1895 | /* Undocumented stuff. */ | ||
1896 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { | ||
1897 | /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ | ||
1898 | if ((RTL_R8(Config2) & 0x07) & 0x01) | ||
1899 | RTL_W32(0x7c, 0x0007ffff); | ||
1900 | |||
1901 | RTL_W32(0x7c, 0x0007ff00); | ||
1902 | |||
1903 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
1904 | cmd = cmd & 0xef; | ||
1905 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
1906 | } | ||
1907 | |||
1908 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 1922 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
1909 | if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || | 1923 | if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || |
1910 | (tp->mac_version == RTL_GIGA_MAC_VER_02) || | 1924 | (tp->mac_version == RTL_GIGA_MAC_VER_02) || |
@@ -1916,11 +1930,7 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
1916 | 1930 | ||
1917 | rtl_set_rx_max_size(ioaddr); | 1931 | rtl_set_rx_max_size(ioaddr); |
1918 | 1932 | ||
1919 | if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || | 1933 | rtl_set_rx_tx_config_registers(tp); |
1920 | (tp->mac_version == RTL_GIGA_MAC_VER_02) || | ||
1921 | (tp->mac_version == RTL_GIGA_MAC_VER_03) || | ||
1922 | (tp->mac_version == RTL_GIGA_MAC_VER_04)) | ||
1923 | rtl_set_rx_tx_config_registers(tp); | ||
1924 | 1934 | ||
1925 | tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; | 1935 | tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; |
1926 | 1936 | ||
@@ -1933,6 +1943,8 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
1933 | 1943 | ||
1934 | RTL_W16(CPlusCmd, tp->cp_cmd); | 1944 | RTL_W16(CPlusCmd, tp->cp_cmd); |
1935 | 1945 | ||
1946 | rtl8169_set_magic_reg(ioaddr, tp->mac_version); | ||
1947 | |||
1936 | /* | 1948 | /* |
1937 | * Undocumented corner. Supposedly: | 1949 | * Undocumented corner. Supposedly: |
1938 | * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets | 1950 | * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets |
@@ -1941,14 +1953,6 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
1941 | 1953 | ||
1942 | rtl_set_rx_tx_desc_registers(tp, ioaddr); | 1954 | rtl_set_rx_tx_desc_registers(tp, ioaddr); |
1943 | 1955 | ||
1944 | if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && | ||
1945 | (tp->mac_version != RTL_GIGA_MAC_VER_02) && | ||
1946 | (tp->mac_version != RTL_GIGA_MAC_VER_03) && | ||
1947 | (tp->mac_version != RTL_GIGA_MAC_VER_04)) { | ||
1948 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1949 | rtl_set_rx_tx_config_registers(tp); | ||
1950 | } | ||
1951 | |||
1952 | RTL_W8(Cfg9346, Cfg9346_Lock); | 1956 | RTL_W8(Cfg9346, Cfg9346_Lock); |
1953 | 1957 | ||
1954 | /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ | 1958 | /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ |
@@ -1960,6 +1964,11 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
1960 | 1964 | ||
1961 | /* no early-rx interrupts */ | 1965 | /* no early-rx interrupts */ |
1962 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); | 1966 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); |
1967 | |||
1968 | /* Enable all known interrupts by setting the interrupt mask. */ | ||
1969 | RTL_W16(IntrMask, rtl8169_intr_mask); | ||
1970 | |||
1971 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1963 | } | 1972 | } |
1964 | 1973 | ||
1965 | static void rtl_hw_start_8168(struct net_device *dev) | 1974 | static void rtl_hw_start_8168(struct net_device *dev) |
@@ -1993,6 +2002,8 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
1993 | rtl_set_rx_mode(dev); | 2002 | rtl_set_rx_mode(dev); |
1994 | 2003 | ||
1995 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); | 2004 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); |
2005 | |||
2006 | RTL_W16(IntrMask, rtl8169_intr_mask); | ||
1996 | } | 2007 | } |
1997 | 2008 | ||
1998 | static void rtl_hw_start_8101(struct net_device *dev) | 2009 | static void rtl_hw_start_8101(struct net_device *dev) |
@@ -2032,6 +2043,8 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
2032 | rtl_set_rx_mode(dev); | 2043 | rtl_set_rx_mode(dev); |
2033 | 2044 | ||
2034 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); | 2045 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); |
2046 | |||
2047 | RTL_W16(IntrMask, rtl8169_intr_mask); | ||
2035 | } | 2048 | } |
2036 | 2049 | ||
2037 | static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) | 2050 | static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) |
@@ -2689,6 +2702,13 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, | |||
2689 | tp->stats.rx_bytes += pkt_size; | 2702 | tp->stats.rx_bytes += pkt_size; |
2690 | tp->stats.rx_packets++; | 2703 | tp->stats.rx_packets++; |
2691 | } | 2704 | } |
2705 | |||
2706 | /* Work around for AMD plateform. */ | ||
2707 | if ((desc->opts2 & 0xfffe000) && | ||
2708 | (tp->mac_version == RTL_GIGA_MAC_VER_05)) { | ||
2709 | desc->opts2 = 0; | ||
2710 | cur_rx++; | ||
2711 | } | ||
2692 | } | 2712 | } |
2693 | 2713 | ||
2694 | count = cur_rx - tp->cur_rx; | 2714 | count = cur_rx - tp->cur_rx; |