[patch] epic100.c - activating fiber interface for the SMC EtherPower II NIC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!

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

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

DISCLAIMER:

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

b) He decided to put the new code mainly in check_media(), which will be 
called every 5 seconds. So it can take up to 5 seconds 'till media change is 
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 report 
if they work for them. We need reports from UTP users as well as from Fiber 
users. Especially interesting would be reports from SMP-systems. 

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

It *won't* apply w/o changes to the epic100.c v.1.14/1.15 found on 
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 
(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 
"***warning*** (mii-transciever not found)"
it doesn´t 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 enable 
it.

3. in function epic_open():
the section followed by the inserted mdio_write was cutted out, modified and 
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 is up, 
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 
types of media needs some time (1 to 5 sec) till the change is realised by 
the driver.
the throughput shouldn´t be influenced by this change (cause there is only 1 
mdio_read() and 1 if-clause called every 5 seconds).

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

Thanks,

Christoph Dolina.

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

-- 
Ciao,

Gernot
--- 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;

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux