Re: PPC 440GX with NS DP83865 phy

3 messages, 2 authors, 2005-03-10 · open the first message on its own page

Re: PPC 440GX with NS DP83865 phy

From: Gerhard Jaeger <hidden>
Date: 2005-03-10 10:07:02

On Thursday 10 March 2005 09:34, Eugene Surovegin wrote:
On Thu, Mar 10, 2005 at 08:37:08AM +0100, Gerhard Jaeger wrote:

[snip]
quoted
I have sent a patch (which has been rejected) a few
weeks ago to the list which changes the setup procedure of the EMAC to work
with a DP83865 PHY. THe current implementation will not work.
Gerhard, I wasn't able to find that patch in the patch tracker 
(http://ozlabs.org/ppc32-patches/) and I missed it when you posted it.

Could you re-send it or post a link to the relevant message in 
archive.
Hi Eugene,

the patch has been posted in October last year (wow, thought it was in
december or so):
http://ozlabs.org/pipermail/linuxppc-embedded/2004-October/015811.html

I think it needs some cleanup to apply correctly, but the issue is still
the same -  the RGMII bridge needs to be setup again after the EMAC has 
been reset. This problem occurs, when the speed is != 100Mbs, then
the clocking for the phy is not correct. 
I have attached an updated patch, which first checks the PHY speed, then
according to that speed the RGMII and ZMII will be setup...

Gerhard

-- 
Gerhard Jaeger [off-list ref]            
SYSGO AG                      Embedded and Real-Time Software
www.sysgo.com | www.elinos.com | www.pikeos.com | www.osek.de 

[PATCH][PPC32]IBM-EMAC GMII
This patch fixes problems with a Gigabit PHY being connected via GMII
interface. It seems, that the RGMII bridge needs to be setup again after
the EMAC has been reset. It causes also some troubles to enable RX & TX
without having a link. Tested on PPC440GP, GX and PPC405 boards.

Signed-off-by: Gerhard Jaeger <redacted>
--- linux-2.6.11/drivers/net/ibm_emac/ibm_emac_core.c.orig	2004-10-18 23:53:06.000000000 +0200
+++ linux-2.6.11/drivers/net/ibm_emac/ibm_emac_core.c		2004-10-22 08:43:12.000000000 +0200
@@ -1018,28 +1018,45 @@ static int emac_start_xmit(struct sk_buf
 	return 0;
 }
 
+static int emac_setup_mii_bridges(struct ocp_enet_private *fep )
+{
+	/* set speed (default is 10Mb) */
+	switch (fep->phy_mii.speed) {
+	case SPEED_1000:
+		if (fep->rgmii_dev)
+			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
+					      1000);
+		break;
+	case SPEED_100:
+		if (fep->rgmii_dev)
+			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
+					      100);
+		if (fep->zmii_dev)
+			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
+					     100);
+		break;
+	case SPEED_10:
+	default:
+		if (fep->rgmii_dev)
+			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
+					      10);
+		if (fep->zmii_dev)
+			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
+					     10);
+	}
+	return 0;
+}
+
 static int emac_adjust_to_link(struct ocp_enet_private *fep)
 {
 	emac_t *emacp = fep->emacp;
 	unsigned long mode_reg;
-	int full_duplex, speed;
-
-	full_duplex = 0;
-	speed = SPEED_10;
 
 	/* set mode register 1 defaults */
 	mode_reg = EMAC_M1_DEFAULT;
 
-	/* Read link mode on PHY */
-	if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) {
-		/* If an error occurred, we don't deal with it yet */
-		full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL);
-		speed = fep->phy_mii.speed;
-	}
-
-
 	/* set speed (default is 10Mb) */
-	switch (speed) {
+	switch (fep->phy_mii.speed) {
 	case SPEED_1000:
 		mode_reg |= EMAC_M1_JUMBO_ENABLE | EMAC_M1_RFS_16K;
 		if (fep->rgmii_dev) {
@@ -1050,41 +1067,28 @@ static int emac_adjust_to_link(struct oc
 				mode_reg |= EMAC_M1_MF_1000GPCS;
 			else
 				mode_reg |= EMAC_M1_MF_1000MBPS;
-
-			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
-					      1000);
 		}
 		break;
 	case SPEED_100:
 		mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K;
-		if (fep->rgmii_dev)
-			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
-					      100);
-		if (fep->zmii_dev)
-			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
-					     100);
 		break;
 	case SPEED_10:
 	default:
 		mode_reg = (mode_reg & ~EMAC_M1_MF_100MBPS) | EMAC_M1_RFS_4K;
-		if (fep->rgmii_dev)
-			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
-					      10);
-		if (fep->zmii_dev)
-			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
-					     10);
 	}
 
-	if (full_duplex)
+	if (fep->phy_mii.duplex)
 		mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST;
 	else
 		mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE);
 
