]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | Date: Tue, 19 May 2009 22:46:48 +0200 |
2 | From: Francois Romieu <romieu@fr.zoreil.com> | |
3 | Subject: r8169: allow true forced mode setting | |
4 | References: bnc#467518 | |
5 | ||
6 | Due to mostly historic reasons, including a lack of reliability | |
7 | of the link handling (especially with the older 8169), the | |
8 | current r8169 driver emulates forced mode setting by limiting | |
9 | the advertised modes. | |
10 | ||
11 | With this change the driver allows real 10/100 forced mode | |
12 | settings on the 8169 and 8101/8102. | |
13 | ||
14 | Original idea by Vincent Steenhoute. The RTL_GIGA_MAC_VER_03 | |
15 | tweak was extracted from Realtek's r8169 v6.010.00 driver. | |
16 | ||
17 | Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> | |
18 | Tested-by: Jean Delvare <jdelvare@suse.de> | |
19 | Cc: Edward Hsu <edward_hsu@realtek.com.tw> | |
20 | ||
21 | Tested-by: Vincent Steenhoute <vsteenhoute@novell.com> | |
22 | Acked-by: Jean Delvare <jdelvare@suse.de> | |
23 | --- | |
24 | drivers/net/r8169.c | 115 +++++++++++++++++++++++++++------------------------- | |
25 | 1 file changed, 61 insertions(+), 54 deletions(-) | |
26 | --- a/drivers/net/r8169.c | |
27 | +++ b/drivers/net/r8169.c | |
28 | @@ -828,76 +828,83 @@ static int rtl8169_set_speed_xmii(struct | |
29 | { | |
30 | struct rtl8169_private *tp = netdev_priv(dev); | |
31 | void __iomem *ioaddr = tp->mmio_addr; | |
32 | - int auto_nego, giga_ctrl; | |
33 | - | |
34 | - auto_nego = mdio_read(ioaddr, MII_ADVERTISE); | |
35 | - auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | | |
36 | - ADVERTISE_100HALF | ADVERTISE_100FULL); | |
37 | - giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); | |
38 | - giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | |
39 | + int giga_ctrl, bmcr; | |
40 | ||
41 | if (autoneg == AUTONEG_ENABLE) { | |
42 | + int auto_nego; | |
43 | + | |
44 | + auto_nego = mdio_read(ioaddr, MII_ADVERTISE); | |
45 | auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | | |
46 | ADVERTISE_100HALF | ADVERTISE_100FULL); | |
47 | - giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; | |
48 | - } else { | |
49 | - if (speed == SPEED_10) | |
50 | - auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL; | |
51 | - else if (speed == SPEED_100) | |
52 | - auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL; | |
53 | - else if (speed == SPEED_1000) | |
54 | - giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; | |
55 | - | |
56 | - if (duplex == DUPLEX_HALF) | |
57 | - auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL); | |
58 | + auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | |
59 | ||
60 | - if (duplex == DUPLEX_FULL) | |
61 | - auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF); | |
62 | - | |
63 | - /* This tweak comes straight from Realtek's driver. */ | |
64 | - if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && | |
65 | - ((tp->mac_version == RTL_GIGA_MAC_VER_13) || | |
66 | - (tp->mac_version == RTL_GIGA_MAC_VER_16))) { | |
67 | - auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; | |
68 | - } | |
69 | - } | |
70 | + giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); | |
71 | + giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | |
72 | ||
73 | - /* The 8100e/8101e/8102e do Fast Ethernet only. */ | |
74 | - if ((tp->mac_version == RTL_GIGA_MAC_VER_07) || | |
75 | - (tp->mac_version == RTL_GIGA_MAC_VER_08) || | |
76 | - (tp->mac_version == RTL_GIGA_MAC_VER_09) || | |
77 | - (tp->mac_version == RTL_GIGA_MAC_VER_10) || | |
78 | - (tp->mac_version == RTL_GIGA_MAC_VER_13) || | |
79 | - (tp->mac_version == RTL_GIGA_MAC_VER_14) || | |
80 | - (tp->mac_version == RTL_GIGA_MAC_VER_15) || | |
81 | - (tp->mac_version == RTL_GIGA_MAC_VER_16)) { | |
82 | - if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) && | |
83 | - netif_msg_link(tp)) { | |
84 | + /* The 8100e/8101e/8102e do Fast Ethernet only. */ | |
85 | + if ((tp->mac_version != RTL_GIGA_MAC_VER_07) && | |
86 | + (tp->mac_version != RTL_GIGA_MAC_VER_08) && | |
87 | + (tp->mac_version != RTL_GIGA_MAC_VER_09) && | |
88 | + (tp->mac_version != RTL_GIGA_MAC_VER_10) && | |
89 | + (tp->mac_version != RTL_GIGA_MAC_VER_13) && | |
90 | + (tp->mac_version != RTL_GIGA_MAC_VER_14) && | |
91 | + (tp->mac_version != RTL_GIGA_MAC_VER_15) && | |
92 | + (tp->mac_version != RTL_GIGA_MAC_VER_16)) { | |
93 | + giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; | |
94 | + } else if (netif_msg_link(tp)) { | |
95 | printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", | |
96 | dev->name); | |
97 | } | |
98 | - giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | |
99 | - } | |
100 | ||
101 | - auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | |
102 | + bmcr = BMCR_ANENABLE | BMCR_ANRESTART; | |
103 | + | |
104 | + if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || | |
105 | + (tp->mac_version == RTL_GIGA_MAC_VER_12) || | |
106 | + (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { | |
107 | + /* | |
108 | + * Wake up the PHY. | |
109 | + * Vendor specific (0x1f) and reserved (0x0e) MII | |
110 | + * registers. | |
111 | + */ | |
112 | + mdio_write(ioaddr, 0x1f, 0x0000); | |
113 | + mdio_write(ioaddr, 0x0e, 0x0000); | |
114 | + } | |
115 | + | |
116 | + tp->phy_auto_nego_reg = auto_nego; | |
117 | + | |
118 | + mdio_write(ioaddr, MII_ADVERTISE, auto_nego); | |
119 | + mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); | |
120 | + } else { | |
121 | + giga_ctrl = 0; | |
122 | + | |
123 | + if (speed == SPEED_10) | |
124 | + bmcr = 0; | |
125 | + else if (speed == SPEED_100) | |
126 | + bmcr = BMCR_SPEED100; | |
127 | + else | |
128 | + return -EINVAL; | |
129 | + | |
130 | + if (duplex == DUPLEX_FULL) | |
131 | + bmcr |= BMCR_FULLDPLX; | |
132 | ||
133 | - if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || | |
134 | - (tp->mac_version == RTL_GIGA_MAC_VER_12) || | |
135 | - (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { | |
136 | - /* | |
137 | - * Wake up the PHY. | |
138 | - * Vendor specific (0x1f) and reserved (0x0e) MII registers. | |
139 | - */ | |
140 | mdio_write(ioaddr, 0x1f, 0x0000); | |
141 | - mdio_write(ioaddr, 0x0e, 0x0000); | |
142 | } | |
143 | ||
144 | - tp->phy_auto_nego_reg = auto_nego; | |
145 | tp->phy_1000_ctrl_reg = giga_ctrl; | |
146 | ||
147 | - mdio_write(ioaddr, MII_ADVERTISE, auto_nego); | |
148 | - mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); | |
149 | - mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); | |
150 | + mdio_write(ioaddr, MII_BMCR, bmcr); | |
151 | + | |
152 | + if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || | |
153 | + (tp->mac_version == RTL_GIGA_MAC_VER_03)) { | |
154 | + if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) { | |
155 | + mdio_write(ioaddr, 0x17, 0x2138); | |
156 | + mdio_write(ioaddr, 0x0e, 0x0260); | |
157 | + } else { | |
158 | + mdio_write(ioaddr, 0x17, 0x2108); | |
159 | + mdio_write(ioaddr, 0x0e, 0x0000); | |
160 | + } | |
161 | + } | |
162 | + | |
163 | return 0; | |
164 | } | |
165 |