Subject: Re: New RTL8168 revision(?)
To: None <tech-kern@NetBSD.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: tech-kern
Date: 03/20/2007 00:17:55
d.den.brok@uni-bonn.de wrote:

> With the patched patch (I also added the missing break to be sure), it now  
> works again, including IPv6. Many thanks!

Okay, thanks for testing!

Anyway, I'd like to call for review my patch before commit
because it contains some structural changes:

- replace rtk_type member in rtk_softc which has chip types
  with new rtk_quirk that represents quirks on each chip:
  - RTKQ_8129		doesn't have internal MII (used in rtk(4))
  - RTKQ_8139CPLUS	has different register layout (for re(4))
  - RTKQ_8169NONS	(original 8169) requires some settings on init
  - RTKQ_PCIE		requires different settings in setmulti
  so that we don't have to check each hwrev values or types everywhere
  and newer variants will also work without changes if they don't
  have other quirks
  (I'll leave sc_rev for now for reference to the Realtek's driver)

- don't check hwrev register in re_pci_match() but check
  only PCI_VENDER(), PCI_PRODUCT() and PCI_REVISION()
  so that we no longer has to map pci space there

- add a new HWREV value for another 8168 variant (as reported by Dennis)

- try to map PCI mem space more properly (tested by Dennis)

- remove (probably unneeded) ifp->if_baudrate initialization


If there is no objection, I'll commit this in a few days.
---
Izumi Tsutsui



Index: dev/cardbus/if_re_cardbus.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cardbus/if_re_cardbus.c,v
retrieving revision 1.12
diff -u -r1.12 if_re_cardbus.c
--- dev/cardbus/if_re_cardbus.c	18 Nov 2006 16:03:53 -0000	1.12
+++ dev/cardbus/if_re_cardbus.c	19 Mar 2007 14:53:38 -0000
@@ -230,7 +230,6 @@
 	 */
 	re_cardbus_setup(csc);
 
-	sc->rtk_type = t->rtk_basetype;
 	sc->sc_dmat = ca->ca_dmat;
 	re_attach(sc);
 
Index: dev/cardbus/if_rtk_cardbus.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cardbus/if_rtk_cardbus.c,v
retrieving revision 1.31
diff -u -r1.31 if_rtk_cardbus.c
--- dev/cardbus/if_rtk_cardbus.c	16 Nov 2006 01:32:48 -0000	1.31
+++ dev/cardbus/if_rtk_cardbus.c	19 Mar 2007 14:53:38 -0000
@@ -247,7 +247,6 @@
 	 * configuration registers.
 	 */
 	rtk_cardbus_setup(csc);
-	sc->rtk_type = t->rtk_basetype;
 
 	rtk_attach(sc);
 
Index: dev/ic/rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.83
diff -u -r1.83 rtl8169.c
--- dev/ic/rtl8169.c	4 Mar 2007 06:02:00 -0000	1.83
+++ dev/ic/rtl8169.c	19 Mar 2007 14:53:39 -0000
@@ -259,7 +259,7 @@
 
 	s = splnet();
 
-	if (sc->rtk_type == RTK_8169) {
+	if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0) {
 		rval = re_gmii_readreg(dev, phy, reg);
 		splx(s);
 		return rval;
@@ -306,7 +306,7 @@
 		return 0;
 	}
 	rval = CSR_READ_2(sc, re8139_reg);
