Subject: Re: Realtek 8168B/8111B not configured on netbsd-3 branch
To: None <bradd@cat.co.za>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-i386
Date: 09/28/2007 21:34:25
bradd@cat.co.za wrote:

> Should I expect this to work on netbsd-3?

No. Related changes on the HEAD has been pulled up
only to netbsd-4.

Could you try the attached patch for netbsd-3?
if it works I'll also send a request for the branch.
---
Izumi Tsutsui


Index: sys/dev/cardbus/if_re_cardbus.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cardbus/if_re_cardbus.c,v
retrieving revision 1.5.2.1
diff -u -r1.5.2.1 if_re_cardbus.c
--- sys/dev/cardbus/if_re_cardbus.c	3 Mar 2007 23:30:23 -0000	1.5.2.1
+++ sys/dev/cardbus/if_re_cardbus.c	28 Sep 2007 12:21:41 -0000
@@ -235,7 +235,6 @@
 	 */
 	re_cardbus_setup(csc);
 
-	sc->rtk_type = t->rtk_basetype;
 	sc->sc_dmat = ca->ca_dmat;
 	re_attach(sc);
 
Index: sys/dev/cardbus/if_rtk_cardbus.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cardbus/if_rtk_cardbus.c,v
retrieving revision 1.25.2.1
diff -u -r1.25.2.1 if_rtk_cardbus.c
--- sys/dev/cardbus/if_rtk_cardbus.c	3 Mar 2007 23:30:23 -0000	1.25.2.1
+++ sys/dev/cardbus/if_rtk_cardbus.c	28 Sep 2007 12:21:41 -0000
@@ -252,7 +252,6 @@
 	 * configuration registers.
 	 */
 	rtk_cardbus_setup(csc);
-	sc->rtk_type = t->rtk_basetype;
 
 	rtk_attach(sc);
 
Index: sys/dev/ic/rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.14.2.6
diff -u -r1.14.2.6 rtl8169.c
--- sys/dev/ic/rtl8169.c	3 Mar 2007 23:30:24 -0000	1.14.2.6
+++ sys/dev/ic/rtl8169.c	28 Sep 2007 12:21:44 -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);
@@ -1188,7 +1192,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)) {
@@ -1353,9 +1357,21 @@
 	 * interrupt that will cause us to re-enter this routine.
 	 * This is done in case the transmitter has gone idle.
 	 */
-	if (sc->re_ldata.re_txq_free < RE_TX_QLEN)
+	if (sc->re_ldata.re_txq_free < RE_TX_QLEN) {
 		CSR_WRITE_4(sc, RTK_TIMERCNT, 1);
-	else
+		if ((sc->sc_quirk & RTKQ_PCIE) != 0) {
+			/*
+			 * Some chips will ignore a second TX request
+			 * issued while an existing transmission is in
+			 * progress. If the transmitter goes idle but
+			 * there are still packets waiting to be sent,
+			 * we need to restart the channel here to flush
+			 * them out. This only seems to be required with
+			 * the PCIe devices.
+			 */
+			CSR_WRITE_2(sc, RTK_GTXSTART, RTK_TXSTART_START);
+		}
+	} else
 		ifp->if_timer = 0;
 }
 
@@ -1724,10 +1740,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.
@@ -1779,10 +1795,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 ? */
@@ -1798,7 +1814,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);
@@ -1844,13 +1860,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);
 
@@ -1914,17 +1927,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: sys/dev/ic/rtl81x9.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9.c,v
retrieving revision 1.51.2.1
diff -u -r1.51.2.1 rtl81x9.c
--- sys/dev/ic/rtl81x9.c	3 Mar 2007 23:30:24 -0000	1.51.2.1
+++ sys/dev/ic/rtl81x9.c	28 Sep 2007 12:21:44 -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: sys/dev/ic/rtl81x9reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9reg.h,v
retrieving revision 1.11.2.3
diff -u -r1.11.2.3 rtl81x9reg.h
--- sys/dev/ic/rtl81x9reg.h	3 Mar 2007 23:30:24 -0000	1.11.2.3
+++ sys/dev/ic/rtl81x9reg.h	28 Sep 2007 12:21:45 -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: sys/dev/ic/rtl81x9var.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9var.h,v
retrieving revision 1.17.4.2
diff -u -r1.17.4.2 rtl81x9var.h
--- sys/dev/ic/rtl81x9var.h	3 Mar 2007 23:30:24 -0000	1.17.4.2
+++ sys/dev/ic/rtl81x9var.h	28 Sep 2007 12:21:45 -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: sys/dev/pci/if_re_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_re_pci.c,v
retrieving revision 1.8.2.6
diff -u -r1.8.2.6 if_re_pci.c
--- sys/dev/pci/if_re_pci.c	10 Mar 2007 18:54:15 -0000	1.8.2.6
+++ sys/dev/pci/if_re_pci.c	28 Sep 2007 12:21:46 -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;
-	boolean_t 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;
 	boolean_t		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: sys/dev/pci/if_rtk_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_rtk_pci.c,v
retrieving revision 1.22.4.2
diff -u -r1.22.4.2 if_rtk_pci.c
--- sys/dev/pci/if_rtk_pci.c	3 Mar 2007 23:30:25 -0000	1.22.4.2
+++ sys/dev/pci/if_rtk_pci.c	28 Sep 2007 12:21:46 -0000
@@ -247,7 +247,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);