[parisc-linux-cvs] PATCH tulip PHY reset/init

Grant Grundler grundler@dsl2.external.hp.com
Mon, 14 Oct 2002 18:25:13 -0600


Grant Grundler wrote:
> Log message:
> 2.5.41-pa1 fix tulip PHY reset/init ( ~= 2.4.19-pa22)
> 
> DP83840A.pdf and lxt971d.pdf both require polling the reset bit
> (bit 15) in mdio control register to determine when a reset has
> completed. Then the "init" sequence can be sent.
> 
> Don't know if all other PHY's are compatible with this or not.
> HP only used the above two PHY's.

The 2.5 diff is appended.
It should also apply (with fuzz) to kernel.org 2.4.19 tree.

2.4.18-pa22 diff is equivalent but deleted crud I had previously added.

Patch tested on C3000, A500-4X, A500-5X, and A500-6X.

grant


Index: Makefile
===================================================================
RCS file: /var/cvs/linux-2.5/Makefile,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile
--- Makefile	8 Oct 2002 22:45:56 -0000	1.8
+++ Makefile	15 Oct 2002 00:04:07 -0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 41
-EXTRAVERSION = -pa0
+EXTRAVERSION = -pa1
 
 # *DOCUMENTATION*
 # Too see a list of typical targets execute "make help"
Index: drivers/net/tulip/media.c
===================================================================
RCS file: /var/cvs/linux-2.5/drivers/net/tulip/media.c,v
retrieving revision 1.2
diff -u -p -r1.2 media.c
--- drivers/net/tulip/media.c	18 Jul 2002 16:15:58 -0000	1.2
+++ drivers/net/tulip/media.c	15 Oct 2002 00:04:07 -0000
@@ -271,13 +271,27 @@ void tulip_select_media(struct net_devic
 				int reset_length = p[2 + init_length];
 				misc_info = (u16*)(reset_sequence + reset_length);
 				if (startup) {
+					int timeout = 20;	/* 2 ms */
 					outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
 					for (i = 0; i < reset_length; i++)
 						outl(reset_sequence[i], ioaddr + CSR12);
+
+					/* flush posted writes */
+					inl(ioaddr + CSR12);
+					/* Sect 3.10.3 in DP83840A.pdf (p39) */
+					udelay(500);
+
+					/* Section 4.2 in DP83840A.pdf (p43) */
+					while (timeout-- &&
+						(tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
+						udelay(100);
 				}
 				for (i = 0; i < init_length; i++)
 					outl(init_sequence[i], ioaddr + CSR12);
+
+				inl(ioaddr + CSR12);	/* flush posted writes */
 			}
+
 			tmp_info = get_u16(&misc_info[1]);
 			if (tmp_info)
 				tp->advertising[phy_num] = tmp_info | 1;