Subject: Re: 3com 3c905B-tx strange behaviour
To: Tony Hernandez <dbsaint@bellsouth.net>
From: Robert Elz <kre@munnari.OZ.AU>
List: port-i386
Date: 08/30/1999 21:42:43
This is a multipart MIME message.

--==_Exmh_10736900560
Content-Type: text/plain; charset=us-ascii

    Date:        Mon, 30 Aug 1999 17:26:29 +1000
    From:        Robert Elz <kre@munnari.OZ.AU>
    Message-ID:  <10934.935997989@munnari.OZ.AU>

  | Then I'll send in a PR with the diffs.   I think it will become a fairly
  | small change.

It turned out to be a bit more than I expected - when I sent that
comment I had anticipated that more of the changes I had made along the
way would turn out to be irrelevant than actually did.

The PR number is kern/8294 - anyone who cares much about this stuff
should probably read the PR.

But for those who simply want to attempt to make their 33C905B-TX work,
when it hasn't been, the patch is appended below.   Apply it in the
/sys/dev/ic directory, and make sure that ukphy is included in the kernel
config.

If some of you with working 3C9xx cards would like to try this patch and
verify that it breaks nothing, I suspect that would be appreciated too.

kre



--==_Exmh_10736900560
Content-Type: text/plain ; name="3C905B-patch"; charset=us-ascii
Content-Description: 3C905B-patch
Content-Disposition: attachment; filename="3C905B-P"

*** elinkxlreg.h.was	Wed Nov  4 11:29:29 1998
--- elinkxlreg.h	Sat Aug 21 15:31:36 1999
***************
*** 177,182 ****
--- 177,184 ----
  #define CONFIG_XCVR_SEL		(u_int16_t) 0x00f0
  #define CONFIG_XCVR_SEL_SHIFT	4
  
+ #define	ELINKMEDIA_AUTO		8
+ 
  #define CONFIG_AUTOSEL		(u_int16_t) 0x0100
  #define CONFIG_AUTOSEL_SHIFT	8
  




*** elinkxl.c.was	Mon Aug 30 20:47:16 1999
--- elinkxl.c	Sat Aug 21 15:31:36 1999
***************
*** 382,387 ****
--- 382,403 ----
  		/*
  		 * Find PHY, extract media information from it.
  		 */
+ 		u_int32_t icfg;
+ 
+ 		/* stolen from FreeBSD xl driver */
+ 		GO_WINDOW(3);
+ 		icfg = bus_space_read_4(iot, ioh, ELINK_W3_INTERNAL_CONFIG);
+ 		icfg &= ~(CONFIG_XCVR_SEL << 16);
+ 		if (val & (ELINK_MEDIACAP_MII | ELINK_MEDIACAP_100BASET4))
+ 			icfg |= ELINKMEDIA_MII << (CONFIG_XCVR_SEL_SHIFT + 16);
+ 		if (val & ELINK_MEDIACAP_100BASETX)
+ 			icfg |= ELINKMEDIA_AUTO << (CONFIG_XCVR_SEL_SHIFT + 16);
+ 		if (val & ELINK_MEDIACAP_100BASEFX)
+ 			icfg |= ELINKMEDIA_100BASE_FX 
+ 				<< (CONFIG_XCVR_SEL_SHIFT + 16);
+ 		bus_space_write_4(iot, ioh, ELINK_W3_INTERNAL_CONFIG, icfg);
+ 		/* end steal */
+ 
  		mii_phy_probe(&sc->sc_dev, &sc->ex_mii, 0xffffffff);
  		if (LIST_FIRST(&sc->ex_mii.mii_phys) == NULL) {
  			ifmedia_add(&sc->ex_mii.mii_media, IFM_ETHER|IFM_NONE,
***************
*** 1714,1746 ****
  
  	bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_W4_PHYSMGMT, 0);
  
! 	ex_mii_clrbit(sc, ELINK_PHY_DIR);
          for (i = 0; i < 32; i++) {
-                 ex_mii_clrbit(sc, ELINK_PHY_CLK);
                  ex_mii_setbit(sc, ELINK_PHY_CLK);
          }
  	ex_mii_writebits(sc, MII_COMMAND_START, 2);
  	ex_mii_writebits(sc, MII_COMMAND_READ, 2);
  	ex_mii_writebits(sc, phy, 5);
  	ex_mii_writebits(sc, reg, 5);
  
! 	ex_mii_clrbit(sc, ELINK_PHY_DIR);
! 	ex_mii_clrbit(sc, ELINK_PHY_CLK);
  	ex_mii_setbit(sc, ELINK_PHY_CLK);
! 	ex_mii_clrbit(sc, ELINK_PHY_CLK);
  
  	err = ex_mii_readbit(sc, ELINK_PHY_DATA);
- 	ex_mii_setbit(sc, ELINK_PHY_CLK);
  
  	for (i = 0; i < 16; i++) {
  		val <<= 1;
  		ex_mii_clrbit(sc, ELINK_PHY_CLK);
  		if (err == 0 && ex_mii_readbit(sc, ELINK_PHY_DATA))
  				val |= 1;
  		ex_mii_setbit(sc, ELINK_PHY_CLK);
  	}
  	ex_mii_clrbit(sc, ELINK_PHY_CLK);
  	ex_mii_setbit(sc, ELINK_PHY_CLK);
  
  	GO_WINDOW(1);
  
--- 1730,1775 ----
  
  	bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_W4_PHYSMGMT, 0);
  