-	if (sc->rtk_type == RTK_8139CPLUS && re8139_reg == RTK_BMCR) {
+	if ((sc->sc_quirk & RTKQ_8139CPLUS) != 0 && re8139_reg == RTK_BMCR) {
 		/* 8139C+ has different bit layout. */
 		rval &= ~(BMCR_LOOP | BMCR_ISO);
 	}
@@ -323,7 +323,7 @@
 
 	s = splnet();
 
-	if (sc->rtk_type == RTK_8169) {
+	if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0) {
 		re_gmii_writereg(dev, phy, reg, data);
 		splx(s);
 		return;
@@ -337,7 +337,7 @@
 	switch (reg) {
 	case MII_BMCR:
 		re8139_reg = RTK_BMCR;
-		if (sc->rtk_type == RTK_8139CPLUS) {
+		if ((sc->sc_quirk & RTKQ_8139CPLUS) != 0) {
 			/* 8139C+ has different bit layout. */
 			data &= ~(BMCR_LOOP | BMCR_ISO);
 		}
@@ -588,7 +588,7 @@
 		eaddr[(i * 2) + 1] = val >> 8;
 	}
 
-	if (sc->rtk_type == RTK_8169) {
+	if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0) {
 		uint32_t hwrev;
 
 		/* Revision of 8169/8169S/8110s in bits 30..26, 23 */
@@ -600,7 +600,8 @@
 			sc->sc_rev = 14;
 		} else if (hwrev == RTK_HWREV_8101E) {
 			sc->sc_rev = 13;
-		} else if (hwrev == RTK_HWREV_8168_SPIN2) {
+		} else if (hwrev == RTK_HWREV_8168_SPIN2 ||
+		           hwrev == RTK_HWREV_8168_SPIN3) {
 			sc->sc_rev = 12;
 		} else if (hwrev == RTK_HWREV_8168_SPIN1) {
 			sc->sc_rev = 11;
@@ -612,8 +613,15 @@
 			sc->sc_rev = 3;
 		} else if (hwrev == RTK_HWREV_8110S) {
 			sc->sc_rev = 2;
-		} else /* RTK_HWREV_8169 */
+		} else if (hwrev == RTK_HWREV_8169) {
 			sc->sc_rev = 1;
+			sc->sc_quirk |= RTKQ_8169NONS;
+		} else {
+			aprint_normal("%s: Unknown revision (0x%08x)\n",
+			    sc->sc_dev.dv_xname, hwrev);
+			/* assume the latest one */
+			sc->sc_rev = 15;
+		}
 
 		/* Set RX length mask */
 		sc->re_rxlenmask = RE_RDESC_STAT_GFRAGLEN;
@@ -763,10 +771,6 @@
 	    IFCAP_TSOv4;
 	ifp->if_watchdog = re_watchdog;
 	ifp->if_init = re_init;
-	if (sc->rtk_type == RTK_8169)
-		ifp->if_baudrate = 1000000000;
-	else
-		ifp->if_baudrate = 100000000;
 	ifp->if_snd.ifq_maxlen = RE_IFQ_MAXLEN;
 	ifp->if_capenable = ifp->if_capabilities;
 	IFQ_SET_READY(&ifp->if_snd);
@@ -1189,7 +1193,7 @@
 		 * them using the 8169 status as though it was in the
 		 * same format as that of the 8139C+.
 		 */
-		if (sc->rtk_type == RTK_8169)
+		if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0)
 			rxstat >>= 1;
 
 		if (__predict_false((rxstat & RE_RDESC_STAT_RXERRSUM) != 0)) {
@@ -1725,10 +1729,10 @@
 		 * RealTek put the TX poll request register in a different
 		 * location on the 8169 gigE chip. I don't know why.
 		 */
-		if (sc->rtk_type == RTK_8169)
-			CSR_WRITE_2(sc, RTK_GTXSTART, RTK_TXSTART_START);
-		else
+		if ((sc->sc_quirk & RTKQ_8139CPLUS) != 0)
 			CSR_WRITE_1(sc, RTK_TXSTART, RTK_TXSTART_START);
+		else
+			CSR_WRITE_2(sc, RTK_GTXSTART, RTK_TXSTART_START);
 
 		/*
 		 * Use the countdown timer for interrupt moderation.
@@ -1780,10 +1784,10 @@
 	 */
 
 	/*
-	 * XXX: For 8169 and 8169S revs below 2, set bit 14.
-	 * For 8169S/8110S rev 2 and above, do not set bit 14.
+	 * XXX: For old 8169 set bit 14.
+	 *      For 8169S/8110S and above, do not set bit 14.
 	 */
-	if (sc->rtk_type == RTK_8169 && sc->sc_rev == 1)
+	if ((sc->sc_quirk & RTKQ_8169NONS) != 0)
 		reg |= (0x1 << 14) | RTK_CPLUSCMD_PCI_MRW;;
 
 	if (1)  {/* not for 8169S ? */
@@ -1799,7 +1803,7 @@
 	    reg | RTK_CPLUSCMD_RXENB | RTK_CPLUSCMD_TXENB);
 
 	/* XXX: from Realtek-supplied Linux driver. Wholly undocumented. */
-	if (sc->rtk_type == RTK_8169)
+	if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0)
 		CSR_WRITE_2(sc, RTK_IM, 0x0000);
 
 	DELAY(10000);
@@ -1845,13 +1849,10 @@
 	/*
 	 * Set the initial TX and RX configuration.
 	 */
-	if (sc->re_testmode) {
-		if (sc->rtk_type == RTK_8169)
-			CSR_WRITE_4(sc, RTK_TXCFG,
-			    RE_TXCFG_CONFIG | RTK_LOOPTEST_ON);
-		else
-			CSR_WRITE_4(sc, RTK_TXCFG,
-			    RE_TXCFG_CONFIG | RTK_LOOPTEST_ON_CPLUS);
+	if (sc->re_testmode && (sc->sc_quirk & RTKQ_8169NONS) != 0) {
+		/* test mode is needed only for old 8169 */
+		CSR_WRITE_4(sc, RTK_TXCFG,
+		    RE_TXCFG_CONFIG | RTK_LOOPTEST_ON);
 	} else
 		CSR_WRITE_4(sc, RTK_TXCFG, RE_TXCFG_CONFIG);
 
@@ -1915,17 +1916,17 @@
 	 * moderation, which dramatically improves TX frame rate.
 	 */
 
-	if (sc->rtk_type == RTK_8169)
-		CSR_WRITE_4(sc, RTK_TIMERINT_8169, 0x800);
-	else
+	if ((sc->sc_quirk & RTKQ_8139CPLUS) != 0)
 		CSR_WRITE_4(sc, RTK_TIMERINT, 0x400);
+	else {
+		CSR_WRITE_4(sc, RTK_TIMERINT_8169, 0x800);
 
-	/*
-	 * For 8169 gigE NICs, set the max allowed RX packet
-	 * size so we can receive jumbo frames.
-	 */
-	if (sc->rtk_type == RTK_8169)
+		/*
+		 * For 8169 gigE NICs, set the max allowed RX packet
+		 * size so we can receive jumbo frames.
+		 */
 		CSR_WRITE_2(sc, RTK_MAXRXPKTLEN, 16383);
+	}
 
 	if (sc->re_testmode)
 		return 0;
Index: dev/ic/rtl81x9.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9.c,v
retrieving revision 1.71
diff -u -r1.71 rtl81x9.c
--- dev/ic/rtl81x9.c	4 Mar 2007 06:02:00 -0000	1.71
+++ dev/ic/rtl81x9.c	19 Mar 2007 14:53:39 -0000
@@ -437,7 +437,7 @@
 	int rval;
 	int rtk8139_reg;
 
-	if (sc->rtk_type == RTK_8139) {
+	if ((sc->sc_quirk & RTKQ_8129) == 0) {
 		if (phy != 7)
 			return 0;
 
@@ -482,7 +482,7 @@
 	struct rtk_mii_frame frame;
 	int rtk8139_reg;
 
-	if (sc->rtk_type == RTK_8139) {
+	if ((sc->sc_quirk & RTKQ_8129) == 0) {
 		if (phy != 7)
 			return;
 
@@ -539,7 +539,7 @@
 {
 	struct ifnet *ifp;
 	uint32_t hashes[2] = { 0, 0 };
-	uint32_t rxfilt, hwrev;
+	uint32_t rxfilt;
 	struct ether_multi *enm;
 	struct ether_multistep step;
 	int h, mcnt;
@@ -594,10 +594,7 @@
 	 * parts. This means we have to write the hash pattern in reverse
 	 * order for those devices.
 	 */
-	hwrev = CSR_READ_4(sc, RTK_TXCFG) & RTK_TXCFG_HWREV;
-	if (hwrev == RTK_HWREV_8100E || hwrev == RTK_HWREV_8100E_SPIN2 ||
-	    hwrev == RTK_HWREV_8101E ||
-	    hwrev == RTK_HWREV_8168_SPIN1 || hwrev == RTK_HWREV_8168_SPIN2) {
+	if ((sc->sc_quirk & RTKQ_PCIE) != 0) {
 		CSR_WRITE_4(sc, RTK_MAR0, bswap32(hashes[1]));
 		CSR_WRITE_4(sc, RTK_MAR4, bswap32(hashes[0]));
 	} else {
Index: dev/ic/rtl81x9reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9reg.h,v
retrieving revision 1.26
diff -u -r1.26 rtl81x9reg.h
--- dev/ic/rtl81x9reg.h	4 Feb 2007 04:41:43 -0000	1.26
+++ dev/ic/rtl81x9reg.h	19 Mar 2007 14:53:39 -0000
@@ -159,6 +159,7 @@
 #define RTK_HWREV_8100E		0x30800000
 #define RTK_HWREV_8101E		0x34000000
 #define RTK_HWREV_8168_SPIN2	0x38000000
+#define RTK_HWREV_8168_SPIN3	0x38400000
 #define RTK_HWREV_8100E_SPIN2	0x38800000
 #define RTK_HWREV_8139		0x60000000
 #define RTK_HWREV_8139A		0x70000000
Index: dev/ic/rtl81x9var.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9var.h,v
retrieving revision 1.38
diff -u -r1.38 rtl81x9var.h
--- dev/ic/rtl81x9var.h	4 Mar 2007 06:02:00 -0000	1.38
+++ dev/ic/rtl81x9var.h	19 Mar 2007 14:53:39 -0000
@@ -58,23 +58,14 @@
 	uint16_t		rtk_vid;
 	uint16_t		rtk_did;
 	int			rtk_basetype;
-	const char		*rtk_name;
-};
-
-struct rtk_hwrev {
-	uint32_t		rtk_rev;
-	int			rtk_type;
-	const char		*rtk_desc;
-};
-
 #define RTK_8129		1
 #define RTK_8139		2
 #define RTK_8139CPLUS		3
 #define RTK_8169		4
-
-#define RTK_ISCPLUS(x)	((x)->rtk_type == RTK_8139CPLUS || \
-			 (x)->rtk_type == RTK_8169)
-
+#define RTK_8168		5
+#define RTK_8101E		6
+	const char		*rtk_name;
+};
 
 struct rtk_mii_frame {
 	uint8_t			mii_stdelim;
@@ -192,7 +183,12 @@
 	struct callout		rtk_tick_ch;	/* tick callout */
 	bus_space_handle_t	rtk_bhandle;	/* bus space handle */
 	bus_space_tag_t		rtk_btag;	/* bus space tag */
-	int			rtk_type;
+	u_int			sc_quirk;	/* chip quirks */
+#define RTKQ_8129		0x00000001	/* 8129 */
+#define RTKQ_8139CPLUS		0x00000002	/* 8139C+ */
+#define RTKQ_8169NONS		0x00000004	/* old non-single 8169 */
+#define RTKQ_PCIE		0x00000008	/* PCIe variants */
+
 	bus_dma_tag_t 		sc_dmat;
 
 	bus_dma_segment_t 	sc_dmaseg;	/* for rtk(4) */
@@ -212,8 +208,12 @@
 	int			re_testmode;
 
 	int			sc_flags;	/* misc flags */
+#define RTK_ATTACHED 0x00000001 /* attach has succeeded */
+#define RTK_ENABLED  0x00000002 /* chip is enabled	*/
+#define RTK_IS_ENABLED(sc)	((sc)->sc_flags & RTK_ENABLED)
+
 	int			sc_txthresh;	/* Early tx threshold */
-	int			sc_rev;		/* revision within rtk_type */
+	int			sc_rev;		/* MII revision */
 
 	void	*sc_sdhook;			/* shutdown hook */
 	void	*sc_powerhook;			/* power management hook */
@@ -266,11 +266,6 @@
 	((sc)->re_ldata.re_rx_list_map->dm_segs[0].ds_addr + RE_TXPADOFF)
 
 
-#define RTK_ATTACHED 0x00000001 /* attach has succeeded */
-#define RTK_ENABLED  0x00000002 /* chip is enabled	*/
-
-#define RTK_IS_ENABLED(sc)	((sc)->sc_flags & RTK_ENABLED)
-
 #define RTK_TXTH_MAX	RTK_TXTH_1536
 
 /*
Index: dev/pci/if_re_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_re_pci.c,v
retrieving revision 1.26
diff -u -r1.26 if_re_pci.c
--- dev/pci/if_re_pci.c	5 Mar 2007 10:32:05 -0000	1.26
+++ dev/pci/if_re_pci.c	19 Mar 2007 14:53:40 -0000
@@ -96,79 +96,35 @@
  */
 static const struct rtk_type re_devs[] = {
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8139,
-	    RTK_HWREV_8139CPLUS,
+	    RTK_8139CPLUS,
 	    "RealTek 8139C+ 10/100BaseTX" },
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8101E,
-	    RTK_HWREV_8100E,
-	    "RealTek 8100E PCIe 10/100BaseTX" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8101E,
-	    RTK_HWREV_8100E_SPIN2,
-	    "RealTek 8100E PCIe 10/100BaseTX" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8101E,
-	    RTK_HWREV_8101E,
-	    "RealTek 8101E PCIe 10/100BaseTX" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8168,
-	    RTK_HWREV_8168_SPIN1,
-	    "RealTek 8168B/8111B PCIe Gigabit Ethernet" },
+	    RTK_8101E,
+	    "RealTek 8100E/8101E PCIe 10/100BaseTX" },
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8168,
-	    RTK_HWREV_8168_SPIN2,
+	    RTK_8168,
 	    "RealTek 8168B/8111B PCIe Gigabit Ethernet" },
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
-	    RTK_HWREV_8169,
-	    "RealTek 8169 Gigabit Ethernet" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
-	    RTK_HWREV_8169S,
-	    "RealTek 8169S Single-chip Gigabit Ethernet" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
-	    RTK_HWREV_8110S,
-	    "RealTek 8110S Single-chip Gigabit Ethernet" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
-	    RTK_HWREV_8169_8110SB,
-	    "RealTek 8169SB/8110SB Single-chip Gigabit Ethernet" },
-	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
-	    RTK_HWREV_8169_8110SC,
-	    "RealTek 8169SC/8110SC Single-chip Gigabit Ethernet" },
+	    RTK_8169,
+	    "RealTek 8169/8110 Gigabit Ethernet" },
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169SC,
-	    RTK_HWREV_8169_8110SC,
+	    RTK_8169,
 	    "RealTek 8169SC/8110SC Single-chip Gigabit Ethernet" },
 	{ PCI_VENDOR_COREGA, PCI_PRODUCT_COREGA_LAPCIGT,
-	    RTK_HWREV_8169S,
+	    RTK_8169,
 	    "Corega CG-LAPCIGT Gigabit Ethernet" },
 	{ PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE528T,
-	    RTK_HWREV_8169S,
+	    RTK_8169,
 	    "D-Link DGE-528T Gigabit Ethernet" },
 	{ PCI_VENDOR_USR2, PCI_PRODUCT_USR2_USR997902,
-	    RTK_HWREV_8169S,
+	    RTK_8169,
 	    "US Robotics (3Com) USR997902 Gigabit Ethernet" },
 	{ PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_EG1032,
-	    RTK_HWREV_8169S,
+	    RTK_8169,
 	    "Linksys EG1032 rev. 3 Gigabit Ethernet" },
 	{ 0, 0, 0, NULL }
 };
 
