Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Dec 2015 17:34:29 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r292784 - in stable/9/sys/dev: re rl
Message-ID:  <201512271734.tBRHYTYv031969@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Sun Dec 27 17:34:29 2015
New Revision: 292784
URL: https://svnweb.freebsd.org/changeset/base/292784

Log:
  MFC: r287768, r290566, r290946
  
  - Although it doesn't make a whole lot of sense to enable RX and TX
    before their initial configuration is done, it turns out that r281337
    (MFCed to stable/9 in r285178) has the inverse effect on some older
    chips. Moreover, as with newer chips before, two chips seemingly
    identical according to their MAC revisions may behave differently in
    this regard, with most working but a few not, making changes extremely
    hard to test.
    Closer inspection of the corresponding Linux code suggests that RX
    and TX should only be enabled after their initial configuration with
    RTL8168G and later chips, i. e. RTL8106E{,US}, RTL8107E, as well as
    RTL8168{EP,G,GU,H}, so limit the new code path to these. [1]
  - Distinguish between RTL8168H and RTL8107E, with the latter being the
    10/100-Mbit/s-only variant of the former.
  - For MAC variants that can only do Fast Ethernet at a maximum, ensure
    that we don't advertise Gigabit Ethernet speed.
  - In re_stop(), do the inverse of re_init_locked() and enable RXDV
    gate on RTL8168G and later chips again, matching what Linux does.
  - With the latter in place, it turns out that WOL previously only worked
    by accident with RTL8168G and later chips when the interface actually
    was brought up. This is due to the fact that with these MAC variants,
    RXDV gate needs be disabled for WOL to work. So in re_setwol() do just
    that when IFCAP_WOL is requested.
  - Add preliminary support for RTL8168H and RTL8107E, with the latter
    being the 10/100-Mbit/s-only variant of the former.

Modified:
  stable/9/sys/dev/re/if_re.c
  stable/9/sys/dev/rl/if_rlreg.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/re/if_re.c
==============================================================================
--- stable/9/sys/dev/re/if_re.c	Sun Dec 27 17:34:18 2015	(r292783)
+++ stable/9/sys/dev/re/if_re.c	Sun Dec 27 17:34:29 2015	(r292784)
@@ -237,6 +237,7 @@ static const struct rl_hwrev re_hwrevs[]
 	{ RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8168G, RL_8169, "8168G/8111G", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8168GU, RL_8169, "8168GU/8111GU", RL_JUMBO_MTU_9K},
+	{ RL_HWREV_8168H, RL_8169, "8168H/8111H", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8411B, RL_8169, "8411B", RL_JUMBO_MTU_9K},
 	{ 0, 0, NULL, 0 }
@@ -633,9 +634,8 @@ re_miibus_statchg(device_t dev)
 		}
 	}
 	/*
-	 * RealTek controllers does not provide any interface to
-	 * Tx/Rx MACs for resolved speed, duplex and flow-control
-	 * parameters.
+	 * RealTek controllers do not provide any interface to the RX/TX
+	 * MACs for resolved speed, duplex and flow-control parameters.
 	 */
 }
 
@@ -657,7 +657,7 @@ re_set_rxmode(struct rl_softc *sc)
 	rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
 	if ((sc->rl_flags & RL_FLAG_EARLYOFF) != 0)
 		rxfilt |= RL_RXCFG_EARLYOFF;
-	else if ((sc->rl_flags & RL_FLAG_EARLYOFFV2) != 0)
+	else if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
 		rxfilt |= RL_RXCFG_EARLYOFFV2;
 
 	if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
@@ -1204,11 +1204,10 @@ re_attach(device_t dev)
 	struct rl_softc		*sc;
 	struct ifnet		*ifp;
 	const struct rl_hwrev	*hw_rev;
+	int			capmask, error = 0, hwrev, i, msic, msixc,
+				phy, reg, rid;
 	u_int32_t		cap, ctl;
-	int			hwrev;
 	u_int16_t		devid, re_did = 0;
-	int			error = 0, i, phy, rid;
-	int			msic, msixc, reg;
 	uint8_t			cfg;
 
 	sc = device_get_softc(dev);
@@ -1488,11 +1487,12 @@ re_attach(device_t dev)
 		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
 		    RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
 		    RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK |
-		    RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+		    RL_FLAG_8168G_PLUS;
 		break;
 	case RL_HWREV_8168GU:
+	case RL_HWREV_8168H:
 		if (pci_get_device(dev) == RT_DEVICEID_8101E) {
-			/* RTL8106EUS */
+			/* RTL8106E(US), RTL8107E */
 			sc->rl_flags |= RL_FLAG_FASTETHER;
 		} else
 			sc->rl_flags |= RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK;
@@ -1500,7 +1500,7 @@ re_attach(device_t dev)
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
 		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
 		    RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ |
-		    RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+		    RL_FLAG_8168G_PLUS;
 		break;
 	case RL_HWREV_8169_8110SB:
 	case RL_HWREV_8169_8110SBL:
@@ -1650,8 +1650,11 @@ re_attach(device_t dev)
 	phy = RE_PHYAD_INTERNAL;
 	if (sc->rl_type == RL_8169)
 		phy = 1;
