diff options
-rw-r--r-- | drivers/net/r8169.c | 112 |
1 files changed, 59 insertions, 53 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index b0573146934b..fb2e50da0e9c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -843,75 +843,81 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
843 | { | 843 | { |
844 | struct rtl8169_private *tp = netdev_priv(dev); | 844 | struct rtl8169_private *tp = netdev_priv(dev); |
845 | void __iomem *ioaddr = tp->mmio_addr; | 845 | void __iomem *ioaddr = tp->mmio_addr; |
846 | int auto_nego, giga_ctrl; | 846 | int giga_ctrl, bmcr; |
847 | |||
848 | auto_nego = mdio_read(ioaddr, MII_ADVERTISE); | ||
849 | auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | | ||
850 | ADVERTISE_100HALF | ADVERTISE_100FULL); | ||
851 | giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); | ||
852 | giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
853 | 847 | ||
854 | if (autoneg == AUTONEG_ENABLE) { | 848 | if (autoneg == AUTONEG_ENABLE) { |
849 | int auto_nego; | ||
850 | |||
851 | auto_nego = mdio_read(ioaddr, MII_ADVERTISE); | ||
855 | auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | | 852 | auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | |
856 | ADVERTISE_100HALF | ADVERTISE_100FULL); | 853 | ADVERTISE_100HALF | ADVERTISE_100FULL); |
857 | giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; | 854 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
858 | } else { | ||
859 | if (speed == SPEED_10) | ||
860 | auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL; | ||
861 | else if (speed == SPEED_100) | ||
862 | auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL; | ||
863 | else if (speed == SPEED_1000) | ||
864 | giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; | ||
865 | |||
866 | if (duplex == DUPLEX_HALF) | ||
867 | auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL); | ||
868 | |||
869 | if (duplex == DUPLEX_FULL) | ||
870 | auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF); | ||
871 | 855 | ||
872 | /* This tweak comes straight from Realtek's driver. */ | 856 | giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); |
873 | if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && | 857 | giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); |
874 | ((tp->mac_version == RTL_GIGA_MAC_VER_13) || | ||
875 | (tp->mac_version == RTL_GIGA_MAC_VER_16))) { | ||
876 | auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; | ||
877 | } | ||
878 | } | ||
879 | 858 | ||
880 | /* The 8100e/8101e/8102e do Fast Ethernet only. */ | 859 | /* The 8100e/8101e/8102e do Fast Ethernet only. */ |
881 | if ((tp->mac_version == RTL_GIGA_MAC_VER_07) || | 860 | if ((tp->mac_version != RTL_GIGA_MAC_VER_07) && |
882 | (tp->mac_version == RTL_GIGA_MAC_VER_08) || | 861 | (tp->mac_version != RTL_GIGA_MAC_VER_08) && |
883 | (tp->mac_version == RTL_GIGA_MAC_VER_09) || | 862 | (tp->mac_version != RTL_GIGA_MAC_VER_09) && |
884 | (tp->mac_version == RTL_GIGA_MAC_VER_10) || | 863 | (tp->mac_version != RTL_GIGA_MAC_VER_10) && |
885 | (tp->mac_version == RTL_GIGA_MAC_VER_13) || | 864 | (tp->mac_version != RTL_GIGA_MAC_VER_13) && |
886 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || | 865 | (tp->mac_version != RTL_GIGA_MAC_VER_14) && |
887 | (tp->mac_version == RTL_GIGA_MAC_VER_15) || | 866 | (tp->mac_version != RTL_GIGA_MAC_VER_15) && |
888 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { | 867 | (tp->mac_version != RTL_GIGA_MAC_VER_16)) { |
889 | if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) && | 868 | giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; |
890 | netif_msg_link(tp)) { | 869 | } else if (netif_msg_link(tp)) { |
891 | printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", | 870 | printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", |
892 | dev->name); | 871 | dev->name); |
893 | } | 872 | } |
894 | giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
895 | } | ||
896 | 873 | ||
897 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | 874 | bmcr = BMCR_ANENABLE | BMCR_ANRESTART; |
875 | |||
876 | if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || | ||
877 | (tp->mac_version == RTL_GIGA_MAC_VER_12) || | ||
878 | (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { | ||
879 | /* | ||
880 | * Wake up the PHY. | ||
881 | * Vendor specific (0x1f) and reserved (0x0e) MII | ||
882 | * registers. | ||
883 | */ | ||
884 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
885 | mdio_write(ioaddr, 0x0e, 0x0000); | ||
886 | } | ||
887 | |||
888 | mdio_write(ioaddr, MII_ADVERTISE, auto_nego); | ||
889 | mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); | ||
890 | } else { | ||
891 | giga_ctrl = 0; | ||
892 | |||
893 | if (speed == SPEED_10) | ||
894 | bmcr = 0; | ||
895 | else if (speed == SPEED_100) | ||
896 | bmcr = BMCR_SPEED100; | ||
897 | else | ||
898 | return -EINVAL; | ||
899 | |||
900 | if (duplex == DUPLEX_FULL) | ||
901 | bmcr |= BMCR_FULLDPLX; | ||
898 | 902 | ||
899 | if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || | ||
900 | (tp->mac_version == RTL_GIGA_MAC_VER_12) || | ||
901 | (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { | ||
902 | /* | ||
903 | * Wake up the PHY. | ||
904 | * Vendor specific (0x1f) and reserved (0x0e) MII registers. | ||
905 | */ | ||
906 | mdio_write(ioaddr, 0x1f, 0x0000); | 903 | mdio_write(ioaddr, 0x1f, 0x0000); |
907 | mdio_write(ioaddr, 0x0e, 0x0000); | ||
908 | } | 904 | } |
909 | 905 | ||
910 | tp->phy_1000_ctrl_reg = giga_ctrl; | 906 | tp->phy_1000_ctrl_reg = giga_ctrl; |
911 | 907 | ||
912 | mdio_write(ioaddr, MII_ADVERTISE, auto_nego); | 908 | mdio_write(ioaddr, MII_BMCR, bmcr); |
913 | mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); | 909 | |
914 | mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); | 910 | if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || |
911 | (tp->mac_version == RTL_GIGA_MAC_VER_03)) { | ||
912 | if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) { | ||
913 | mdio_write(ioaddr, 0x17, 0x2138); | ||
914 | mdio_write(ioaddr, 0x0e, 0x0260); | ||
915 | } else { | ||
916 | mdio_write(ioaddr, 0x17, 0x2108); | ||
917 | mdio_write(ioaddr, 0x0e, 0x0000); | ||
918 | } | ||
919 | } | ||
920 | |||
915 | return 0; | 921 | return 0; |
916 | } | 922 | } |
917 | 923 | ||