-static const struct rtk_hwrev re_hwrevs[] = {
-	{ RTK_HWREV_8139, RTK_8139,  "" },
-	{ RTK_HWREV_8139A, RTK_8139, "A" },
-	{ RTK_HWREV_8139AG, RTK_8139, "A-G" },
-	{ RTK_HWREV_8139B, RTK_8139, "B" },
-	{ RTK_HWREV_8130, RTK_8139, "8130" },
-	{ RTK_HWREV_8139C, RTK_8139, "C" },
-	{ RTK_HWREV_8139D, RTK_8139, "8139D/8100B/8100C" },
-	{ RTK_HWREV_8139CPLUS, RTK_8139CPLUS, "C+"},
-	{ RTK_HWREV_8168_SPIN1, RTK_8169, "8168B/8111B"},
-	{ RTK_HWREV_8168_SPIN2, RTK_8169, "8168B/8111B"},
-	{ RTK_HWREV_8169, RTK_8169, "8169"},
-	{ RTK_HWREV_8169S, RTK_8169, "8169S"},
-	{ RTK_HWREV_8110S, RTK_8169, "8110S"},
-	{ RTK_HWREV_8169_8110SB, RTK_8169, "8169SB"},
-	{ RTK_HWREV_8169_8110SC, RTK_8169, "8169SC"},
-	{ RTK_HWREV_8100E, RTK_8169, "8100E"},
-	{ RTK_HWREV_8101E, RTK_8169, "8101E"},
-	{ RTK_HWREV_8100, RTK_8139, "8100"},
-	{ RTK_HWREV_8101, RTK_8139, "8101"},
-	{ 0, 0, NULL }
-};
-
 #define RE_LINKSYS_EG1032_SUBID	0x00241737
 
 CFATTACH_DECL(re_pci, sizeof(struct re_pci_softc), re_pci_match, re_pci_attach,
@@ -183,55 +139,29 @@
 {
 	const struct rtk_type	*t;
 	struct pci_attach_args	*pa = aux;
-	bus_space_tag_t		iot, memt, bst;
-	bus_space_handle_t	ioh, memh, bsh;
-	bus_size_t		memsize, iosize, bsize;
-	u_int32_t		hwrev;
 	pcireg_t subid;
-	bool ioh_valid, memh_valid;
 
 	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
 
 	/* special-case Linksys EG1032, since rev 2 uses sk(4) */
 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LINKSYS &&
-	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LINKSYS_EG1032 &&
-	    subid == RE_LINKSYS_EG1032_SUBID)
-		return 1;
+	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LINKSYS_EG1032) {
+		if (subid != RE_LINKSYS_EG1032_SUBID)
+			return 0;
+	}
+	/* Don't match 8139 other than C-PLUS */
+	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK &&
+	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8139) {
+		if (PCI_REVISION(pa->pa_class) != 0x20)
+			return 0;
+	}
 
 	t = re_devs;
 
 	while (t->rtk_name != NULL) {
 		if ((PCI_VENDOR(pa->pa_id) == t->rtk_vid) &&
 		    (PCI_PRODUCT(pa->pa_id) == t->rtk_did)) {
-
-			/*
-			 * Temporarily map the I/O space
-			 * so we can read the chip ID register.
-			 */
-			ioh_valid = (pci_mapreg_map(pa, RTK_PCI_LOIO,
-			    PCI_MAPREG_TYPE_IO, 0, &iot, &ioh,
-			    NULL, &iosize) == 0);
-			memh_valid = (pci_mapreg_map(pa, RTK_PCI_LOMEM,
-			    PCI_MAPREG_TYPE_MEM, 0, &memt, &memh,
-			    NULL, &memsize) == 0);
-			if (ioh_valid) {
-				bst = iot;
-				bsh = ioh;
-				bsize = iosize;
-			} else if (memh_valid) {
-				bst = memt;
-				bsh = memh;
-				bsize = memsize;
-			} else
-				return 0;
-			hwrev = bus_space_read_4(bst, bsh, RTK_TXCFG) &
-			    RTK_TXCFG_HWREV;
-			if (ioh_valid)
-				bus_space_unmap(iot, ioh, iosize);
-			if (memh_valid)
-				bus_space_unmap(memt, memh, memsize);
-			if (t->rtk_basetype == hwrev)
-				return 2;	/* defeat rtk(4) */
+			return 2;	/* defect rtk(4) */
 		}
 		t++;
 	}
