re(4) link goes down when manually setting media type
Pyun YongHyeon
pyunyh at gmail.com
Thu Aug 10 09:29:41 UTC 2006
On Tue, Aug 08, 2006 at 10:06:56AM +0200, Jelte Jansen wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>
> Hi,
>
> i have a problem with the if_re driver for my gigabit network card
> (RTL8196). When i set it to autoselect, it works fine,
> although with apparently random performance problems. When i try to set
> it to a fixed media type (both 100baseTX and 1000baseTX) the link goes
> down, and stays down until i set it to autoselect again. It does seem to
> work when setting it to 10baset/utp.
>
> This happens with the driver in -CURRENT (__FBSDID("$FreeBSD:
> src/sys/dev/re/if_re.c,v 1.72 2006/08/03 00:15:19 yongari Ex)
>
> I have seen in the issue tracker and on the -current and -stable that
> there were other problems with the re(4) driver, but did not see this
> one. Any ideas?
>
Due to the poor PHY documentation from RealTek I can't sure but
I guess the RealTek PHY needs to set RGEPHY_BMCR_AUTOEN bit of
RGEPHY_MII_BMCR register and proper ANAR register setting for
manual media type selection.
How about attached patch?
--
Regards,
Pyun YongHyeon
-------------- next part --------------
Index: rgephy.c
===================================================================
RCS file: /pool/ncvs/src/sys/dev/mii/rgephy.c,v
retrieving revision 1.10
diff -u -r1.10 rgephy.c
--- rgephy.c 3 Jul 2006 02:53:39 -0000 1.10
+++ rgephy.c 10 Aug 2006 09:28:26 -0000
@@ -166,7 +166,7 @@
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
- int reg, speed, gig;
+ int reg, speed, gig, anar;
switch (cmd) {
case MII_POLLSTAT:
@@ -196,6 +196,10 @@
rgephy_reset(sc); /* XXX hardware bug work-around */
+ anar = PHY_READ(sc, RGEPHY_MII_ANAR);
+ anar &= ~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX |
+ RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10);
+
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_AUTO:
#ifdef foo
@@ -212,28 +216,30 @@
goto setit;
case IFM_100_TX:
speed = RGEPHY_S100;
+ anar |= RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX;
goto setit;
case IFM_10_T:
speed = RGEPHY_S10;
+ anar |= RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10;
setit:
rgephy_loop(sc);
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) {
speed |= RGEPHY_BMCR_FDX;
gig = RGEPHY_1000CTL_AFD;
+ anar &= ~(RGEPHY_ANAR_TX | RGEPHY_ANAR_10);
} else {
gig = RGEPHY_1000CTL_AHD;
+ anar &=
+ ~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_10_FD);
}
- PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
- PHY_WRITE(sc, RGEPHY_MII_BMCR, speed);
- PHY_WRITE(sc, RGEPHY_MII_ANAR, RGEPHY_SEL_TYPE);
-
- if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T)
+ if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) {
+ PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
+ PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
+ PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
+ RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
break;
-
- PHY_WRITE(sc, RGEPHY_MII_1000CTL, gig);
- PHY_WRITE(sc, RGEPHY_MII_BMCR,
- speed|RGEPHY_BMCR_AUTOEN|RGEPHY_BMCR_STARTNEG);
+ }
/*
* When settning the link manually, one side must
@@ -250,6 +256,8 @@
PHY_WRITE(sc, RGEPHY_MII_1000CTL,
gig|RGEPHY_1000CTL_MSE);
}
+ PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
+ RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
break;
#ifdef foo
case IFM_NONE:
More information about the freebsd-current
mailing list