[epic] [PATCH] activating fiber interface for the SMC EtherPower II NIC

Gernot Hillier gernot@hillier.de
Fri Jun 28 18:25:03 2002


--------------Boundary-00=_O6TETYHDQ2H82K078CVF
Content-Type: text/plain;
  charset="utf-8"
Content-Transfer-Encoding: quoted-printable

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

As we have many SMC Etherpower II cards installed in Intel-workstations i=
n our=20
university (UAS Landshut, Germany), we were very disappointed that the=20
Kernel-Driver epic100.c didn't support the fiber interface of these cards=
=2E

So I convinced a college, who has some knowledge about NICs and MIIs to h=
ave a=20
look at the driver and he finally manged to get the epic100.c-driver to w=
ork=20
with the fiber interface of these cards.

DISCLAIMER:

a) Neither the author of this patch nor I have much knowledge about devel=
oping=20
Linux drivers. So please handle with care. But as far as we can see, ther=
e=20
should be nothing critical triggered by our changes.

b) He decided to put the new code mainly in check_media(), which will be=20
called every 5 seconds. So it can take up to 5 seconds 'till media change=
 is=20
detected and a link is shown. So be patient... ;-))

If you have any idea how this could be improved, please tell us!

For further details, see his description, below.

We would GREATLY appreciate if many of you could test our changes and rep=
ort=20
if they work for them. We need reports from UTP users as well as from Fib=
er=20
users. Especially interesting would be reports from SMP-systems.=20

The attached patch applies cleanly to the current SuSE-kernel and applies=
=20
nearly cleanly to the current Marcelo-kernel. (if the first hunk fails, d=
on't=20
worry, these are only some changes to comments and versions).=20

It *won't* apply w/o changes to the epic100.c v.1.14/1.15 found on=20
www.scyld.com. If you need a patch for these versions, please tell me!

So, thanks in advance for your help!

- -------------------------------------------

From: Christoph Dolina <Christoph.Dolina@fh-landshut.de>
To: gernot@hillier.de
Date: Thu, 27 Jun 2002 11:25:50 +0200

Changes made to activate the fiber interface at the SMC EtherPower II NIC=
=20
(26.Jun.2002) by Christoph Dolina (cdolina@fh-landshut.de):

1. in function epic_open():
udelay(), without udelay, hardware not yet rised up and you got sometimes=
=20
"***warning*** (mii-transciever not found)"
it doesn=C2=B4t matter the function, but it disturbed me :-)

2. in function epic_open():
mdio_write to the config-Register inserted, for power-on at fiber and ena=
ble=20
it.

3. in function epic_open():
the section followed by the inserted mdio_write was cutted out, modified =
and=20
pasted to the function check_media()

4. in function check_media():
the section meant in (3.) was modified for check if link is up; if link i=
s up,=20
do nothing more, if link is down, change type of media

NOTE:
check_media is called every 5 seconds, so a physical change between the 2=
=20
types of media needs some time (1 to 5 sec) till the change is realised b=
y=20
the driver.
the throughput shouldn=C2=B4t be influenced by this change (cause there i=
s only 1=20
mdio_read() and 1 if-clause called every 5 seconds).

If you think there is a possibility to fix the "delay" appearing at the c=
hange=20
of media, be free to send me an email or to change it yourself.

Thanks,

Christoph Dolina.

- ------------------------------------

- --=20
Ciao,

Gernot
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9HC1Ck997/GGeSeIRAj4dAJ4oZgaTWrQyK5OkSZZPSGG6+xGuGQCfVLXI
yRD3pU19oBox3DphvtTJawg=3D
=3DSdyg
-----END PGP SIGNATURE-----

--------------Boundary-00=_O6TETYHDQ2H82K078CVF
Content-Type: text/x-diff;
  charset="us-ascii";
  name="epic100_fx_2.4.18.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="epic100_fx_2.4.18.diff"

--- epic100.c.orig	Thu Jun 27 10:19:52 2002
+++ epic100.c	Thu Jun 27 11:24:42 2002
@@ -63,11 +63,15 @@
 	LK1.1.13:
 	* revert version 1.1.12, power-up sequence "fix"
 
+       	LK1.1.xx:
+       	* fiber link enabled (Christoph Dolina), switch media delayed by 5 sec
+
+
 */
 
 #define DRV_NAME	"epic100"
-#define DRV_VERSION	"1.11+LK1.1.13"
-#define DRV_RELDATE	"Mar 20, 2002"
+#define DRV_VERSION   "1.11+LK1.1.xx"
+#define DRV_RELDATE   "Jun 26, 2002"
 
 
 /* The user-configurable values.
@@ -697,35 +701,22 @@
 	outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
 #endif
 
+	/* (Christoph Dolina): Needed for rising up the Hardware */
+	{ udelay(200); }
+
 	for (i = 0; i < 3; i++)
 		outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
 
 	ep->tx_threshold = TX_FIFO_THRESH;
 	outl(ep->tx_threshold, ioaddr + TxThresh);
 