+	capmask = BMSR_DEFCAPMASK;
+	if ((sc->rl_flags & RL_FLAG_FASTETHER) != 0)
+		 capmask &= ~BMSR_EXTSTAT;
 	error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd,
-	    re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
+	    re_ifmedia_sts, capmask, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
 	if (error != 0) {
 		device_printf(dev, "attaching PHYs failed\n");
 		goto fail;
@@ -1691,13 +1694,13 @@ re_attach(device_t dev)
 #ifdef DEV_NETMAP
 	re_netmap_attach(sc);
 #endif /* DEV_NETMAP */
+
 #ifdef RE_DIAG
 	/*
 	 * Perform hardware diagnostic on the original RTL8169.
 	 * Some 32-bit cards were incorrectly wired and would
 	 * malfunction if plugged into a 64-bit slot.
 	 */
-
 	if (hwrev == RL_HWREV_8169) {
 		error = re_diag(sc);
 		if (error) {
@@ -1729,7 +1732,6 @@ re_attach(device_t dev)
 	}
 
 fail:
-
 	if (error)
 		re_detach(dev);
 
@@ -2935,6 +2937,7 @@ re_start_locked(struct ifnet *ifp)
 		return;
 	}
 #endif /* DEV_NETMAP */
+
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
 	    IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
 		return;
@@ -3190,9 +3193,18 @@ re_init_locked(struct rl_softc *sc)
 	CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
 	    RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr));
 
-	if ((sc->rl_flags & RL_FLAG_RXDV_GATED) != 0)
+	if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+		/* Disable RXDV gate. */
 		CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
 		    ~0x00080000);
+	}
+
+	/*
+	 * Enable transmit and receive for pre-RTL8168G controllers.
+	 * RX/TX MACs should be enabled before RX/TX configuration.
+	 */
+	if ((sc->rl_flags & RL_FLAG_8168G_PLUS) == 0)
+		CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
 
 	/*
 	 * Set the initial TX configuration.
@@ -3221,9 +3233,11 @@ re_init_locked(struct rl_softc *sc)
 	}
 
 	/*
-	 * Enable transmit and receive.
+	 * Enable transmit and receive for RTL8168G and later controllers.
+	 * RX/TX MACs should be enabled after RX/TX configuration.
 	 */
-	CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
+	if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
+		CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
 
 #ifdef DEVICE_POLLING
 	/*
@@ -3579,6 +3593,12 @@ re_stop(struct rl_softc *sc)
 	    ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI |
 	    RL_RXCFG_RX_BROAD));
 
+	if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+		/* Enable RXDV gate. */
+		CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) |
+		    0x00080000);
+	}
+
 	if ((sc->rl_flags & RL_FLAG_WAIT_TXPOLL) != 0) {
 		for (i = RL_TIMEOUT; i > 0; i--) {
 			if ((CSR_READ_1(sc, sc->rl_txstart) &
@@ -3830,6 +3850,11 @@ re_setwol(struct rl_softc *sc)
 			    CSR_READ_1(sc, RL_GPIO) & ~0x01);
 	}
 	if ((ifp->if_capenable & IFCAP_WOL) != 0) {
+		if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+			/* Disable RXDV gate. */
+			CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
+			    ~0x00080000);
+		}
 		re_set_rxmode(sc);
 		if ((sc->rl_flags & RL_FLAG_WOL_MANLINK) != 0)
 			re_set_linkspeed(sc);
@@ -3942,7 +3967,6 @@ re_add_sysctls(struct rl_softc *sc)
 			sc->rl_int_rx_mod = RL_TIMER_DEFAULT;
 		}
 	}
-
 }
 
 static int

Modified: stable/9/sys/dev/rl/if_rlreg.h
==============================================================================
--- stable/9/sys/dev/rl/if_rlreg.h	Sun Dec 27 17:34:18 2015	(r292783)
+++ stable/9/sys/dev/rl/if_rlreg.h	Sun Dec 27 17:34:29 2015	(r292784)
@@ -195,6 +195,7 @@
 #define	RL_HWREV_8168G		0x4C000000
 #define	RL_HWREV_8168EP		0x50000000
 #define	RL_HWREV_8168GU		0x50800000
+#define	RL_HWREV_8168H		0x54000000
 #define	RL_HWREV_8411B		0x5C800000
 #define	RL_HWREV_8139		0x60000000
 #define	RL_HWREV_8139A		0x70000000
@@ -930,8 +931,7 @@ struct rl_softc {
 #define	RL_FLAG_CMDSTOP_WAIT_TXQ	0x00008000
 #define	RL_FLAG_WOL_MANLINK	0x00010000
 #define	RL_FLAG_EARLYOFF	0x00020000
-#define	RL_FLAG_EARLYOFFV2	0x00040000
-#define	RL_FLAG_RXDV_GATED	0x00080000
+#define	RL_FLAG_8168G_PLUS	0x00040000
 #define	RL_FLAG_PCIE		0x40000000
 #define	RL_FLAG_LINK		0x80000000
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512271734.tBRHYTYv031969>