[PATCH] 2.6.9-rc2 tulip phy reset

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

 



Andrew,
You had mentioned at OLS I should send you this patch even though
jgarzik (maintainer) has rejected them. Jeff rejected them because
the patches can delay up to 1.5ms (originally 2.5ms) while interrupts
are blocked.  Maybe now one could use msleep() or something like that?

I "maintain" this patch in the parisc-linux CVS tree because it
Works For Me (tm). AFAIK, no one has submitted better fixes to date.

This patch is also available from:
	ftp://ftp.parisc-linux.org/patches/diff-tulip_phy_reset-03

thanks,
grant


Index: drivers/net/tulip/media.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/net/tulip/media.c,v
retrieving revision 1.10.10.1
diff -u -p -r1.10.10.1 media.c
--- drivers/net/tulip/media.c	24 Nov 2003 03:06:39 -0000	1.10.10.1
+++ drivers/net/tulip/media.c	24 Nov 2003 05:33:35 -0000
@@ -43,8 +43,10 @@ static const unsigned char comet_miireg2
 
 /* MII transceiver control section.
    Read and write the MII registers using software-generated serial
-   MDIO protocol.  See the MII specifications or DP83840A data sheet
-   for details. */
+   MDIO protocol.
+   See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
+   or DP83840A data sheet for more details.
+   */
 
 int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
 {
@@ -271,13 +273,29 @@ 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 = 10;	/* max 1 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) */
+					/* and IEEE 802.3 "22.2.4.1.1 Reset" */
+					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;
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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