Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Oct 2008 03:41:36 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r184245 - head/sys/pci
Message-ID:  <200810250341.m9P3faHB015427@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Sat Oct 25 03:41:36 2008
New Revision: 184245
URL: http://svn.freebsd.org/changeset/base/184245

Log:
  Implement miibus_statchg handler. It detects whether rl(4)
  established a valid link or not.
  In rl_start_locked, don't try to send packets unless we have valid
  link. While I'm here add a check that verifies whether driver can
  accept Tx requests by inspecting IFF_DRV_OACTIVE/IFF_DRV_RUNNING
  flag.

Modified:
  head/sys/pci/if_rl.c

Modified: head/sys/pci/if_rl.c
==============================================================================
--- head/sys/pci/if_rl.c	Sat Oct 25 03:36:21 2008	(r184244)
+++ head/sys/pci/if_rl.c	Sat Oct 25 03:41:36 2008	(r184245)
@@ -636,6 +636,34 @@ rl_miibus_writereg(device_t dev, int phy
 static void
 rl_miibus_statchg(device_t dev)
 {
+	struct rl_softc		*sc;
+	struct ifnet		*ifp;
+	struct mii_data		*mii;
+
+	sc = device_get_softc(dev);
+	mii = device_get_softc(sc->rl_miibus);
+	ifp = sc->rl_ifp;
+	if (mii == NULL || ifp == NULL ||
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	sc->rl_flags &= ~RL_FLAG_LINK;
+	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_10_T:
+		case IFM_100_TX:
+			sc->rl_flags |= RL_FLAG_LINK;
+			break;
+		default:
+			break;
+		}
+	}
+	/*
+	 * RealTek controllers do not provide any interface to
+	 * Tx/Rx MACs for resolved speed, duplex and flow-control
+	 * parameters.
+	 */
 }
 
 /*
@@ -1545,6 +1573,10 @@ rl_start_locked(struct ifnet *ifp)
 
 	RL_LOCK_ASSERT(sc);
 
+	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
+		return;
+
 	while (RL_CUR_TXMBUF(sc) == NULL) {
 
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
@@ -1686,6 +1718,7 @@ rl_init_locked(struct rl_softc *sc)
 	/* Enable receiver and transmitter. */
 	CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
 
+	sc->rl_flags &= ~RL_FLAG_LINK;
 	mii_mediachg(mii);
 
 	CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX);
@@ -1831,6 +1864,7 @@ rl_stop(struct rl_softc *sc)
 	sc->rl_watchdog_timer = 0;
 	callout_stop(&sc->rl_stat_callout);
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	sc->rl_flags &= ~RL_FLAG_LINK;
 
 	CSR_WRITE_1(sc, RL_COMMAND, 0x00);
 	CSR_WRITE_2(sc, RL_IMR, 0x0000);



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