Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jan 2011 19:20:09 +0300
From:      Lev Serebryakov <lev@serebryakov.spb.ru>
To:        freebsd-net@freebsd.org
Subject:   [patch] re(4) problems on networks with disabled autonegotiation "solver" (WAS: Juniper e3k with ports limitied to...) -- REQUEST FOR REVIEW
Message-ID:  <36074996.20110112192009@serebryakov.spb.ru>

index | next in thread | raw e-mail

[-- Attachment #1 --]
Hello, Freebsd-net.

  Thanks to Pyun YongHyeon, who point me at fact, that rgephy(4) used
with re(4) does autonegotiation always and all other, who helps me
diagnose problem!

  I've prepared patch, which adds tunable/sysctl for rgephy(4) which
allows not to sue autonegotiation by this PHY (at user responsibility,
as here is PHYs which CAN NOT live without autonegotiation). It is OFF
by default, and in such case behavior of driver IS NOT CHANGED.

  But if it is set ON (non-zero value) before "media / mediopt"
changes via "ifconfig" autonegotiation IS NOT set with 10/100Mbit
settings.

  I've documented this new tunable in re(4) manpage, as here is no
rgephy(4) manpage.

  Tunable is per-device, not global one.

  Sysctl can be set after boot, but will affect only future ifconfig
 calls, it doesn't change anything in PHY settings by itself.

  It allows fully manual setup on non-buggy hardware, which allows to
use Hetzner dedicated servers with FreeBSD without additional NIC or
gigabit connection.

  I've tested this patch on FreeBSD 8-STABLE on Hetzner server and it
allows me to get full-duplex 100Mbit connection and I got 11MiB/s from
local NFS with it.

  Without this patch FreeBSD is unusable on Hetzner dedicated servers
in newer DCs (DC 13 and DC 14).

  Patch is attached. I think, it worths to include it to base system,
as it allows use FreeBSD at least on one very large and popular
hosting provider without additional costs :)

-- 
// Black Lion AKA Lev Serebryakov <lev@serebryakov.spb.ru>
[-- Attachment #2 --]
diff -ruN /mnt/src/share/man/man4/re.4 share/man/man4/re.4
--- /mnt/src/share/man/man4/re.4	2011-01-12 16:14:28.000000000 +0300
+++ share/man/man4/re.4	2011-01-12 19:00:11.000000000 +0300
@@ -178,6 +178,26 @@
 .It Va hw.re.msi_disable
 This tunable disables MSI support on the Ethernet hardware.
 The default value is 0.
+.It Va dev.rgephy.%d.autoneg_can_be_disabled
+By default, rgephy, PHY used with supported Realtek controllers, always
+uses autonegotiation, even if
+.Cm media
+or
+.Cm mdeiaopt
+are specified by user. It is done to avoid bug in some PHY
+implementations. Sometimes you need to disable autonegotiation anywhere.
+This tunable, if set to non-zero value, enables to use manual media settings
+without autonegoteation at all. If 
+.Cm media
+is set as 
+.Cm autoselect
+autonegotiation will not depend on this tunable. This tunable is accessible
+as sysctl too, but affects only future using of 
+.Cm media
+and
+.Cm mediaopt
+options of
+.Xr ifconfig 8
 .El
 .Sh DIAGNOSTICS
 .Bl -diag
diff -ruN /mnt/src/sys/dev/mii/rgephy.c sys/dev/mii/rgephy.c
--- /mnt/src/sys/dev/mii/rgephy.c	2011-01-12 16:14:26.000000000 +0300
+++ sys/dev/mii/rgephy.c	2011-01-12 18:52:06.000000000 +0300
@@ -42,6 +42,7 @@
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
+#include <sys/sysctl.h>
 #include <sys/bus.h>
 
 #include <net/if.h>
@@ -66,6 +67,7 @@
 	struct mii_softc mii_sc;
 	int mii_model;
 	int mii_revision;
+	int mii_autoneg_can_be_disabled;
 };
 
 static device_method_t rgephy_methods[] = {
@@ -113,6 +115,7 @@
 	struct mii_softc *sc;
 	struct mii_attach_args *ma;
 	struct mii_data *mii;
+	char tn[64];
 
 	rsc = device_get_softc(dev);
 	sc = &rsc->mii_sc;
@@ -129,6 +132,16 @@
 
 	rsc->mii_model = MII_MODEL(ma->mii_id2);
 	rsc->mii_revision = MII_REV(ma->mii_id2);
+	
+	rsc->mii_autoneg_can_be_disabled = 0;
+	snprintf(tn, sizeof(tn), "dev.%s.%d.autoneg_can_be_disabled",
+	    device_get_name(dev), device_get_unit(dev));
+	TUNABLE_INT_FETCH(tn, &rsc->mii_autoneg_can_be_disabled);
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "autoneg_can_be_disabled", CTLFLAG_RW,
+	    &rsc->mii_autoneg_can_be_disabled, 0,
+	    "Autonegation can be disabled on adapter");
 
 #define	ADD(m, c)	ifmedia_add(&mii->mii_media, (m), (c), NULL)
 
@@ -213,11 +226,12 @@
 			}
 
 			if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) {
+				if (!rsc->mii_autoneg_can_be_disabled)
+					speed |= RGEPHY_BMCR_AUTOEN |
+					    RGEPHY_BMCR_STARTNEG;
 				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);
+				PHY_WRITE(sc, RGEPHY_MII_BMCR, speed);
 				break;
 			}
 
help

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