-	if (media2miictl[dev->if_port & 15]) {
-		if (ep->mii_phy_cnt)
-			mdio_write(dev, ep->phys[0], MII_BMCR, media2miictl[dev->if_port&15]);
-		if (dev->if_port == 1) {
-			if (debug > 1)
-				printk(KERN_INFO "%s: Using the 10base2 transceiver, MII "
-					   "status %4.4x.\n",
-					   dev->name, mdio_read(dev, ep->phys[0], MII_BMSR));
-		}
-	} else {
-		int mii_lpa = mdio_read(dev, ep->phys[0], MII_LPA);
-		if (mii_lpa != 0xffff) {
-			if ((mii_lpa & LPA_100FULL) || (mii_lpa & 0x01C0) == LPA_10FULL)
-				ep->mii.full_duplex = 1;
-			else if (! (mii_lpa & LPA_LPACK))
-				mdio_write(dev, ep->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
-			if (debug > 1)
-				printk(KERN_INFO "%s: Setting %s-duplex based on MII xcvr %d"
-					   " register read of %4.4x.\n", dev->name,
-					   ep->mii.full_duplex ? "full" : "half",
-					   ep->phys[0], mii_lpa);
-		}
-	}
+
+	/* 26.Jun.2002: Switch on the Power on Fiber and Enables the Fiber */
+	// Config-Reg (0x13): Fiber_Enable (0x0004), Fiber_On, Led_On
+	mdio_write(dev, ep->phys[0], 0x13, 0x0004 | 0x0040 | 0x0080);
+
+	/* 26.Jun.2002 Followed section moved to check_media() to switch btw. fiber and utp*/
+
 
 	outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
 	outl(ep->rx_ring_dma, ioaddr + PRxCDAR);
@@ -845,6 +836,69 @@
 	int mii_lpa = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], MII_LPA) : 0;
 	int negotiated = mii_lpa & ep->mii.advertising;
 	int duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
+	int i;
+
+	// Status-Reg (0x14): check FOR Link
+	i = mdio_read(dev, ep->phys[0], 0x14);
+
+	/* 26.Jun.2002 Following section moved from open()
+	   modified to switch btw. fiber and utp */
+
+	/* IF no Link, change type of media */
+	if ( ( i & 0x2000) == 0 ) {
+
+		/* read Config-Reg (0x13): check IF fiber is on */
+		i = mdio_read(dev, ep->phys[0], 0x13);
+
+		/* fiber on (and no link) then disable fiber */
+		if ( ( i & 0x0004 ) != 0 ) {
+			// Config-Reg (0x13): disable it
+			mdio_write(dev, ep->phys[0], 0x13, 0x0000);
+
+		/* and activate utp, this if-section is copied from function open_() */
+			{
+				if (media2miictl[dev->if_port & 15]) {
+					if (ep->mii_phy_cnt)
+						mdio_write(dev, ep->phys[0], MII_BMCR, media2miictl[dev->if_port&15]);
+					if (dev->if_port == 1) {
+						if (debug > 1)
+							printk(KERN_INFO "%s: Using the 10base2 transceiver, MII "
+								   "status %4.4x.\n",
+								   dev->name, mdio_read(dev, ep->phys[0], MII_BMSR));
+					}
+				} else {
+					int mii_lpa = mdio_read(dev, ep->phys[0], MII_LPA);
+					if (mii_lpa != 0xffff) {
+						if ((mii_lpa & LPA_100FULL) || (mii_lpa & 0x01C0) == LPA_10FULL)
+							ep->mii.full_duplex = 1;
+ 						else if (! (mii_lpa & LPA_LPACK))
+							mdio_write(dev, ep->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
+						if (debug > 1)
+							printk(KERN_INFO "%s: Setting %s-duplex based on MII xcvr %d"
+								   " register read of %4.4x.\n", dev->name,
+								   ep->mii.full_duplex ? "full" : "half",
+								   ep->phys[0], mii_lpa);
+					}
+				}
+			}
+		/* IF fiber off (and no link) then enable it */
+		} else {
+			/*	26.Jun.2002, Changes for Fiber (Christoph Dolina)
+				1. Switch on the Power and Enables the Fiber
+				2. Activates the Loopbackmode (forces the other side to autoneg.)
+				3. Deactivates the Loopback, back to net in 100Mbps and Fulldplx
+			*/
+
+			/* Config-Reg (0x13): Fiber_Enable (0x0004), Fiber_On, Led_On */
+			mdio_write(dev, ep->phys[0], 0x13, 0x0004 | 0x0040 | 0x0080);
+
+			/* Phy-BMC-Reg: Loopback */
+			mdio_write(dev, ep->phys[0], 0x00, 0x4000);
+
+			/*  Phy-BMC-Reg: Loopback aus(0x0002), FullDuplex (0x0100), 100Mbps (0x2000) */
+			mdio_write(dev, ep->phys[0], 0x00, 0x0002 | 0x0100 | 0x2000);
+		}
+	}
 
 	if (ep->mii.duplex_lock)
 		return;

--------------Boundary-00=_O6TETYHDQ2H82K078CVF--