-	LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n",
-		    fep->ndev->name, speed, full_duplex, fep->opened));
-
+ 	LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n",
+		    fep->ndev->name, fep->phy_mii.speed,
+		    fep->phy_mii.full_duplex, fep->opened));
+ 
 	printk(KERN_INFO "%s: Speed: %d, %s duplex.\n",
-	       fep->ndev->name, speed, full_duplex ? "Full" : "Half");
+	       fep->ndev->name, fep->phy_mii.speed,
+	       (fep->phy_mii.duplex == DUPLEX_FULL) ? "Full" : "Half");
 	if (fep->opened)
 		out_be32(&emacp->em0mr1, mode_reg);
 
@@ -1312,15 +1316,23 @@ static void emac_reset_configure(struct 
 	 * soft reset without a PHY clock present.
 	 */
 	if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
+
+		/* Read link mode on PHY */
+		fep->phy_mii.def->ops->read_link(&fep->phy_mii);
+
 		/* Reset the EMAC */
 		out_be32(&emacp->em0mr0, EMAC_M0_SRST);
-		udelay(20);
+
+		/* it seems, that this is necessary for some configs
+		 * to come out of the reset
+		 */
+		emac_setup_mii_bridges( fep );
+
 		for (i = 0; i < 100; i++) {
 			if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0)
 				break;
 			udelay(10);
 		}
-
 		if (i >= 100) {
 			printk(KERN_ERR "%s: Cannot reset EMAC\n",
 			       fep->ndev->name);
@@ -1630,7 +1642,10 @@ static int emac_open(struct net_device *
 	}
 	/* Kick the chip rx & tx channels into life */
 	spin_lock_irq(&fep->lock);
-	emac_kick(fep);
+
+	/* no link, no need to kick the interface */
+	if (netif_carrier_ok(fep->ndev))
+		emac_kick(fep);
 	spin_unlock_irq(&fep->lock);
 
 	netif_start_queue(dev);

Re: PPC 440GX with NS DP83865 phy

From: Eugene Surovegin <hidden>
Date: 2005-03-10 16:03:59

On Thu, Mar 10, 2005 at 11:06:53AM +0100, Gerhard Jaeger wrote:
the patch has been posted in October last year (wow, thought it was in
december or so):
http://ozlabs.org/pipermail/linuxppc-embedded/2004-October/015811.html

I think it needs some cleanup to apply correctly, but the issue is still
the same -  the RGMII bridge needs to be setup again after the EMAC has 
been reset. This problem occurs, when the speed is != 100Mbs, then
the clocking for the phy is not correct. 
I have attached an updated patch, which first checks the PHY speed, then
according to that speed the RGMII and ZMII will be setup...
[snip]

OK, from quick look it seems that this is infamous problem with PHYs 
which don't generate Rx clock if there is no link.

Current driver works sometimes probably just by luck.

Gerhard, there is an experimental NAPI driver for 4xx at 
http://kernel.ebshome.net (for current 2.4 & 2.6 BK trees). I recently 
added full 440GX support. We (Matt and I) are thinking about 
scraping the current driver and using my new version sometimes in the 
future. It'd be great if you could find some time and try this new 
driver on your board. Enable "PHY Rx clock workaround" in driver 
config.

Feel free to contact me directly if you have any problems with this 
driver (e.g. applying patch to an older kernel version, etc).

--
Eugene

Re: PPC 440GX with NS DP83865 phy

From: Gerhard Jaeger <hidden>
Date: 2005-03-10 16:22:39

On Thursday 10 March 2005 17:03, Eugene Surovegin wrote:
On Thu, Mar 10, 2005 at 11:06:53AM +0100, Gerhard Jaeger wrote:
quoted
the patch has been posted in October last year (wow, thought it was in
december or so):
http://ozlabs.org/pipermail/linuxppc-embedded/2004-October/015811.html

I think it needs some cleanup to apply correctly, but the issue is still
the same -  the RGMII bridge needs to be setup again after the EMAC has 
been reset. This problem occurs, when the speed is != 100Mbs, then
the clocking for the phy is not correct. 
I have attached an updated patch, which first checks the PHY speed, then
according to that speed the RGMII and ZMII will be setup...
[snip]

OK, from quick look it seems that this is infamous problem with PHYs 
which don't generate Rx clock if there is no link.

Current driver works sometimes probably just by luck.

Gerhard, there is an experimental NAPI driver for 4xx at 
http://kernel.ebshome.net (for current 2.4 & 2.6 BK trees). I recently 
added full 440GX support. We (Matt and I) are thinking about 
scraping the current driver and using my new version sometimes in the 
future. It'd be great if you could find some time and try this new 
driver on your board. Enable "PHY Rx clock workaround" in driver 
config.

Feel free to contact me directly if you have any problems with this 
driver (e.g. applying patch to an older kernel version, etc).
Eugene, I will give it a try ASAP. As we are using a heavily patched 2.4 
kernel on the customers board, where came up, it might took some time 
for making it work - but I'll keep you informed.

Thanx
Gerhard

-- 
Gerhard Jaeger [off-list ref]            
SYSGO AG                      Embedded and Real-Time Software
www.sysgo.com | www.elinos.com | www.pikeos.com | www.osek.de 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help