@@ -249,10 +179,9 @@
 	pci_intr_handle_t ih;
 	const char *intrstr = NULL;
 	const struct rtk_type	*t;
-	const struct rtk_hwrev	*hw_rev;
 	uint32_t		hwrev;
 	int			error = 0;
-	int			pmreg;
+	pcireg_t		pmreg, memtype;
 	bool			ioh_valid, memh_valid;
 	pcireg_t		command;
 	bus_space_tag_t		iot, memt;
@@ -298,8 +227,18 @@
 
 	ioh_valid = (pci_mapreg_map(pa, RTK_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
 	    &iot, &ioh, NULL, &iosize) == 0);
-	memh_valid = (pci_mapreg_map(pa, RTK_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
-	    &memt, &memh, NULL, &memsize) == 0);
+	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RTK_PCI_LOMEM);
+	switch (memtype) {
+	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
+	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
+		memh_valid = (pci_mapreg_map(pa, RTK_PCI_LOMEM,
+		    memtype, 0, &memt, &memh, NULL, &memsize) == 0);
+		break;
+	default:
+		memh_valid = 0;
+		break;
+	}
+
 	if (ioh_valid) {
 		sc->rtk_btag = iot;
 		sc->rtk_bhandle = ioh;
@@ -319,23 +258,20 @@
 	while (t->rtk_name != NULL) {
 		if ((PCI_VENDOR(pa->pa_id) == t->rtk_vid) &&
 		    (PCI_PRODUCT(pa->pa_id) == t->rtk_did)) {
-
-			if (t->rtk_basetype == hwrev)
-				break;
+			break;
 		}
 		t++;
 	}
-	aprint_normal(": %s\n", t->rtk_name);
 
-	hw_rev = re_hwrevs;
-	hwrev = CSR_READ_4(sc, RTK_TXCFG) & RTK_TXCFG_HWREV;
-	while (hw_rev->rtk_desc != NULL) {
-		if (hw_rev->rtk_rev == hwrev) {
-			sc->rtk_type = hw_rev->rtk_type;
-			break;
-		}
-		hw_rev++;
-	}
+	if (t->rtk_basetype == RTK_8139CPLUS)
+		sc->sc_quirk |= RTKQ_8139CPLUS;
+
+	if (t->rtk_basetype == RTK_8168 ||
+	    t->rtk_basetype == RTK_8101E)
+		sc->sc_quirk |= RTKQ_PCIE;
+
+	aprint_normal(": %s (rev. 0x%02x)\n",
+	    t->rtk_name, PCI_REVISION(pa->pa_class));
 
 	sc->sc_dmat = pa->pa_dmat;
 
Index: dev/pci/if_rtk_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_rtk_pci.c,v
retrieving revision 1.31
diff -u -r1.31 if_rtk_pci.c
--- dev/pci/if_rtk_pci.c	25 Feb 2007 04:19:32 -0000	1.31
+++ dev/pci/if_rtk_pci.c	19 Mar 2007 14:53:40 -0000
@@ -248,7 +248,8 @@
 		return;
 	}
 
-	sc->rtk_type = t->rtk_basetype;
+	if (t->rtk_basetype == RTK_8129)
+		sc->sc_quirk |= RTKQ_8129;
 
 	printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);