diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2006-07-26 17:14:13 -0400 |
---|---|---|
committer | Francois Romieu <romieu@electric-eye.fr.zoreil.com> | 2006-07-26 17:23:15 -0400 |
commit | bcf0bf90cd9e9242b66e0563b6a8c8db2e4c262c (patch) | |
tree | 07c718f1bf9ca8c3699ba31727195f5cf95ab93e | |
parent | 4ff96fa67379c31ced69f193c7ffba17051f38e8 (diff) |
r8169: sync with vendor's driver
- add several PCI ID for the PCI-E adapters ;
- new identification strings ;
- the RTL_GIGA_MAC_VER_ defines have been renamed to closely match the
out-of-tree driver. It makes the comparison less hairy ;
- various magic ;
- the PCI region for the device with PCI ID 0x8136 is guessed.
Explanation: the in-kernel Linux driver is written to allow MM register
accesses and avoid the IO tax. The relevant BAR register was found at
base address 1 for the plain-old PCI 8169. User reported lspci show that
it is found at base address 2 for the new Gigabit PCI-E 816{8/9}.
Typically:
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.: Unknown device 8168 (rev 01)
Subsystem: Unknown device 1631:e015
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, cache line size 20
Interrupt: pin A routed to IRQ 16
Region 0: I/O ports at b800 [size=256]
Region 2: Memory at ff7ff000 (64-bit, non-prefetchable) [size=4K]
^^^^^^^^
So far I have not received any lspci report for the 0x8136 and
Realtek's driver do not help: be it under BSD or Linux, their r1000 driver
include a USE_IO_SPACE #define but the bar address is always hardcoded
to 1 in the MM case. :o/
- the 8168 has been reported to require an extra alignment for its receive
buffers. The status of the 8167 and 8136 is not known in this regard.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
-rw-r--r-- | drivers/net/r8169.c | 218 |
1 files changed, 144 insertions, 74 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ca0f303a6b5d..d0bfe4c8950d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -150,11 +150,16 @@ static const int multicast_filter_limit = 32; | |||
150 | #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) | 150 | #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) |
151 | 151 | ||
152 | enum mac_version { | 152 | enum mac_version { |
153 | RTL_GIGA_MAC_VER_B = 0x00, | 153 | RTL_GIGA_MAC_VER_01 = 0x00, |
154 | /* RTL_GIGA_MAC_VER_C = 0x03, */ | 154 | RTL_GIGA_MAC_VER_02 = 0x01, |
155 | RTL_GIGA_MAC_VER_D = 0x01, | 155 | RTL_GIGA_MAC_VER_03 = 0x02, |
156 | RTL_GIGA_MAC_VER_E = 0x02, | 156 | RTL_GIGA_MAC_VER_04 = 0x03, |
157 | RTL_GIGA_MAC_VER_X = 0x04 /* Greater than RTL_GIGA_MAC_VER_E */ | 157 | RTL_GIGA_MAC_VER_05 = 0x04, |
158 | RTL_GIGA_MAC_VER_11 = 0x0b, | ||
159 | RTL_GIGA_MAC_VER_12 = 0x0c, | ||
160 | RTL_GIGA_MAC_VER_13 = 0x0d, | ||
161 | RTL_GIGA_MAC_VER_14 = 0x0e, | ||
162 | RTL_GIGA_MAC_VER_15 = 0x0f | ||
158 | }; | 163 | }; |
159 | 164 | ||
160 | enum phy_version { | 165 | enum phy_version { |
@@ -166,7 +171,6 @@ enum phy_version { | |||
166 | RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */ | 171 | RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */ |
167 | }; | 172 | }; |
168 | 173 | ||
169 | |||
170 | #define _R(NAME,MAC,MASK) \ | 174 | #define _R(NAME,MAC,MASK) \ |
171 | { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } | 175 | { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } |
172 | 176 | ||
@@ -175,19 +179,44 @@ static const struct { | |||
175 | u8 mac_version; | 179 | u8 mac_version; |
176 | u32 RxConfigMask; /* Clears the bits supported by this chip */ | 180 | u32 RxConfigMask; /* Clears the bits supported by this chip */ |
177 | } rtl_chip_info[] = { | 181 | } rtl_chip_info[] = { |
178 | _R("RTL8169", RTL_GIGA_MAC_VER_B, 0xff7e1880), | 182 | _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), |
179 | _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_D, 0xff7e1880), | 183 | _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_02, 0xff7e1880), |
180 | _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_E, 0xff7e1880), | 184 | _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), |
181 | _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_X, 0xff7e1880), | 185 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), |
186 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), | ||
187 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E | ||
188 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E | ||
189 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 | ||
190 | _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 | ||
191 | _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880) // PCI-E 8139 | ||
182 | }; | 192 | }; |
183 | #undef _R | 193 | #undef _R |
184 | 194 | ||
195 | enum cfg_version { | ||
196 | RTL_CFG_0 = 0x00, | ||
197 | RTL_CFG_1, | ||
198 | RTL_CFG_2 | ||
199 | }; | ||
200 | |||
201 | static const struct { | ||
202 | unsigned int region; | ||
203 | unsigned int align; | ||
204 | } rtl_cfg_info[] = { | ||
205 | [RTL_CFG_0] = { 1, NET_IP_ALIGN }, | ||
206 | [RTL_CFG_1] = { 2, NET_IP_ALIGN }, | ||
207 | [RTL_CFG_2] = { 2, 8 } | ||
208 | }; | ||
209 | |||
185 | static struct pci_device_id rtl8169_pci_tbl[] = { | 210 | static struct pci_device_id rtl8169_pci_tbl[] = { |
186 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), }, | 211 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, |
187 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), }, | 212 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_1 }, |
188 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), }, | 213 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_1 }, |
189 | { PCI_DEVICE(0x16ec, 0x0116), }, | 214 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, |
190 | { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, }, | 215 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, |
216 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, | ||
217 | { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, | ||
218 | { PCI_VENDOR_ID_LINKSYS, 0x1032, | ||
219 | PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, | ||
191 | {0,}, | 220 | {0,}, |
192 | }; | 221 | }; |
193 | 222 | ||
@@ -347,6 +376,7 @@ enum RTL8169_register_content { | |||
347 | PHY_Cap_100_Full = 0x0100, | 376 | PHY_Cap_100_Full = 0x0100, |
348 | 377 | ||
349 | /* PHY_1000_CTRL_REG = 9 */ | 378 | /* PHY_1000_CTRL_REG = 9 */ |
379 | PHY_Cap_1000_Half = 0x0100, | ||
350 | PHY_Cap_1000_Full = 0x0200, | 380 | PHY_Cap_1000_Full = 0x0200, |
351 | 381 | ||
352 | PHY_Cap_Null = 0x0, | 382 | PHY_Cap_Null = 0x0, |
@@ -434,6 +464,7 @@ struct rtl8169_private { | |||
434 | dma_addr_t RxPhyAddr; | 464 | dma_addr_t RxPhyAddr; |
435 | struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ | 465 | struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ |
436 | struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ | 466 | struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ |
467 | unsigned align; | ||
437 | unsigned rx_buf_sz; | 468 | unsigned rx_buf_sz; |
438 | struct timer_list timer; | 469 | struct timer_list timer; |
439 | u16 cp_cmd; | 470 | u16 cp_cmd; |
@@ -750,25 +781,43 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
750 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full | | 781 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full | |
751 | PHY_Cap_100_Half | PHY_Cap_100_Full); | 782 | PHY_Cap_100_Half | PHY_Cap_100_Full); |
752 | giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG); | 783 | giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG); |
753 | giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null); | 784 | giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half | PHY_Cap_Null); |
754 | 785 | ||
755 | if (autoneg == AUTONEG_ENABLE) { | 786 | if (autoneg == AUTONEG_ENABLE) { |
756 | auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full | | 787 | auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full | |
757 | PHY_Cap_100_Half | PHY_Cap_100_Full); | 788 | PHY_Cap_100_Half | PHY_Cap_100_Full); |
758 | giga_ctrl |= PHY_Cap_1000_Full; | 789 | giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half; |
759 | } else { | 790 | } else { |
760 | if (speed == SPEED_10) | 791 | if (speed == SPEED_10) |
761 | auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full; | 792 | auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full; |
762 | else if (speed == SPEED_100) | 793 | else if (speed == SPEED_100) |
763 | auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full; | 794 | auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full; |
764 | else if (speed == SPEED_1000) | 795 | else if (speed == SPEED_1000) |
765 | giga_ctrl |= PHY_Cap_1000_Full; | 796 | giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half; |
766 | 797 | ||
767 | if (duplex == DUPLEX_HALF) | 798 | if (duplex == DUPLEX_HALF) |
768 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); | 799 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); |
769 | 800 | ||
770 | if (duplex == DUPLEX_FULL) | 801 | if (duplex == DUPLEX_FULL) |
771 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half); | 802 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half); |
803 | |||
804 | /* This tweak comes straight from Realtek's driver. */ | ||
805 | if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && | ||
806 | (tp->mac_version == RTL_GIGA_MAC_VER_13)) { | ||
807 | auto_nego = PHY_Cap_100_Half | 0x01; | ||
808 | } | ||
809 | } | ||
810 | |||
811 | /* The 8100e/8101e do Fast Ethernet only. */ | ||
812 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || | ||
813 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || | ||
814 | (tp->mac_version == RTL_GIGA_MAC_VER_15)) { | ||
815 | if ((giga_ctrl & (PHY_Cap_1000_Full | PHY_Cap_1000_Half)) && | ||
816 | netif_msg_link(tp)) { | ||
817 | printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", | ||
818 | dev->name); | ||
819 | } | ||
820 | giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half); | ||
772 | } | 821 | } |
773 | 822 | ||
774 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | 823 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
@@ -1148,10 +1197,16 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io | |||
1148 | u32 mask; | 1197 | u32 mask; |
1149 | int mac_version; | 1198 | int mac_version; |
1150 | } mac_info[] = { | 1199 | } mac_info[] = { |
1151 | { 0x1 << 28, RTL_GIGA_MAC_VER_X }, | 1200 | { 0x38800000, RTL_GIGA_MAC_VER_15 }, |
1152 | { 0x1 << 26, RTL_GIGA_MAC_VER_E }, | 1201 | { 0x38000000, RTL_GIGA_MAC_VER_12 }, |
1153 | { 0x1 << 23, RTL_GIGA_MAC_VER_D }, | 1202 | { 0x34000000, RTL_GIGA_MAC_VER_13 }, |
1154 | { 0x00000000, RTL_GIGA_MAC_VER_B } /* Catch-all */ | 1203 | { 0x30800000, RTL_GIGA_MAC_VER_14 }, |
1204 | { 0x30000000, RTL_GIGA_MAC_VER_11 }, | ||
1205 | { 0x18000000, RTL_GIGA_MAC_VER_05 }, | ||
1206 | { 0x10000000, RTL_GIGA_MAC_VER_04 }, | ||
1207 | { 0x04000000, RTL_GIGA_MAC_VER_03 }, | ||
1208 | { 0x00800000, RTL_GIGA_MAC_VER_02 }, | ||
1209 | { 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */ | ||
1155 | }, *p = mac_info; | 1210 | }, *p = mac_info; |
1156 | u32 reg; | 1211 | u32 reg; |
1157 | 1212 | ||
@@ -1163,24 +1218,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io | |||
1163 | 1218 | ||
1164 | static void rtl8169_print_mac_version(struct rtl8169_private *tp) | 1219 | static void rtl8169_print_mac_version(struct rtl8169_private *tp) |
1165 | { | 1220 | { |
1166 | struct { | 1221 | dprintk("mac_version = 0x%02x\n", tp->mac_version); |
1167 | int version; | ||
1168 | char *msg; | ||
1169 | } mac_print[] = { | ||
1170 | { RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" }, | ||
1171 | { RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" }, | ||
1172 | { RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" }, | ||
1173 | { 0, NULL } | ||
1174 | }, *p; | ||
1175 | |||
1176 | for (p = mac_print; p->msg; p++) { | ||
1177 | if (tp->mac_version == p->version) { | ||
1178 | dprintk("mac_version == %s (%04d)\n", p->msg, | ||
1179 | p->version); | ||
1180 | return; | ||
1181 | } | ||
1182 | } | ||
1183 | dprintk("mac_version == Unknown\n"); | ||
1184 | } | 1222 | } |
1185 | 1223 | ||
1186 | static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) | 1224 | static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) |
@@ -1265,7 +1303,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev) | |||
1265 | rtl8169_print_mac_version(tp); | 1303 | rtl8169_print_mac_version(tp); |
1266 | rtl8169_print_phy_version(tp); | 1304 | rtl8169_print_phy_version(tp); |
1267 | 1305 | ||
1268 | if (tp->mac_version <= RTL_GIGA_MAC_VER_B) | 1306 | if (tp->mac_version <= RTL_GIGA_MAC_VER_01) |
1269 | return; | 1307 | return; |
1270 | if (tp->phy_version >= RTL_GIGA_PHY_VER_H) | 1308 | if (tp->phy_version >= RTL_GIGA_PHY_VER_H) |
1271 | return; | 1309 | return; |
@@ -1275,7 +1313,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev) | |||
1275 | 1313 | ||
1276 | /* Shazam ! */ | 1314 | /* Shazam ! */ |
1277 | 1315 | ||
1278 | if (tp->mac_version == RTL_GIGA_MAC_VER_X) { | 1316 | if (tp->mac_version == RTL_GIGA_MAC_VER_04) { |
1279 | mdio_write(ioaddr, 31, 0x0001); | 1317 | mdio_write(ioaddr, 31, 0x0001); |
1280 | mdio_write(ioaddr, 9, 0x273a); | 1318 | mdio_write(ioaddr, 9, 0x273a); |
1281 | mdio_write(ioaddr, 14, 0x7bfb); | 1319 | mdio_write(ioaddr, 14, 0x7bfb); |
@@ -1314,7 +1352,7 @@ static void rtl8169_phy_timer(unsigned long __opaque) | |||
1314 | void __iomem *ioaddr = tp->mmio_addr; | 1352 | void __iomem *ioaddr = tp->mmio_addr; |
1315 | unsigned long timeout = RTL8169_PHY_TIMEOUT; | 1353 | unsigned long timeout = RTL8169_PHY_TIMEOUT; |
1316 | 1354 | ||
1317 | assert(tp->mac_version > RTL_GIGA_MAC_VER_B); | 1355 | assert(tp->mac_version > RTL_GIGA_MAC_VER_01); |
1318 | assert(tp->phy_version < RTL_GIGA_PHY_VER_H); | 1356 | assert(tp->phy_version < RTL_GIGA_PHY_VER_H); |
1319 | 1357 | ||
1320 | if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)) | 1358 | if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)) |
@@ -1350,7 +1388,7 @@ static inline void rtl8169_delete_timer(struct net_device *dev) | |||
1350 | struct rtl8169_private *tp = netdev_priv(dev); | 1388 | struct rtl8169_private *tp = netdev_priv(dev); |
1351 | struct timer_list *timer = &tp->timer; | 1389 | struct timer_list *timer = &tp->timer; |
1352 | 1390 | ||
1353 | if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) || | 1391 | if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) || |
1354 | (tp->phy_version >= RTL_GIGA_PHY_VER_H)) | 1392 | (tp->phy_version >= RTL_GIGA_PHY_VER_H)) |
1355 | return; | 1393 | return; |
1356 | 1394 | ||
@@ -1362,7 +1400,7 @@ static inline void rtl8169_request_timer(struct net_device *dev) | |||
1362 | struct rtl8169_private *tp = netdev_priv(dev); | 1400 | struct rtl8169_private *tp = netdev_priv(dev); |
1363 | struct timer_list *timer = &tp->timer; | 1401 | struct timer_list *timer = &tp->timer; |
1364 | 1402 | ||
1365 | if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) || | 1403 | if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) || |
1366 | (tp->phy_version >= RTL_GIGA_PHY_VER_H)) | 1404 | (tp->phy_version >= RTL_GIGA_PHY_VER_H)) |
1367 | return; | 1405 | return; |
1368 | 1406 | ||
@@ -1448,12 +1486,12 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) | |||
1448 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); | 1486 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); |
1449 | RTL_W8(0x82, 0x01); | 1487 | RTL_W8(0x82, 0x01); |
1450 | 1488 | ||
1451 | if (tp->mac_version < RTL_GIGA_MAC_VER_E) { | 1489 | if (tp->mac_version < RTL_GIGA_MAC_VER_03) { |
1452 | dprintk("Set PCI Latency=0x40\n"); | 1490 | dprintk("Set PCI Latency=0x40\n"); |
1453 | pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); | 1491 | pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); |
1454 | } | 1492 | } |
1455 | 1493 | ||
1456 | if (tp->mac_version == RTL_GIGA_MAC_VER_D) { | 1494 | if (tp->mac_version == RTL_GIGA_MAC_VER_02) { |
1457 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); | 1495 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); |
1458 | RTL_W8(0x82, 0x01); | 1496 | RTL_W8(0x82, 0x01); |
1459 | dprintk("Set PHY Reg 0x0bh = 0x00h\n"); | 1497 | dprintk("Set PHY Reg 0x0bh = 0x00h\n"); |
@@ -1471,6 +1509,7 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) | |||
1471 | static int __devinit | 1509 | static int __devinit |
1472 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1510 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1473 | { | 1511 | { |
1512 | const unsigned int region = rtl_cfg_info[ent->driver_data].region; | ||
1474 | struct rtl8169_private *tp; | 1513 | struct rtl8169_private *tp; |
1475 | struct net_device *dev; | 1514 | struct net_device *dev; |
1476 | void __iomem *ioaddr; | 1515 | void __iomem *ioaddr; |
@@ -1522,17 +1561,18 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1522 | } | 1561 | } |
1523 | 1562 | ||
1524 | /* make sure PCI base addr 1 is MMIO */ | 1563 | /* make sure PCI base addr 1 is MMIO */ |
1525 | if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { | 1564 | if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { |
1526 | if (netif_msg_probe(tp)) { | 1565 | if (netif_msg_probe(tp)) { |
1527 | dev_err(&pdev->dev, | 1566 | dev_err(&pdev->dev, |
1528 | "region #1 not an MMIO resource, aborting\n"); | 1567 | "region #%d not an MMIO resource, aborting\n", |
1568 | region); | ||
1529 | } | 1569 | } |
1530 | rc = -ENODEV; | 1570 | rc = -ENODEV; |
1531 | goto err_out_mwi_3; | 1571 | goto err_out_mwi_3; |
1532 | } | 1572 | } |
1533 | 1573 | ||
1534 | /* check for weird/broken PCI region reporting */ | 1574 | /* check for weird/broken PCI region reporting */ |
1535 | if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) { | 1575 | if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) { |
1536 | if (netif_msg_probe(tp)) { | 1576 | if (netif_msg_probe(tp)) { |
1537 | dev_err(&pdev->dev, | 1577 | dev_err(&pdev->dev, |
1538 | "Invalid PCI region size(s), aborting\n"); | 1578 | "Invalid PCI region size(s), aborting\n"); |
@@ -1568,7 +1608,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1568 | pci_set_master(pdev); | 1608 | pci_set_master(pdev); |
1569 | 1609 | ||
1570 | /* ioremap MMIO region */ | 1610 | /* ioremap MMIO region */ |
1571 | ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE); | 1611 | ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE); |
1572 | if (!ioaddr) { | 1612 | if (!ioaddr) { |
1573 | if (netif_msg_probe(tp)) | 1613 | if (netif_msg_probe(tp)) |
1574 | dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); | 1614 | dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); |
@@ -1668,6 +1708,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1668 | tp->intr_mask = 0xffff; | 1708 | tp->intr_mask = 0xffff; |
1669 | tp->pci_dev = pdev; | 1709 | tp->pci_dev = pdev; |
1670 | tp->mmio_addr = ioaddr; | 1710 | tp->mmio_addr = ioaddr; |
1711 | tp->align = rtl_cfg_info[ent->driver_data].align; | ||
1671 | 1712 | ||
1672 | spin_lock_init(&tp->lock); | 1713 | spin_lock_init(&tp->lock); |
1673 | 1714 | ||
@@ -1675,11 +1716,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1675 | if (rc < 0) | 1716 | if (rc < 0) |
1676 | goto err_out_unmap_5; | 1717 | goto err_out_unmap_5; |
1677 | 1718 | ||
1678 | if (netif_msg_probe(tp)) { | ||
1679 | printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", | ||
1680 | dev->name, rtl_chip_info[tp->chipset].name); | ||
1681 | } | ||
1682 | |||
1683 | pci_set_drvdata(pdev, dev); | 1719 | pci_set_drvdata(pdev, dev); |
1684 | 1720 | ||
1685 | if (netif_msg_probe(tp)) { | 1721 | if (netif_msg_probe(tp)) { |
@@ -1687,7 +1723,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1687 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " | 1723 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " |
1688 | "IRQ %d\n", | 1724 | "IRQ %d\n", |
1689 | dev->name, | 1725 | dev->name, |
1690 | rtl_chip_info[ent->driver_data].name, | 1726 | rtl_chip_info[tp->chipset].name, |
1691 | dev->base_addr, | 1727 | dev->base_addr, |
1692 | dev->dev_addr[0], dev->dev_addr[1], | 1728 | dev->dev_addr[0], dev->dev_addr[1], |
1693 | dev->dev_addr[2], dev->dev_addr[3], | 1729 | dev->dev_addr[2], dev->dev_addr[3], |
@@ -1805,6 +1841,7 @@ rtl8169_hw_start(struct net_device *dev) | |||
1805 | { | 1841 | { |
1806 | struct rtl8169_private *tp = netdev_priv(dev); | 1842 | struct rtl8169_private *tp = netdev_priv(dev); |
1807 | void __iomem *ioaddr = tp->mmio_addr; | 1843 | void __iomem *ioaddr = tp->mmio_addr; |
1844 | struct pci_dev *pdev = tp->pci_dev; | ||
1808 | u32 i; | 1845 | u32 i; |
1809 | 1846 | ||
1810 | /* Soft reset the chip. */ | 1847 | /* Soft reset the chip. */ |
@@ -1817,8 +1854,28 @@ rtl8169_hw_start(struct net_device *dev) | |||
1817 | udelay(10); | 1854 | udelay(10); |
1818 | } | 1855 | } |
1819 | 1856 | ||
1857 | if (tp->mac_version == RTL_GIGA_MAC_VER_13) { | ||
1858 | pci_write_config_word(pdev, 0x68, 0x00); | ||
1859 | pci_write_config_word(pdev, 0x69, 0x08); | ||
1860 | } | ||
1861 | |||
1862 | /* Undocumented stuff. */ | ||
1863 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) { | ||
1864 | u16 cmd; | ||
1865 | |||
1866 | /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ | ||
1867 | if ((RTL_R8(Config2) & 0x07) & 0x01) | ||
1868 | RTL_W32(0x7c, 0x0007ffff); | ||
1869 | |||
1870 | RTL_W32(0x7c, 0x0007ff00); | ||
1871 | |||
1872 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
1873 | cmd = cmd & 0xef; | ||
1874 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
1875 | } | ||
1876 | |||
1877 | |||
1820 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 1878 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
1821 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1822 | RTL_W8(EarlyTxThres, EarlyTxThld); | 1879 | RTL_W8(EarlyTxThres, EarlyTxThld); |
1823 | 1880 | ||
1824 | /* Low hurts. Let's disable the filtering. */ | 1881 | /* Low hurts. Let's disable the filtering. */ |
@@ -1833,17 +1890,18 @@ rtl8169_hw_start(struct net_device *dev) | |||
1833 | RTL_W32(TxConfig, | 1890 | RTL_W32(TxConfig, |
1834 | (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << | 1891 | (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << |
1835 | TxInterFrameGapShift)); | 1892 | TxInterFrameGapShift)); |
1836 | tp->cp_cmd |= RTL_R16(CPlusCmd); | ||
1837 | RTL_W16(CPlusCmd, tp->cp_cmd); | ||
1838 | 1893 | ||
1839 | if ((tp->mac_version == RTL_GIGA_MAC_VER_D) || | 1894 | tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW; |
1840 | (tp->mac_version == RTL_GIGA_MAC_VER_E)) { | 1895 | |
1896 | if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || | ||
1897 | (tp->mac_version == RTL_GIGA_MAC_VER_03)) { | ||
1841 | dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. " | 1898 | dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. " |
1842 | "Bit-3 and bit-14 MUST be 1\n"); | 1899 | "Bit-3 and bit-14 MUST be 1\n"); |
1843 | tp->cp_cmd |= (1 << 14) | PCIMulRW; | 1900 | tp->cp_cmd |= (1 << 14); |
1844 | RTL_W16(CPlusCmd, tp->cp_cmd); | ||
1845 | } | 1901 | } |
1846 | 1902 | ||
1903 | RTL_W16(CPlusCmd, tp->cp_cmd); | ||
1904 | |||
1847 | /* | 1905 | /* |
1848 | * Undocumented corner. Supposedly: | 1906 | * Undocumented corner. Supposedly: |
1849 | * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets | 1907 | * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets |
@@ -1854,6 +1912,7 @@ rtl8169_hw_start(struct net_device *dev) | |||
1854 | RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); | 1912 | RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); |
1855 | RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); | 1913 | RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); |
1856 | RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); | 1914 | RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); |
1915 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
1857 | RTL_W8(Cfg9346, Cfg9346_Lock); | 1916 | RTL_W8(Cfg9346, Cfg9346_Lock); |
1858 | udelay(10); | 1917 | udelay(10); |
1859 | 1918 | ||
@@ -1937,17 +1996,18 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, | |||
1937 | } | 1996 | } |
1938 | 1997 | ||
1939 | static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, | 1998 | static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, |
1940 | struct RxDesc *desc, int rx_buf_sz) | 1999 | struct RxDesc *desc, int rx_buf_sz, |
2000 | unsigned int align) | ||
1941 | { | 2001 | { |
1942 | struct sk_buff *skb; | 2002 | struct sk_buff *skb; |
1943 | dma_addr_t mapping; | 2003 | dma_addr_t mapping; |
1944 | int ret = 0; | 2004 | int ret = 0; |
1945 | 2005 | ||
1946 | skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN); | 2006 | skb = dev_alloc_skb(rx_buf_sz + align); |
1947 | if (!skb) | 2007 | if (!skb) |
1948 | goto err_out; | 2008 | goto err_out; |
1949 | 2009 | ||
1950 | skb_reserve(skb, NET_IP_ALIGN); | 2010 | skb_reserve(skb, align); |
1951 | *sk_buff = skb; | 2011 | *sk_buff = skb; |
1952 | 2012 | ||
1953 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, | 2013 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, |
@@ -1986,9 +2046,9 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, | |||
1986 | 2046 | ||
1987 | if (tp->Rx_skbuff[i]) | 2047 | if (tp->Rx_skbuff[i]) |
1988 | continue; | 2048 | continue; |
1989 | 2049 | ||
1990 | ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, | 2050 | ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, |
1991 | tp->RxDescArray + i, tp->rx_buf_sz); | 2051 | tp->RxDescArray + i, tp->rx_buf_sz, tp->align); |
1992 | if (ret < 0) | 2052 | if (ret < 0) |
1993 | break; | 2053 | break; |
1994 | } | 2054 | } |
@@ -2399,16 +2459,17 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) | |||
2399 | } | 2459 | } |
2400 | 2460 | ||
2401 | static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, | 2461 | static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, |
2402 | struct RxDesc *desc, int rx_buf_sz) | 2462 | struct RxDesc *desc, int rx_buf_sz, |
2463 | unsigned int align) | ||
2403 | { | 2464 | { |
2404 | int ret = -1; | 2465 | int ret = -1; |
2405 | 2466 | ||
2406 | if (pkt_size < rx_copybreak) { | 2467 | if (pkt_size < rx_copybreak) { |
2407 | struct sk_buff *skb; | 2468 | struct sk_buff *skb; |
2408 | 2469 | ||
2409 | skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); | 2470 | skb = dev_alloc_skb(pkt_size + align); |
2410 | if (skb) { | 2471 | if (skb) { |
2411 | skb_reserve(skb, NET_IP_ALIGN); | 2472 | skb_reserve(skb, align); |
2412 | eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); | 2473 | eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); |
2413 | *sk_buff = skb; | 2474 | *sk_buff = skb; |
2414 | rtl8169_mark_to_asic(desc, rx_buf_sz); | 2475 | rtl8169_mark_to_asic(desc, rx_buf_sz); |
@@ -2478,13 +2539,13 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, | |||
2478 | } | 2539 | } |
2479 | 2540 | ||
2480 | rtl8169_rx_csum(skb, desc); | 2541 | rtl8169_rx_csum(skb, desc); |
2481 | 2542 | ||
2482 | pci_dma_sync_single_for_cpu(tp->pci_dev, | 2543 | pci_dma_sync_single_for_cpu(tp->pci_dev, |
2483 | le64_to_cpu(desc->addr), tp->rx_buf_sz, | 2544 | le64_to_cpu(desc->addr), tp->rx_buf_sz, |
2484 | PCI_DMA_FROMDEVICE); | 2545 | PCI_DMA_FROMDEVICE); |
2485 | 2546 | ||
2486 | if (rtl8169_try_rx_copy(&skb, pkt_size, desc, | 2547 | if (rtl8169_try_rx_copy(&skb, pkt_size, desc, |
2487 | tp->rx_buf_sz)) { | 2548 | tp->rx_buf_sz, tp->align)) { |
2488 | pci_action = pci_unmap_single; | 2549 | pci_action = pci_unmap_single; |
2489 | tp->Rx_skbuff[entry] = NULL; | 2550 | tp->Rx_skbuff[entry] = NULL; |
2490 | } | 2551 | } |
@@ -2747,6 +2808,15 @@ rtl8169_set_rx_mode(struct net_device *dev) | |||
2747 | tmp = rtl8169_rx_config | rx_mode | | 2808 | tmp = rtl8169_rx_config | rx_mode | |
2748 | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); | 2809 | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); |
2749 | 2810 | ||
2811 | if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || | ||
2812 | (tp->mac_version == RTL_GIGA_MAC_VER_12) || | ||
2813 | (tp->mac_version == RTL_GIGA_MAC_VER_13) || | ||
2814 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || | ||
2815 | (tp->mac_version == RTL_GIGA_MAC_VER_15)) { | ||
2816 | mc_filter[0] = 0xffffffff; | ||
2817 | mc_filter[1] = 0xffffffff; | ||
2818 | } | ||
2819 | |||
2750 | RTL_W32(RxConfig, tmp); | 2820 | RTL_W32(RxConfig, tmp); |
2751 | RTL_W32(MAR0 + 0, mc_filter[0]); | 2821 | RTL_W32(MAR0 + 0, mc_filter[0]); |
2752 | RTL_W32(MAR0 + 4, mc_filter[1]); | 2822 | RTL_W32(MAR0 + 4, mc_filter[1]); |