! 	ex_mii_setbit(sc, ELINK_PHY_DIR);
! 	delay(1);
! 	ex_mii_setbit(sc, ELINK_PHY_DIR|ELINK_PHY_DATA);
! 	delay(1);
! 
          for (i = 0; i < 32; i++) {
                  ex_mii_setbit(sc, ELINK_PHY_CLK);
+ 		delay(1);
+                 ex_mii_clrbit(sc, ELINK_PHY_CLK);
+ 		delay(1);
          }
  	ex_mii_writebits(sc, MII_COMMAND_START, 2);
  	ex_mii_writebits(sc, MII_COMMAND_READ, 2);
  	ex_mii_writebits(sc, phy, 5);
  	ex_mii_writebits(sc, reg, 5);
  
! 	ex_mii_clrbit(sc, ELINK_PHY_DATA|ELINK_PHY_CLK);
! 	delay(1);
  	ex_mii_setbit(sc, ELINK_PHY_CLK);
! 	delay(1);
! 	ex_mii_clrbit(sc, ELINK_PHY_DIR|ELINK_PHY_CLK);
! 	delay(1);
! 	ex_mii_setbit(sc, ELINK_PHY_CLK);
! 	delay(1);
  
  	err = ex_mii_readbit(sc, ELINK_PHY_DATA);
  
  	for (i = 0; i < 16; i++) {
  		val <<= 1;
  		ex_mii_clrbit(sc, ELINK_PHY_CLK);
+ 		delay(1);
  		if (err == 0 && ex_mii_readbit(sc, ELINK_PHY_DATA))
  				val |= 1;
  		ex_mii_setbit(sc, ELINK_PHY_CLK);
+ 		delay(1);
  	}
  	ex_mii_clrbit(sc, ELINK_PHY_CLK);
+ 	delay(1);
  	ex_mii_setbit(sc, ELINK_PHY_CLK);
+ 	delay(1);
  
  	GO_WINDOW(1);
  
***************
*** 1756,1770 ****
  	int i;
  
  	ex_mii_setbit(sc, ELINK_PHY_DIR);
  	for (i = 1 << (nbits -1); i; i = i >>  1) {
- 		ex_mii_clrbit(sc, ELINK_PHY_CLK);
- 		ex_mii_readbit(sc, ELINK_PHY_CLK);
  		if (data & i)
  			ex_mii_setbit(sc, ELINK_PHY_DATA);
  		else
  			ex_mii_clrbit(sc, ELINK_PHY_DATA);
  		ex_mii_setbit(sc, ELINK_PHY_CLK);
- 		ex_mii_readbit(sc, ELINK_PHY_CLK);
  	}
  }
  
--- 1785,1801 ----
  	int i;
  
  	ex_mii_setbit(sc, ELINK_PHY_DIR);
+ 	ex_mii_clrbit(sc, ELINK_PHY_CLK);
+ 
  	for (i = 1 << (nbits -1); i; i = i >>  1) {
  		if (data & i)
  			ex_mii_setbit(sc, ELINK_PHY_DATA);
  		else
  			ex_mii_clrbit(sc, ELINK_PHY_DATA);
+ 		delay(1);
+ 		ex_mii_clrbit(sc, ELINK_PHY_CLK);
+ 		delay(1);
  		ex_mii_setbit(sc, ELINK_PHY_CLK);
  	}
  }
  
***************
*** 1780,1789 ****
  
  	GO_WINDOW(4);
  
! 	ex_mii_clrbit(sc, ELINK_PHY_DIR);
  	for (i = 0; i < 32; i++) {
! 		ex_mii_clrbit(sc, ELINK_PHY_CLK);
! 		ex_mii_setbit(sc, ELINK_PHY_CLK);
  	}
  	ex_mii_writebits(sc, MII_COMMAND_START, 2);
  	ex_mii_writebits(sc, MII_COMMAND_WRITE, 2);
--- 1811,1825 ----
  
  	GO_WINDOW(4);
  
! 	ex_mii_setbit(sc, ELINK_PHY_DIR);
! 	delay(1);
! 	ex_mii_setbit(sc, ELINK_PHY_DIR|ELINK_PHY_DATA);
! 	delay(1);
  	for (i = 0; i < 32; i++) {
!                 ex_mii_setbit(sc, ELINK_PHY_CLK);
! 		delay(1);
!                 ex_mii_clrbit(sc, ELINK_PHY_CLK);
! 		delay(1);
  	}
  	ex_mii_writebits(sc, MII_COMMAND_START, 2);
  	ex_mii_writebits(sc, MII_COMMAND_WRITE, 2);
***************
*** 1792,1799 ****
  	ex_mii_writebits(sc, MII_COMMAND_ACK, 2);
  	ex_mii_writebits(sc, data, 16);
  
- 	ex_mii_clrbit(sc, ELINK_PHY_CLK);
  	ex_mii_setbit(sc, ELINK_PHY_CLK);
  
  	GO_WINDOW(1);
  }
--- 1828,1838 ----
  	ex_mii_writebits(sc, MII_COMMAND_ACK, 2);
  	ex_mii_writebits(sc, data, 16);
  
  	ex_mii_setbit(sc, ELINK_PHY_CLK);
+ 	delay(1);
+ 	ex_mii_clrbit(sc, ELINK_PHY_CLK);
+ 	delay(1);
+ 	ex_mii_clrbit(sc, ELINK_PHY_DIR);
  
  	GO_WINDOW(1);
  }

--==_Exmh_10736900560--