linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* spidernet: dynamic phy setup code
@ 2007-01-26 13:09 Jens Osterkamp
  2007-01-26 17:58 ` Linas Vepstas
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Jens Osterkamp @ 2007-01-26 13:09 UTC (permalink / raw)
  To: Ishizaki Kou; +Cc: cbe-oss-dev, linuxppc-dev, netdev, jgarzik, James K Lewis

This patch modifies the patch submitted by Kou Ishizaki to make it work on the
blade (http://marc.theaimsgroup.com/?l=linux-netdev&m=116593424505539&w=2).
Unfortunately I dont have access to a Celleb so I cannot test it there.

The basic logic behind this is simple : when the interface first comes up
it tries to detect the phy. When the phy is detected, it is initially set up
to use copper. A timer is set to check the link status in spidernet_link_phy
using poll_link. If link check fails more than SPIDER_NET_ANEG_TIMEOUT
times, it switches to fiber link with autonegotiation. If that fails more
than SPIDER_NET_ANEG_TIMEOUT times, it switches to fiber link with no
autonegotiation. If that also fails, it goes back to copper, and so forth.
If the link comes up, it prints the link abilites and we are done.

The name of the phy found attached to the spider chip is reported to the
user. Hardcoded values for the timeout are moved to #defines. I put in a
few comments to make the code more readable.

Signed-off-by: Jens Osterkamp <jens@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

Index: linux-2.6/drivers/net/spider_net.c
===================================================================
--- linux-2.6.orig/drivers/net/spider_net.c
+++ linux-2.6/drivers/net/spider_net.c
@@ -1280,19 +1280,23 @@ spider_net_set_mac(struct net_device *ne
  * spider_net_link_reset
  * @netdev: net device structure
  *
+ * This is called when the PHY_LINK signal is asserted. For the blade this is
+ * not connected so we should never get here.
+ *
  */
 static void
 spider_net_link_reset(struct net_device *netdev)
 {
-
  struct spider_net_card *card=netdev_priv(netdev);
 
  del_timer_sync(&card->aneg_timer);
 
+ /* clear interrupt, block further interrupts */
  spider_net_write_reg(card, SPIDER_NET_GMACST,
         spider_net_read_reg(card, SPIDER_NET_GMACST));
  spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
 
+ /* reset phy and setup aneg */
  mii_phy_probe(&card->phy, card->phy.mii_id);
  spider_net_setup_aneg(card, is1000);
  if (card->phy.def->phy_id)
@@ -1616,6 +1620,7 @@ spider_net_init_card(struct spider_net_c
  spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
         SPIDER_NET_CKRCTRL_RUN_VALUE);
 
+ /* trigger ETOMOD signal */
  spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
                       spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
 
@@ -1739,6 +1744,8 @@ spider_net_open(struct net_device *netde
  if (spider_net_init_firmware(card))
   goto init_firmware_failed;
 
+ /* start probing with copper */
+ card->phy.medium = GMII_COPPER;
  spider_net_setup_aneg(card, is1000);
  if (card->phy.def->phy_id)
   mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
@@ -1805,43 +1812,54 @@ static void spider_net_link_phy(unsigned
  struct spider_net_card *card = (struct spider_net_card *)data;
  struct mii_phy *phy = &card->phy;
 
- if (card->aneg_count > 10) {
-  /* timeout */
-  card->aneg_count = 0;
-  is1000 = !is1000;
-  goto re_setup;
+ /* if link didn't come up after SPIDER_NET_ANEG_TIMEOUT tries, setup phy 
again */
+ if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) {
+
+  pr_info("%s: link is down, trying to bring it up\n", card->netdev->name);
+
+  switch(phy->medium) {
+  case GMII_COPPER:
+   /* enable fiber with autonegotiation first */
+   if (phy->def->ops->enable_fiber)
+    phy->def->ops->enable_fiber(phy, 1);
+   phy->medium = GMII_FIBER;
+   break;
+
+  case GMII_FIBER:
+   /* fiber didn't come up, try to disable fiber autoneg */
+   if (phy->def->ops->enable_fiber)
+    phy->def->ops->enable_fiber(phy, 0);
+   phy->medium = GMII_UNKNOWN;
+   break;
+
+  case GMII_UNKNOWN:
+   /* copper, fiber with and without autoneg failed,
+    * retry from beginning */
+   spider_net_setup_aneg(card, is1000);
+   phy->medium = GMII_COPPER;
+   break;
+  }
+
+ card->aneg_count = 0;
+ mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+ return;
  }
 
+ /* link still not up, try again later */
  if (!(phy->def->ops->poll_link(phy))) {
   card->aneg_count++;
   mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
   return;
  }
 
+ /* link came up, get abilities */
  phy->def->ops->read_link(phy);
 
- if (phy->speed == 1000 && !is1000) {
-  is1000 = 1;
-  goto re_setup;
- } else if(phy->speed != 1000 && is1000) {
-  is1000 = 0;
-  goto re_setup;
- }
-
- spider_net_write_reg(card, SPIDER_NET_GMACST,
-        spider_net_read_reg(card, SPIDER_NET_GMACST));
- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
-
- pr_info("Found %s with %i Mbps, %s-duplex.\n",
-  phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half");
+ pr_info("%s: link is up with %i Mbps, %s-duplex, %sautoneg.\n",
+  card->netdev->name, phy->speed, phy->duplex==1 ? "Full" : "Half",
+  phy->autoneg==1 ? "" : "no ");
 
  return;
-
-re_setup:
- mii_phy_probe(phy, phy->mii_id);
- spider_net_setup_aneg(card, is1000);
- card->aneg_count = 0;
- mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
 }
 
 /**
@@ -1871,8 +1889,10 @@ spider_net_setup_phy(struct spider_net_c
   unsigned short id;
   id = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
   if (id != 0x0000 && id != 0xffff) {
-   mii_phy_probe(phy, phy->mii_id);
+   if (!mii_phy_probe(phy, phy->mii_id)) {
+    pr_info("Found %s.\n", phy->def->name);
    break;
+   }
   }
  }
 
Index: linux-2.6/drivers/net/spider_net.h
===================================================================
--- linux-2.6.orig/drivers/net/spider_net.h
+++ linux-2.6/drivers/net/spider_net.h
@@ -51,7 +51,8 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_TX_DESCRIPTORS_MAX  512
 
 #define SPIDER_NET_TX_TIMER   (HZ/5)
-#define SPIDER_NET_ANEG_TIMER   (HZ*2)
+#define SPIDER_NET_ANEG_TIMER   (HZ)
+#define SPIDER_NET_ANEG_TIMEOUT   2
 
 #define SPIDER_NET_RX_CSUM_DEFAULT  1
 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-01-26 13:09 spidernet: dynamic phy setup code Jens Osterkamp
@ 2007-01-26 17:58 ` Linas Vepstas
       [not found]   ` <200701262150.52882.jens@de.ibm.com>
  2007-01-26 20:21 ` Benjamin Herrenschmidt
  2007-02-01  8:05 ` [Cbe-oss-dev] " Ishizaki Kou
  2 siblings, 1 reply; 16+ messages in thread
From: Linas Vepstas @ 2007-01-26 17:58 UTC (permalink / raw)
  To: Jens Osterkamp; +Cc: netdev, cbe-oss-dev, linuxppc-dev, jgarzik, James K Lewis

On Fri, Jan 26, 2007 at 02:09:29PM +0100, Jens Osterkamp wrote:
> This patch modifies the patch submitted by Kou Ishizaki to make it work on the
> blade (http://marc.theaimsgroup.com/?l=linux-netdev&m=116593424505539&w=2).
> 
> Index: linux-2.6/drivers/net/spider_net.c
> + if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) {
> +
> +  pr_info("%s: link is down, trying to bring it up\n", card->netdev->name);
> +
> +  switch(phy->medium) {
> +  case GMII_COPPER:
> +   /* enable fiber with autonegotiation first */
> +   if (phy->def->ops->enable_fiber)
> +    phy->def->ops->enable_fiber(phy, 1);
> +   phy->medium = GMII_FIBER;
> +   break;

Can you fix this to use tabs for indentation, instead of spaces?

Please note, if you do not like tabs of 8 spaces, you can always
change this in your editor, e.g "set ts=3" for making a tab 
be 3 spaces in vi. You would put this in your .exrc or .vimrc file.

Patches submitted to the kernel should use tabs, uniformly.

--linas

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-01-26 13:09 spidernet: dynamic phy setup code Jens Osterkamp
  2007-01-26 17:58 ` Linas Vepstas
@ 2007-01-26 20:21 ` Benjamin Herrenschmidt
  2007-02-01 10:50   ` Jens Osterkamp
  2007-02-01  8:05 ` [Cbe-oss-dev] " Ishizaki Kou
  2 siblings, 1 reply; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2007-01-26 20:21 UTC (permalink / raw)
  To: Jens Osterkamp; +Cc: netdev, James K Lewis, linuxppc-dev, jgarzik, cbe-oss-dev

On Fri, 2007-01-26 at 14:09 +0100, Jens Osterkamp wrote:
> This patch modifies the patch submitted by Kou Ishizaki to make it work on the
> blade (http://marc.theaimsgroup.com/?l=linux-netdev&m=116593424505539&w=2).
> Unfortunately I dont have access to a Celleb so I cannot test it there.
> 
> The basic logic behind this is simple : when the interface first comes up
> it tries to detect the phy. When the phy is detected, it is initially set up
> to use copper. A timer is set to check the link status in spidernet_link_phy
> using poll_link. If link check fails more than SPIDER_NET_ANEG_TIMEOUT
> times, it switches to fiber link with autonegotiation. If that fails more
> than SPIDER_NET_ANEG_TIMEOUT times, it switches to fiber link with no
> autonegotiation. If that also fails, it goes back to copper, and so forth.
> If the link comes up, it prints the link abilites and we are done.
> 
> The name of the phy found attached to the spider chip is reported to the
> user. Hardcoded values for the timeout are moved to #defines. I put in a
> few comments to make the code more readable.

Can't we have a device-tree property indicating wether to use fiber or
copper ?

Ben.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
       [not found]   ` <200701262150.52882.jens@de.ibm.com>
@ 2007-01-26 22:15     ` Linas Vepstas
  2007-01-26 22:30       ` Jens Osterkamp
  0 siblings, 1 reply; 16+ messages in thread
From: Linas Vepstas @ 2007-01-26 22:15 UTC (permalink / raw)
  To: Jens Osterkamp; +Cc: linuxppc-dev

On Fri, Jan 26, 2007 at 09:50:52PM +0100, Jens Osterkamp wrote:
> Seems like my kmail has eaten the tabs...i am attaching it as a file,

Ahhh

> does it look ok for you now ?

Yes.

FWIW, 

Acked-by: Linas Vepstas <linas@austin.ibm.com>

--linas

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-01-26 22:15     ` Linas Vepstas
@ 2007-01-26 22:30       ` Jens Osterkamp
  0 siblings, 0 replies; 16+ messages in thread
From: Jens Osterkamp @ 2007-01-26 22:30 UTC (permalink / raw)
  To: Linas Vepstas; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 362 bytes --]

On Friday 26 January 2007 23:15, Linas Vepstas wrote:
> On Fri, Jan 26, 2007 at 09:50:52PM +0100, Jens Osterkamp wrote:
> > Seems like my kmail has eaten the tabs...i am attaching it as a file,
>
> Ahhh
>
> > does it look ok for you now ?
>
> Yes.
>
> FWIW,
>
> Acked-by: Linas Vepstas <linas@austin.ibm.com>
>
> --linas

Sending it again as attached file

Jens

[-- Attachment #2: spidernet-on-celleb-update-2.diff --]
[-- Type: text/x-diff, Size: 5903 bytes --]

Subject: spidernet: dynamic phy setup code

This patch modifies the patch submitted by Kou Ishizaki to make it work on the
blade (http://marc.theaimsgroup.com/?l=linux-netdev&m=116593424505539&w=2).
Unfortunately I dont have access to a Celleb so I cannot test it there.

The basic logic behind this is simple : when the interface first comes up
it tries to detect the phy. When the phy is detected, it is initially set up
to use copper. A timer is set to check the link status in spidernet_link_phy
using poll_link. If link check fails more than SPIDER_NET_ANEG_TIMEOUT
times, it switches to fiber link with autonegotiation. If that fails more
than SPIDER_NET_ANEG_TIMEOUT times, it switches to fiber link with no
autonegotiation. If that also fails, it goes back to copper, and so forth.
If the link comes up, it prints the link abilites and we are done.

The name of the phy found attached to the spider chip is reported to the
user. Hardcoded values for the timeout are moved to #defines. I put in a
few comments to make the code more readable.

Signed-off-by: Jens Osterkamp <jens@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

Index: linux-2.6/drivers/net/spider_net.c
===================================================================
--- linux-2.6.orig/drivers/net/spider_net.c
+++ linux-2.6/drivers/net/spider_net.c
@@ -1280,19 +1280,23 @@ spider_net_set_mac(struct net_device *ne
  * spider_net_link_reset
  * @netdev: net device structure
  *
+ * This is called when the PHY_LINK signal is asserted. For the blade this is
+ * not connected so we should never get here.
+ *
  */
 static void
 spider_net_link_reset(struct net_device *netdev)
 {
-
 	struct spider_net_card *card=netdev_priv(netdev);
 
 	del_timer_sync(&card->aneg_timer);
 
+	/* clear interrupt, block further interrupts */
 	spider_net_write_reg(card, SPIDER_NET_GMACST,
 			     spider_net_read_reg(card, SPIDER_NET_GMACST));
 	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
 
+	/* reset phy and setup aneg */
 	mii_phy_probe(&card->phy, card->phy.mii_id);
 	spider_net_setup_aneg(card, is1000);
 	if (card->phy.def->phy_id)
@@ -1616,6 +1620,7 @@ spider_net_init_card(struct spider_net_c
 	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
 			     SPIDER_NET_CKRCTRL_RUN_VALUE);
 
+	/* trigger ETOMOD signal */
 	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
 	                     spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
 
@@ -1739,6 +1744,8 @@ spider_net_open(struct net_device *netde
 	if (spider_net_init_firmware(card))
 		goto init_firmware_failed;
 
+	/* start probing with copper */
+	card->phy.medium = GMII_COPPER;
 	spider_net_setup_aneg(card, is1000);
 	if (card->phy.def->phy_id)
 		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
@@ -1805,43 +1812,54 @@ static void spider_net_link_phy(unsigned
 	struct spider_net_card *card = (struct spider_net_card *)data;
 	struct mii_phy *phy = &card->phy;
 
-	if (card->aneg_count > 10) {
-		/* timeout */
-		card->aneg_count = 0;
-		is1000 = !is1000;
-		goto re_setup;
+	/* if link didn't come up after SPIDER_NET_ANEG_TIMEOUT tries, setup phy again */
+	if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) {
+
+		pr_info("%s: link is down, trying to bring it up\n", card->netdev->name);
+
+		switch(phy->medium) {
+		case GMII_COPPER:
+			/* enable fiber with autonegotiation first */
+			if (phy->def->ops->enable_fiber)
+				phy->def->ops->enable_fiber(phy, 1);
+			phy->medium = GMII_FIBER;
+			break;
+
+		case GMII_FIBER:
+			/* fiber didn't come up, try to disable fiber autoneg */
+			if (phy->def->ops->enable_fiber)
+				phy->def->ops->enable_fiber(phy, 0);
+			phy->medium = GMII_UNKNOWN;
+			break;
+
+		case GMII_UNKNOWN:
+			/* copper, fiber with and without autoneg failed,
+			 * retry from beginning */
+			spider_net_setup_aneg(card, is1000);
+			phy->medium = GMII_COPPER;
+			break;
+		}
+
+	card->aneg_count = 0;
+	mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+	return;
 	}
 
+	/* link still not up, try again later */
 	if (!(phy->def->ops->poll_link(phy))) {
 		card->aneg_count++;
 		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
 		return;
 	}
 
+	/* link came up, get abilities */
 	phy->def->ops->read_link(phy);
 
-	if (phy->speed == 1000 && !is1000) {
-		is1000 = 1;
-		goto re_setup;
-	} else if(phy->speed != 1000 && is1000) {
-		is1000 = 0;
-		goto re_setup;
-	}
-
-	spider_net_write_reg(card, SPIDER_NET_GMACST,
-			     spider_net_read_reg(card, SPIDER_NET_GMACST));
-	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
-
-	pr_info("Found %s with %i Mbps, %s-duplex.\n",
-		phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half");
+	pr_info("%s: link is up with %i Mbps, %s-duplex, %sautoneg.\n",
+		card->netdev->name, phy->speed, phy->duplex==1 ? "Full" : "Half",
+		phy->autoneg==1 ? "" : "no ");
 
 	return;
-
-re_setup:
-	mii_phy_probe(phy, phy->mii_id);
-	spider_net_setup_aneg(card, is1000);
-	card->aneg_count = 0;
-	mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
 }
 
 /**
@@ -1871,8 +1889,10 @@ spider_net_setup_phy(struct spider_net_c
 		unsigned short id;
 		id = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
 		if (id != 0x0000 && id != 0xffff) {
-			mii_phy_probe(phy, phy->mii_id);
+			if (!mii_phy_probe(phy, phy->mii_id)) {
+				pr_info("Found %s.\n", phy->def->name);
 			break;
+			}
 		}
 	}
 
Index: linux-2.6/drivers/net/spider_net.h
===================================================================
--- linux-2.6.orig/drivers/net/spider_net.h
+++ linux-2.6/drivers/net/spider_net.h
@@ -51,7 +51,8 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_TX_DESCRIPTORS_MAX		512
 
 #define SPIDER_NET_TX_TIMER			(HZ/5)
-#define SPIDER_NET_ANEG_TIMER			(HZ*2)
+#define SPIDER_NET_ANEG_TIMER			(HZ)
+#define SPIDER_NET_ANEG_TIMEOUT			2
 
 #define SPIDER_NET_RX_CSUM_DEFAULT		1
 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Cbe-oss-dev] spidernet: dynamic phy setup code
  2007-01-26 13:09 spidernet: dynamic phy setup code Jens Osterkamp
  2007-01-26 17:58 ` Linas Vepstas
  2007-01-26 20:21 ` Benjamin Herrenschmidt
@ 2007-02-01  8:05 ` Ishizaki Kou
  2007-02-01 11:04   ` Jens Osterkamp
  2 siblings, 1 reply; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-01  8:05 UTC (permalink / raw)
  To: jens; +Cc: jim, linuxppc-dev, jgarzik, netdev

I apologize if you received this mail many times.


Jens-san

> This patch modifies the patch submitted by Kou Ishizaki to make it
work on the
> blade
(http://marc.theaimsgroup.com/?l=linux-netdev&m=116593424505539&w=2).
> Unfortunately I dont have access to a Celleb so I cannot test it
there.

Thanks for arranging our patch to work on Cell Blade.

This patch partially works on celleb but remains 
following several problems.
1. It doesn't recover once an ethernet cable which is
   connected to a spider_net card is unpluged. 
2. It doesn't work when the spider_net card is connected to 
   a 100Mbps ethernet switch.

To solve these problems, we need to restore some codes
you removed from your patch.

(1)
>- if (card->aneg_count > 10) {
>-  /* timeout */
>-  card->aneg_count = 0;
>-  is1000 = !is1000;
>-  goto re_setup;

>- if (phy->speed == 1000 && !is1000) {
>-  is1000 = 1;
>-  goto re_setup;
>- } else if(phy->speed != 1000 && is1000) {
>-  is1000 = 0;
>-  goto re_setup;
>- }

We need to use different auto-neg initial settings between
for 10/100Mbps ethernet switches and for Gbps ethernet switches.
Driver don't know which type of network switch is connected to
network card, so we try both settings alternately in auto negtiation
sequences by using a variable "is1000".
Furthermore, we have a problem that poll_link() may succeed even when
the auto-neg initial setting is for different network switch type,
and the network card does not work on this case. We retry auto-neg
with the another initial setting on this case.

#We are commented that "is1000" should be in spider_net_card.
#We fixed it in another patch. Please refer the following.
#http://ozlabs.org/pipermail/linuxppc-dev/2007-January/030203.html

But we don't think this is the best solution, and we are still
developing 
our spidernet driver. If you have a good alternative idea, please tell
us.

(2)
>- spider_net_write_reg(card, SPIDER_NET_GMACST,
>-        spider_net_read_reg(card, SPIDER_NET_GMACST));
>- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);

These codes are enabling LINK status interrupt which is disabled
at the beginning of auto-neg.
Without this operation, auto negotiation works only when a connection
detected for the first time, and auto negotiation will not work 
when an ethernet cable is unpluged or pluged.

(3)
>- mii_phy_probe(phy, phy->mii_id);
It seems that PHY reset is necessary before auto negotiation,
after a link once went down.
We can't call directly reset routine from driver, so we call
mii_phy_probe().
We are still developping the patch as we noted, and we are considering
to call mii_phy_probe() from spider_net_setup_aneg(), or to call
reset_one_mii_phy() from bcm54xx_setup_aneg().

We think these (1)-(3) are necessary, but we are afraid that you removed
them
by a reason that they causes some trouble in Cell Blade. If so please
tell us.


Best regards,
Kou Ishizaki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-01-26 20:21 ` Benjamin Herrenschmidt
@ 2007-02-01 10:50   ` Jens Osterkamp
  0 siblings, 0 replies; 16+ messages in thread
From: Jens Osterkamp @ 2007-02-01 10:50 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: netdev, James K Lewis, linuxppc-dev, jgarzik, cbe-oss-dev

On Friday 26 January 2007 9:21 pm, Benjamin Herrenschmidt wrote:

> Can't we have a device-tree property indicating wether to use fiber or
> copper ?

Well, yes, I am sure we could, but what would be the benefit of doing so
if we can get the same information dynamically ?

Jens

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Cbe-oss-dev] spidernet: dynamic phy setup code
  2007-02-01  8:05 ` [Cbe-oss-dev] " Ishizaki Kou
@ 2007-02-01 11:04   ` Jens Osterkamp
  2007-02-02 10:20     ` Ishizaki Kou
                       ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Jens Osterkamp @ 2007-02-01 11:04 UTC (permalink / raw)
  To: Ishizaki Kou; +Cc: jim, linuxppc-dev, jgarzik, netdev


Ishizaki-san,

> This patch partially works on celleb but remains 
> following several problems.
> 1. It doesn't recover once an ethernet cable which is
>    connected to a spider_net card is unpluged. 

My understanding is that you are using the LINK interrupt to detect this.
For the blade this is not connected but reenabling it wont hurt, I hope.

> 2. It doesn't work when the spider_net card is connected to 
>    a 100Mbps ethernet switch.
> 
> To solve these problems, we need to restore some codes
> you removed from your patch.
> 
> (1)
> >- if (card->aneg_count > 10) {
> >-  /* timeout */
> >-  card->aneg_count = 0;
> >-  is1000 = !is1000;
> >-  goto re_setup;
> 
> >- if (phy->speed == 1000 && !is1000) {
> >-  is1000 = 1;
> >-  goto re_setup;
> >- } else if(phy->speed != 1000 && is1000) {
> >-  is1000 = 0;
> >-  goto re_setup;
> >- }
> 
> We need to use different auto-neg initial settings between
> for 10/100Mbps ethernet switches and for Gbps ethernet switches.
> Driver don't know which type of network switch is connected to
> network card, so we try both settings alternately in auto negtiation
> sequences by using a variable "is1000".

I still dont see why you need different settings for different speed switches.
This is getting to a point where access to some hardware would be handy.
What exact phy are using anyway ?

> Furthermore, we have a problem that poll_link() may succeed even when
> the auto-neg initial setting is for different network switch type,
> and the network card does not work on this case. We retry auto-neg
> with the another initial setting on this case.

See above, could you give some more details why this is the case. Or maybe Ben
knows more about this ?

> #We are commented that "is1000" should be in spider_net_card.
> #We fixed it in another patch. Please refer the following.
> #http://ozlabs.org/pipermail/linuxppc-dev/2007-January/030203.html
> 
> But we don't think this is the best solution, and we are still
> developing 
> our spidernet driver. If you have a good alternative idea, please tell
> us.
> 
> (2)
> >- spider_net_write_reg(card, SPIDER_NET_GMACST,
> >-        spider_net_read_reg(card, SPIDER_NET_GMACST));
> >- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
> 
> These codes are enabling LINK status interrupt which is disabled
> at the beginning of auto-neg.
> Without this operation, auto negotiation works only when a connection
> detected for the first time, and auto negotiation will not work 
> when an ethernet cable is unpluged or pluged.

I will reenable it and see wether it affects us. The pin is not connected so
we should never enter this part of the code.

> (3)
> >- mii_phy_probe(phy, phy->mii_id);
> It seems that PHY reset is necessary before auto negotiation,
> after a link once went down.
> We can't call directly reset routine from driver, so we call
> mii_phy_probe().
> We are still developping the patch as we noted, and we are considering
> to call mii_phy_probe() from spider_net_setup_aneg(), or to call
> reset_one_mii_phy() from bcm54xx_setup_aneg().

IMHO using mii_phy_probe is the right way to do this.

> We think these (1)-(3) are necessary, but we are afraid that you removed
> them
> by a reason that they causes some trouble in Cell Blade. If so please
> tell us.

I'll do some investigations and let you know of the results.

Jens

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-02-01 11:04   ` Jens Osterkamp
@ 2007-02-02 10:20     ` Ishizaki Kou
  2007-02-05  0:08       ` Benjamin Herrenschmidt
  2007-02-02 10:29     ` [RFC/PATCH 2.6.20-rc6 1/4] spidernet: autoneg support for Celleb Ishizaki Kou
                       ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-02 10:20 UTC (permalink / raw)
  To: jens; +Cc: linuxppc-dev, jgarzik, jim, netdev

Jens-san,

Thanks for your comments.

>Ishizaki-san,
>
>> This patch partially works on celleb but remains 
>> following several problems.
>> 1. It doesn't recover once an ethernet cable which is
>>    connected to a spider_net card is unpluged. 
>
>My understanding is that you are using the LINK interrupt to detect this.

Yes. We use the LINK interrupt for this purpose.

>For the blade this is not connected but reenabling it wont hurt, I hope.
>
>> 2. It doesn't work when the spider_net card is connected to 
>>    a 100Mbps ethernet switch.
>> 
>> To solve these problems, we need to restore some codes
>> you removed from your patch.
>> 
>> (1)
>> >- if (card->aneg_count > 10) {
>> >-  /* timeout */
>> >-  card->aneg_count = 0;
>> >-  is1000 = !is1000;
>> >-  goto re_setup;
>> 
>> >- if (phy->speed == 1000 && !is1000) {
>> >-  is1000 = 1;
>> >-  goto re_setup;
>> >- } else if(phy->speed != 1000 && is1000) {
>> >-  is1000 = 0;
>> >-  goto re_setup;
>> >- }
>> 
>> We need to use different auto-neg initial settings between
>> for 10/100Mbps ethernet switches and for Gbps ethernet switches.
>> Driver don't know which type of network switch is connected to
>> network card, so we try both settings alternately in auto negtiation
>> sequences by using a variable "is1000".
>
>I still dont see why you need different settings for different speed switches.
>This is getting to a point where access to some hardware would be handy.
>What exact phy are using anyway ?

We use bcm5461. There is a possibility that we don't know the appropriate
setting which is applicable for both type of switches.

>> Furthermore, we have a problem that poll_link() may succeed even when
>> the auto-neg initial setting is for different network switch type,
>> and the network card does not work on this case. We retry auto-neg
>> with the another initial setting on this case.
>
>See above, could you give some more details why this is the case. Or maybe Ben
>knows more about this ?

We didn't investigate for the detail, but we met the following phenomena.
1. When auto-neg starts with Gbps setting and ethernet card is connected to
   a 100Mbps switch, LINK is not detected.
2. When auto-neg starts with 100/10Mbps setting and ethernet card is 
   connected to Gbps switch, LINK is detected (poll_link() succeeds), but
   the network is not available.

>> #We are commented that "is1000" should be in spider_net_card.
>> #We fixed it in another patch. Please refer the following.
>> #http://ozlabs.org/pipermail/linuxppc-dev/2007-January/030203.html
>> 
>> But we don't think this is the best solution, and we are still
>> developing 
>> our spidernet driver. If you have a good alternative idea, please
tell
>> us.
>> 
>> (2)
>> >- spider_net_write_reg(card, SPIDER_NET_GMACST,
>> >-        spider_net_read_reg(card, SPIDER_NET_GMACST));
>> >- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
>> 
>> These codes are enabling LINK status interrupt which is disabled
>> at the beginning of auto-neg.
>> Without this operation, auto negotiation works only when a connection
>> detected for the first time, and auto negotiation will not work 
>> when an ethernet cable is unpluged or pluged.
>
>I will reenable it and see wether it affects us. The pin is not
connected so
>we should never enter this part of the code.
>
>> (3)
>> >- mii_phy_probe(phy, phy->mii_id);
>> It seems that PHY reset is necessary before auto negotiation,
>> after a link once went down.
>> We can't call directly reset routine from driver, so we call
>> mii_phy_probe().
>> We are still developping the patch as we noted, and we are considering
>> to call mii_phy_probe() from spider_net_setup_aneg(), or to call
>> reset_one_mii_phy() from bcm54xx_setup_aneg().
>
>IMHO using mii_phy_probe is the right way to do this.

OK. We will do so.

>> We think these (1)-(3) are necessary, but we are afraid that you removed
>> them
>> by a reason that they causes some trouble in Cell Blade. If so please
>> tell us.
>
>I'll do some investigations and let you know of the results.

Thanks for your cooperation to us.

By the way, we have a suggestion. Would you please make your spidernet
patch based main-line code(not based on our patch)? 
Our patch are still changing, so we think it's more convenient
for you and us to maintain the code.
We will not mind whether it includes our code or not.

We will post our recent spidernet patch set based on 2.6.20-rc6.
This patch set is merged Jens-san's spidernet patch and works on celleb.
We hope this patch set will work on Cell blade.

We intend this patch set is just for a test so far(not intended to be
taken for main-line immediately). Please try this, if you can.

Best regards,
Kou Ishizaki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [RFC/PATCH 2.6.20-rc6 1/4] spidernet: autoneg support for Celleb
  2007-02-01 11:04   ` Jens Osterkamp
  2007-02-02 10:20     ` Ishizaki Kou
@ 2007-02-02 10:29     ` Ishizaki Kou
  2007-02-02 10:30     ` [RFC/PATCH 2.6.20-rc6 2/4] spidernet: load firmaware when open Ishizaki Kou
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-02 10:29 UTC (permalink / raw)
  To: jens; +Cc: linuxppc-dev, jgarzik, jim, netdev

Add auto negotiation support for Celleb. 

This patch is just for a test. Please try this, if you can.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

--- org-linux-powerpc-git/drivers/net/spider_net.h	2007-02-02 14:24:26.000000000 +0900
+++ linux-powerpc-git/drivers/net/spider_net.h	2007-02-02 14:24:45.000000000 +0900
@@ -50,6 +50,8 @@
 #define SPIDER_NET_TX_DESCRIPTORS_MAX		512
 
 #define SPIDER_NET_TX_TIMER			(HZ/5)
+#define SPIDER_NET_ANEG_TIMER			(HZ)
+#define SPIDER_NET_ANEG_TIMEOUT			2
 
 #define SPIDER_NET_RX_CSUM_DEFAULT		1
 
@@ -104,6 +106,7 @@
 
 #define SPIDER_NET_GMACOPEMD		0x00000100
 #define SPIDER_NET_GMACLENLMT		0x00000108
+#define SPIDER_NET_GMACST		0x00000110
 #define SPIDER_NET_GMACINTEN		0x00000118
 #define SPIDER_NET_GMACPHYCTRL		0x00000120
 
@@ -333,9 +336,12 @@
 /* We rely on flagged descriptor interrupts */
 #define SPIDER_NET_RXINT	( (1 << SPIDER_NET_GDAFDCINT) )
 
+#define SPIDER_NET_LINKINT	( 1 << SPIDER_NET_GMAC2INT )
+
 #define SPIDER_NET_ERRINT	( 0xffffffff & \
 				  (~SPIDER_NET_TXINT) & \
-				  (~SPIDER_NET_RXINT) )
+				  (~SPIDER_NET_RXINT) & \
+				  (~SPIDER_NET_LINKINT) )
 
 #define SPIDER_NET_GPREXEC			0x80000000
 #define SPIDER_NET_GPRDAT_MASK			0x0000ffff
@@ -447,6 +453,10 @@
 
 	spinlock_t intmask_lock;
 	struct tasklet_struct rxram_full_tl;
+
+	int aneg_count;
+	int is1000;
+	struct timer_list aneg_timer;
 	struct timer_list tx_timer;
 
 	struct work_struct tx_timeout_task;
--- org-linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:24:22.000000000 +0900
+++ linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:26:17.000000000 +0900
@@ -165,6 +165,57 @@
 	return readvalue;
 }
 
+/** spider_net_setup_aneg - initial auto-negotiation setup
+ * @card: device structure 
+ **/
+static void
+spider_net_setup_aneg(struct spider_net_card *card)
+{
+	struct mii_phy *phy = &card->phy;
+	u32 advertise = 0;
+	u16 bmcr, bmsr, ctrl1000, stat1000, estat;
+
+	bmcr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR);
+	bmsr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+	ctrl1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_CTRL1000);
+	stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000);
+	estat    = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
+
+	if (bmsr & BMSR_10HALF)
+		advertise |= ADVERTISE_10HALF;
+	if (bmsr & BMSR_10FULL)
+		advertise |= ADVERTISE_10FULL;
+	if (bmsr & BMSR_100HALF)
+		advertise |= ADVERTISE_100HALF;
+	if (bmsr & BMSR_100FULL)
+		advertise |= ADVERTISE_100FULL;
+	if (bmsr & BMSR_100BASE4)
+		advertise |= ADVERTISE_100BASE4;
+
+	mii_phy_probe(phy, phy->mii_id);
+
+	if (card->is1000) {
+		if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_TFULL)) {
+			advertise |= ADVERTISE_1000XFULL;
+			ctrl1000 |= ADVERTISE_1000FULL;
+		}
+		if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_THALF)) {
+			advertise |= ADVERTISE_1000XHALF;
+			ctrl1000 |= ADVERTISE_1000HALF;
+		}
+
+		spider_net_write_phy(card->netdev, phy->mii_id,
+				     MII_CTRL1000, ctrl1000);
+
+
+		phy->def->ops->setup_aneg(phy, advertise);
+	} else {
+		bmcr |= (BMCR_ANRESTART | BMCR_ANENABLE);
+		spider_net_write_phy(card->netdev, phy->mii_id,
+				     MII_BMCR, bmcr);
+	}
+}
+
 /**
  * spider_net_rx_irq_off - switch off rx irq on this spider card
  * @card: device structure
@@ -1245,6 +1296,33 @@
 }
 
 /**
+ * spider_net_link_reset
+ * @netdev: net device structure
+ *
+ * This is called when the PHY_LINK signal is asserted. For the blade this is
+ * not connected so we should never get here.
+ *
+ */
+static void
+spider_net_link_reset(struct net_device *netdev)
+{
+
+	struct spider_net_card *card = netdev_priv(netdev);
+
+	del_timer_sync(&card->aneg_timer);
+
+	/* clear interrupt, block further interrupts */
+	spider_net_write_reg(card, SPIDER_NET_GMACST,
+			     spider_net_read_reg(card, SPIDER_NET_GMACST));
+	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+
+	/* reset phy and setup aneg */
+	spider_net_setup_aneg(card);
+	mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+
+}
+
+/**
  * spider_net_handle_error_irq - handles errors raised by an interrupt
  * @card: card structure
  * @status_reg: interrupt status register 0 (GHIINT0STS)
@@ -1497,6 +1575,9 @@
 	if (status_reg & SPIDER_NET_TXINT)
 		netif_rx_schedule(netdev);
 
+	if (status_reg & SPIDER_NET_LINKINT)
+		spider_net_link_reset(netdev);
+
 	if (status_reg & SPIDER_NET_ERRINT )
 		spider_net_handle_error_irq(card, status_reg);
 
@@ -1621,8 +1702,6 @@
 
 	spider_net_write_reg(card, SPIDER_NET_GMACLENLMT,
 			     SPIDER_NET_LENLMT_VALUE);
-	spider_net_write_reg(card, SPIDER_NET_GMACMODE,
-			     SPIDER_NET_MACMODE_VALUE);
 	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
 			     SPIDER_NET_OPMODE_VALUE);
 
@@ -1655,6 +1734,12 @@
 	int i, result;
 
 	result = -ENOMEM;
+
+	/* start probing with copper */
+	spider_net_setup_aneg(card);
+	if (card->phy.def->phy_id)
+		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+
 	if (spider_net_init_chain(card, &card->tx_chain, card->descr,
 	                          card->num_tx_desc))
 		goto alloc_tx_failed;
@@ -1699,17 +1784,112 @@
 alloc_rx_failed:
 	spider_net_free_chain(card, &card->tx_chain);
 alloc_tx_failed:
+	del_timer_sync(&card->aneg_timer);
 	return result;
 }
 
 /**
+ * spider_net_link_phy
+ * @data: used for pointer to card structure
+ *
+ */
+static void spider_net_link_phy(unsigned long data)
+{
+	struct spider_net_card *card = (struct spider_net_card *)data;
+	struct mii_phy *phy = &card->phy;
+
+	/* if link didn't come up after SPIDER_NET_ANEG_TIMEOUT tries, setup phy again */
+	if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) {
+
+		pr_info("%s: link is down trying to bring it up\n", card->netdev->name);
+
+		switch (phy->medium) {
+		case GMII_COPPER:
+			if (card->is1000) {
+				/* try autoneg with the setting not for Gbps */
+				card->is1000 = 0;
+				spider_net_setup_aneg(card);
+				break;
+			} else {
+				/* enable fiber with autonegotiation first */
+				card->is1000 = 1;
+				if (phy->def->ops->enable_fiber)
+					phy->def->ops->enable_fiber(phy, 1);
+				phy->medium = GMII_FIBER;
+				break;
+			}
+
+		case GMII_FIBER:
+			/* fiber didn't come up, try to disable fiber autoneg */
+			if (phy->def->ops->enable_fiber)
+				phy->def->ops->enable_fiber(phy, 0);
+			phy->medium = GMII_UNKNOWN;
+			break;
+
+		case GMII_UNKNOWN:
+			/* copper, fiber with and without failed,
+			 * retry from beginning */
+			card->is1000 = 1;
+			spider_net_setup_aneg(card);
+			phy->medium = GMII_COPPER;
+			break;
+		}
+
+		card->aneg_count = 0;
+		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+		return;
+	}
+
+	/* link still not up, try again later */
+	if (!(phy->def->ops->poll_link(phy))) {
+		card->aneg_count++;
+		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+		return;
+	}
+
+	/* link came up, get abilities */
+	phy->def->ops->read_link(phy);
+
+	/* link is detected but we need retrying autoneg 
+	 * when initial setting was wrong */
+	if (phy->speed == 1000 && !(card->is1000)) {
+		card->is1000 = 1;
+		goto re_setup;
+	} else if (phy->speed != 1000 && card->is1000) {
+		card->is1000 = 0;
+		goto re_setup;
+	}
+
+	spider_net_write_reg(card, SPIDER_NET_GMACST,
+			     spider_net_read_reg(card, SPIDER_NET_GMACST));
+	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
+
+	if (phy->speed == 1000)
+		spider_net_write_reg(card, SPIDER_NET_GMACMODE, 0x00000001);
+	else
+		spider_net_write_reg(card, SPIDER_NET_GMACMODE, 0);
+
+	card->aneg_count = 0;
+
+	pr_info("Found %s with %i Mbps, %s-duplex %sautoneg.\n",
+		phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half",
+		phy->autoneg==1 ? "" : "no ");
+
+	return;
+
+re_setup:
+	spider_net_setup_aneg(card);
+	card->aneg_count = 0;
+	mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+}
+
+/**
  * spider_net_setup_phy - setup PHY
  * @card: card structure
  *
  * returns 0 on success, <0 on failure
  *
- * spider_net_setup_phy is used as part of spider_net_probe. Sets
- * the PHY to 1000 Mbps
+ * spider_net_setup_phy is used as part of spider_net_probe.
  **/
 static int
 spider_net_setup_phy(struct spider_net_card *card)
@@ -1720,21 +1900,21 @@
 			     SPIDER_NET_DMASEL_VALUE);
 	spider_net_write_reg(card, SPIDER_NET_GPCCTRL,
 			     SPIDER_NET_PHY_CTRL_VALUE);
-	phy->mii_id = 1;
+
 	phy->dev = card->netdev;
 	phy->mdio_read = spider_net_read_phy;
 	phy->mdio_write = spider_net_write_phy;
 
-	mii_phy_probe(phy, phy->mii_id);
-
-	if (phy->def->ops->setup_forced)
-		phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL);
-
-	phy->def->ops->enable_fiber(phy);
-
-	phy->def->ops->read_link(phy);
-	pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name,
-		phy->speed, phy->duplex==1 ? "Full" : "Half");
+	for (phy->mii_id = 1; phy->mii_id <= 31; phy->mii_id++) {
+		unsigned short id;
+		id = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+		if (id != 0x0000 && id != 0xffff) {
+			if (!mii_phy_probe(phy, phy->mii_id)) {
+				pr_info("Found %s.\n", phy->def->name);
+				break;
+			}
+		}
+	}
 
 	return 0;
 }
@@ -1907,11 +2087,13 @@
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
 	del_timer_sync(&card->tx_timer);
+	del_timer_sync(&card->aneg_timer);
 
 	/* disable/mask all interrupts */
 	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
 	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
 	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
 
 	/* free_irq(netdev->irq, netdev);*/
 	free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
@@ -2053,6 +2235,12 @@
 	card->tx_timer.data = (unsigned long) card;
 	netdev->irq = card->pdev->irq;
 
+	card->is1000 = 1;
+	card->aneg_count = 0;
+	init_timer(&card->aneg_timer);
+	card->aneg_timer.function = spider_net_link_phy;
+	card->aneg_timer.data = (unsigned long) card;
+
 	card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
 
 	card->num_tx_desc = tx_descriptors;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [RFC/PATCH 2.6.20-rc6 2/4] spidernet: load firmaware when open
  2007-02-01 11:04   ` Jens Osterkamp
  2007-02-02 10:20     ` Ishizaki Kou
  2007-02-02 10:29     ` [RFC/PATCH 2.6.20-rc6 1/4] spidernet: autoneg support for Celleb Ishizaki Kou
@ 2007-02-02 10:30     ` Ishizaki Kou
  2007-02-02 10:31     ` [RFC/PATCH 2.6.20-rc6 3/4] spidernet: add support for Celleb Ishizaki Kou
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-02 10:30 UTC (permalink / raw)
  To: jens; +Cc: linuxppc-dev, jgarzik, jim, netdev

This patch moves calling init_firmware() from spider_net_probe() to
spider_net_open() so as to use the driver by built-in.

This patch is just for a test. Please try this, if you can.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

--- org-linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:29:17.000000000 +0900
+++ linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:29:39.000000000 +0900
@@ -1718,6 +1718,124 @@
 }
 
 /**
+ * spider_net_download_firmware - loads firmware into the adapter
+ * @card: card structure
+ * @firmware_ptr: pointer to firmware data
+ *
+ * spider_net_download_firmware loads the firmware data into the
+ * adapter. It assumes the length etc. to be allright.
+ */
+static int
+spider_net_download_firmware(struct spider_net_card *card,
+			     const void *firmware_ptr)
+{
+	int sequencer, i;
+	const u32 *fw_ptr = firmware_ptr;
+
+	/* stop sequencers */
+	spider_net_write_reg(card, SPIDER_NET_GSINIT,
+			     SPIDER_NET_STOP_SEQ_VALUE);
+
+	for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
+	     sequencer++) {
+		spider_net_write_reg(card,
+				     SPIDER_NET_GSnPRGADR + sequencer * 8, 0);
+		for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
+			spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
+					     sequencer * 8, *fw_ptr);
+			fw_ptr++;
+		}
+	}
+
+	if (spider_net_read_reg(card, SPIDER_NET_GSINIT))
+		return -EIO;
+
+	spider_net_write_reg(card, SPIDER_NET_GSINIT,
+			     SPIDER_NET_RUN_SEQ_VALUE);
+
+	return 0;
+}
+
+/**
+ * spider_net_init_firmware - reads in firmware parts
+ * @card: card structure
+ *
+ * Returns 0 on success, <0 on failure
+ *
+ * spider_net_init_firmware opens the sequencer firmware and does some basic
+ * checks. This function opens and releases the firmware structure. A call
+ * to download the firmware is performed before the release.
+ *
+ * Firmware format
+ * ===============
+ * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being
+ * the program for each sequencer. Use the command
+ *    tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt              \
+ *         Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt   \
+ *         Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin
+ *
+ * to generate spider_fw.bin, if you have sequencer programs with something
+ * like the following contents for each sequencer:
+ *    <ONE LINE COMMENT>
+ *    <FIRST 4-BYTES-WORD FOR SEQUENCER>
+ *    <SECOND 4-BYTES-WORD FOR SEQUENCER>
+ *     ...
+ *    <1024th 4-BYTES-WORD FOR SEQUENCER>
+ */
+static int
+spider_net_init_firmware(struct spider_net_card *card)
+{
+	struct firmware *firmware = NULL;
+	struct device_node *dn;
+	const u8 *fw_prop = NULL;
+	int err = -ENOENT;
+	int fw_size;
+
+	if (request_firmware((const struct firmware **)&firmware,
+			     SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
+		if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
+		     netif_msg_probe(card) ) {
+			pr_err("Incorrect size of spidernet firmware in " \
+			       "filesystem. Looking in host firmware...\n");
+			goto try_host_fw;
+		}
+		err = spider_net_download_firmware(card, firmware->data);
+
+		release_firmware(firmware);
+		if (err)
+			goto try_host_fw;
+
+		goto done;
+	}
+
+try_host_fw:
+	dn = pci_device_to_OF_node(card->pdev);
+	if (!dn)
+		goto out_err;
+
+	fw_prop = get_property(dn, "firmware", &fw_size);
+	if (!fw_prop)
+		goto out_err;
+
+	if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
+	     netif_msg_probe(card) ) {
+		pr_err("Incorrect size of spidernet firmware in " \
+		       "host firmware\n");
+		goto done;
+	}
+
+	err = spider_net_download_firmware(card, fw_prop);
+
+done:
+	return err;
+out_err:
+	if (netif_msg_probe(card))
+		pr_err("Couldn't find spidernet firmware in filesystem " \
+		       "or host firmware\n");
+	return err;
+}
+
+/**
  * spider_net_open - called upon ifonfig up
  * @netdev: interface device structure
  *
@@ -1735,6 +1853,10 @@
 
 	result = -ENOMEM;
 
+	result = spider_net_init_firmware(card);
+	if (result)
+		goto init_firmware_failed;
+
 	/* start probing with copper */
 	spider_net_setup_aneg(card);
 	if (card->phy.def->phy_id)
@@ -1785,6 +1907,7 @@
 	spider_net_free_chain(card, &card->tx_chain);
 alloc_tx_failed:
 	del_timer_sync(&card->aneg_timer);
+init_firmware_failed:
 	return result;
 }
 
@@ -1920,124 +2043,6 @@
 }
 
 /**
- * spider_net_download_firmware - loads firmware into the adapter
- * @card: card structure
- * @firmware_ptr: pointer to firmware data
- *
- * spider_net_download_firmware loads the firmware data into the
- * adapter. It assumes the length etc. to be allright.
- */
-static int
-spider_net_download_firmware(struct spider_net_card *card,
-			     const void *firmware_ptr)
-{
-	int sequencer, i;
-	const u32 *fw_ptr = firmware_ptr;
-
-	/* stop sequencers */
-	spider_net_write_reg(card, SPIDER_NET_GSINIT,
-			     SPIDER_NET_STOP_SEQ_VALUE);
-
-	for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
-	     sequencer++) {
-		spider_net_write_reg(card,
-				     SPIDER_NET_GSnPRGADR + sequencer * 8, 0);
-		for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
-			spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
-					     sequencer * 8, *fw_ptr);
-			fw_ptr++;
-		}
-	}
-
-	if (spider_net_read_reg(card, SPIDER_NET_GSINIT))
-		return -EIO;
-
-	spider_net_write_reg(card, SPIDER_NET_GSINIT,
-			     SPIDER_NET_RUN_SEQ_VALUE);
-
-	return 0;
-}
-
-/**
- * spider_net_init_firmware - reads in firmware parts
- * @card: card structure
- *
- * Returns 0 on success, <0 on failure
- *
- * spider_net_init_firmware opens the sequencer firmware and does some basic
- * checks. This function opens and releases the firmware structure. A call
- * to download the firmware is performed before the release.
- *
- * Firmware format
- * ===============
- * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being
- * the program for each sequencer. Use the command
- *    tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt              \
- *         Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt   \
- *         Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin
- *
- * to generate spider_fw.bin, if you have sequencer programs with something
- * like the following contents for each sequencer:
- *    <ONE LINE COMMENT>
- *    <FIRST 4-BYTES-WORD FOR SEQUENCER>
- *    <SECOND 4-BYTES-WORD FOR SEQUENCER>
- *     ...
- *    <1024th 4-BYTES-WORD FOR SEQUENCER>
- */
-static int
-spider_net_init_firmware(struct spider_net_card *card)
-{
-	struct firmware *firmware = NULL;
-	struct device_node *dn;
-	const u8 *fw_prop = NULL;
-	int err = -ENOENT;
-	int fw_size;
-
-	if (request_firmware((const struct firmware **)&firmware,
-			     SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
-		if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
-		     netif_msg_probe(card) ) {
-			pr_err("Incorrect size of spidernet firmware in " \
-			       "filesystem. Looking in host firmware...\n");
-			goto try_host_fw;
-		}
-		err = spider_net_download_firmware(card, firmware->data);
-
-		release_firmware(firmware);
-		if (err)
-			goto try_host_fw;
-
-		goto done;
-	}
-
-try_host_fw:
-	dn = pci_device_to_OF_node(card->pdev);
-	if (!dn)
-		goto out_err;
-
-	fw_prop = get_property(dn, "firmware", &fw_size);
-	if (!fw_prop)
-		goto out_err;
-
-	if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
-	     netif_msg_probe(card) ) {
-		pr_err("Incorrect size of spidernet firmware in " \
-		       "host firmware\n");
-		goto done;
-	}
-
-	err = spider_net_download_firmware(card, fw_prop);
-
-done:
-	return err;
-out_err:
-	if (netif_msg_probe(card))
-		pr_err("Couldn't find spidernet firmware in filesystem " \
-		       "or host firmware\n");
-	return err;
-}
-
-/**
  * spider_net_workaround_rxramfull - work around firmware bug
  * @card: card structure
  *
@@ -2138,8 +2143,6 @@
 
 	if (spider_net_setup_phy(card))
 		goto out;
-	if (spider_net_init_firmware(card))
-		goto out;
 
 	spider_net_open(netdev);
 	spider_net_kick_tx_dma(card);
@@ -2419,10 +2422,6 @@
 	if (err)
 		goto out_undo_pci;
 
-	err = spider_net_init_firmware(card);
-	if (err)
-		goto out_undo_pci;
-
 	err = spider_net_setup_netdev(card);
 	if (err)
 		goto out_undo_pci;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [RFC/PATCH 2.6.20-rc6 3/4] spidernet: add support for Celleb
  2007-02-01 11:04   ` Jens Osterkamp
                       ` (2 preceding siblings ...)
  2007-02-02 10:30     ` [RFC/PATCH 2.6.20-rc6 2/4] spidernet: load firmaware when open Ishizaki Kou
@ 2007-02-02 10:31     ` Ishizaki Kou
  2007-02-02 10:33     ` [RFC/PATCH 2.6.20-rc6 4/4] spidernet: remove txram full logging Ishizaki Kou
  2007-02-04 23:44     ` [Cbe-oss-dev] spidernet: dynamic phy setup code Benjamin Herrenschmidt
  5 siblings, 0 replies; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-02 10:31 UTC (permalink / raw)
  To: jens; +Cc: linuxppc-dev, jgarzik, jim, netdev

This patch adds or changes some HW specific settings for spider_net on
Celleb.

This patch is just for a test. Please try this, if you can.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

--- org-linux-powerpc-git/drivers/net/Kconfig	2007-02-02 14:34:19.000000000 +0900
+++ linux-powerpc-git/drivers/net/Kconfig	2007-02-02 14:32:18.000000000 +0900
@@ -2256,7 +2256,7 @@
 
 config SPIDER_NET
 	tristate "Spider Gigabit Ethernet driver"
-	depends on PCI && PPC_IBM_CELL_BLADE
+	depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
 	select FW_LOADER
 	help
 	  This driver supports the Gigabit Ethernet chips present on the
--- org-linux-powerpc-git/drivers/net/spider_net.h	2007-02-02 14:29:13.000000000 +0900
+++ linux-powerpc-git/drivers/net/spider_net.h	2007-02-02 14:32:18.000000000 +0900
@@ -1,7 +1,8 @@
 /*
- * Network device driver for Cell Processor-Based Blade
+ * Network device driver for Cell Processor-Based Blade and Celleb platform
  *
  * (C) Copyright IBM Corp. 2005
+ * (C) Copyright 2006 TOSHIBA CORPORATION
  *
  * Authors : Utz Bacher <utz.bacher@de.ibm.com>
  *           Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
@@ -184,7 +185,8 @@
 
 /* pause frames: automatic, no upper retransmission count */
 /* outside loopback mode: ETOMOD signal dont matter, not connected */
-#define SPIDER_NET_OPMODE_VALUE		0x00000063
+/* ETOMOD signal is brought to PHY reset. bit 2 must be 1 in Celleb */
+#define SPIDER_NET_OPMODE_VALUE		0x00000067
 /*#define SPIDER_NET_OPMODE_VALUE		0x001b0062*/
 #define SPIDER_NET_LENLMT_VALUE		0x00000908
 
--- org-linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:31:39.000000000 +0900
+++ linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:32:18.000000000 +0900
@@ -1,7 +1,8 @@
 /*
- * Network device driver for Cell Processor-Based Blade
+ * Network device driver for Cell Processor-Based Blade and Celleb platform
  *
  * (C) Copyright IBM Corp. 2005
+ * (C) Copyright 2006 TOSHIBA CORPORATION
  *
  * Authors : Utz Bacher <utz.bacher@de.ibm.com>
  *           Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
@@ -1618,6 +1619,11 @@
 
 	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
 			     SPIDER_NET_CKRCTRL_RUN_VALUE);
+
+	/* trigger ETOMOD signal */
+	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
+		spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
+
 }
 
 /**

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [RFC/PATCH 2.6.20-rc6 4/4] spidernet: remove txram full logging
  2007-02-01 11:04   ` Jens Osterkamp
                       ` (3 preceding siblings ...)
  2007-02-02 10:31     ` [RFC/PATCH 2.6.20-rc6 3/4] spidernet: add support for Celleb Ishizaki Kou
@ 2007-02-02 10:33     ` Ishizaki Kou
  2007-02-04 23:44     ` [Cbe-oss-dev] spidernet: dynamic phy setup code Benjamin Herrenschmidt
  5 siblings, 0 replies; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-02 10:33 UTC (permalink / raw)
  To: jens; +Cc: linuxppc-dev, jgarzik, jim, netdev

This patches removes logging for SPIDER_NET_GTMFLLINT interrupts.
Since the interrupts are not irregular, and they happen frequently
when using 100Mbps network switches.

This patch is just for a test. Please try this if you can.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

--- org-linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:35:14.000000000 +0900
+++ linux-powerpc-git/drivers/net/spider_net.c	2007-02-02 14:35:49.000000000 +0900
@@ -1435,8 +1435,8 @@
 				switch (i)
 	{
 	case SPIDER_NET_GTMFLLINT:
-		if (netif_msg_intr(card) && net_ratelimit())
-			pr_err("Spider TX RAM full\n");
+		/* TX RAM full may happen on a usual case.
+		 * Logging is not needed. */
 		show_error = 0;
 		break;
 	case SPIDER_NET_GRFDFLLINT: /* fallthrough */

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Cbe-oss-dev] spidernet: dynamic phy setup code
  2007-02-01 11:04   ` Jens Osterkamp
                       ` (4 preceding siblings ...)
  2007-02-02 10:33     ` [RFC/PATCH 2.6.20-rc6 4/4] spidernet: remove txram full logging Ishizaki Kou
@ 2007-02-04 23:44     ` Benjamin Herrenschmidt
  5 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2007-02-04 23:44 UTC (permalink / raw)
  To: Jens Osterkamp; +Cc: linuxppc-dev, netdev, jgarzik, jim

On Thu, 2007-02-01 at 12:04 +0100, Jens Osterkamp wrote:
> Ishizaki-san,
> 
> > This patch partially works on celleb but remains 
> > following several problems.
> > 1. It doesn't recover once an ethernet cable which is
> >    connected to a spider_net card is unpluged. 
> 
> My understanding is that you are using the LINK interrupt to detect this.
> For the blade this is not connected but reenabling it wont hurt, I hope.

I would suggest just polling from a delayed work or a timer like sungem
does.

> I still dont see why you need different settings for different speed switches.
> This is getting to a point where access to some hardware would be handy.
> What exact phy are using anyway ?

Yeah, same question...

> > Furthermore, we have a problem that poll_link() may succeed even when
> > the auto-neg initial setting is for different network switch type,
> > and the network card does not work on this case. We retry auto-neg
> > with the another initial setting on this case.
> 
> See above, could you give some more details why this is the case. Or maybe Ben
> knows more about this ?

No, I'm surprised too.

Ben.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-02-02 10:20     ` Ishizaki Kou
@ 2007-02-05  0:08       ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2007-02-05  0:08 UTC (permalink / raw)
  To: Ishizaki Kou; +Cc: netdev, jgarzik, jim, linuxppc-dev


> We use bcm5461. There is a possibility that we don't know the appropriate
> setting which is applicable for both type of switches.

Have you tested the existing 54xx code in sungem_phy.c ? We use that
with 5462 at least in K2 and all sorts of 54xx chips and it works
fine... Just setup the right advertisement bits and call setup_aneg in
the PHY ops. You don't even need to implement the "forced" fallback code
that is in sungem. It's not necessary with most broadcom PHYs as they do
that themselves, just setup aneg and poll the link from a timer, that's
it. Once you get a link, then setup your GMACMODE based on the link
speed.

I don't have the datasheet of the 5461 at hand but I doubt it's any
different... Like other Broadcom 54xx PHYs, it might need some special
initialization code to work around firmware bugs though...

> We didn't investigate for the detail, but we met the following phenomena.
> 1. When auto-neg starts with Gbps setting and ethernet card is connected to
>    a 100Mbps switch, LINK is not detected.
> 2. When auto-neg starts with 100/10Mbps setting and ethernet card is 
>    connected to Gbps switch, LINK is detected (poll_link() succeeds), but
>    the network is not available.

That is very strange... I would need to review your code in more details
or eventually have HW access to run my own experiments, but none of this
should happen if things are setup properly. Also avoid relying on the
link interrupt, it's a known cause of trouble. Just poll.

Ben.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: spidernet: dynamic phy setup code
  2007-02-01  7:54 kou.ishizaki
@ 2007-02-06 10:42 ` Ishizaki Kou
  0 siblings, 0 replies; 16+ messages in thread
From: Ishizaki Kou @ 2007-02-06 10:42 UTC (permalink / raw)
  To: jens, benh; +Cc: linuxppc-dev, netdev

Ben-san, Jens-san

Thanks for your comments and advices.
First, we should apologize to you that some troubles which we informed
about spidernet auto-negotiation are caused by our mistake.
We used wrong MACRO for "advertise" variable to
phy->def->ops->setup_aneg(). 

We will post the revised patch for spider_net.
Following are the current status of troubles we informed.

(1)
>- if (card->aneg_count > 10) {
>-  /* timeout */
>-  card->aneg_count = 0;
>-  is1000 = !is1000;
>-  goto re_setup;
>- if (phy->speed == 1000 && !is1000) {
>-  is1000 = 1;
>-  goto re_setup;
>- } else if(phy->speed != 1000 && is1000) {
>-  is1000 = 0;
>-  goto re_setup;
>- }
> We need to use different auto-neg initial settings between
> for 10/100Mbps ethernet switches and for Gbps ethernet switches.
> Driver don't know which type of network switch is connected to
> network card, so we try both settings alternately in auto negtiation
> sequences by using a variable "is1000".
> Furthermore, we have a problem that poll_link() may succeed even when
> the auto-neg initial setting is for different network switch type,
> and the network card does not work on this case. We retry auto-neg
> with the another initial setting on this case.
Solved.

We are now able to use Gbps switches and 10/100Mbps switches with 
the same advertise setting and we don't need to use is1000.
The re_setup is not necessary and they are removed in the revised patch.

2.
>> - spider_net_write_reg(card, SPIDER_NET_GMACST,
>> -        spider_net_read_reg(card, SPIDER_NET_GMACST));
>> - spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
>
> These codes are enabling LINK status interrupt which is disabled
> at the beginning of auto-neg.
> Without this operation, auto negotiation works only when a connection
> detected for the first time, and auto negotiation will not work 
> when an ethernet cable is unpluged or pluged.
Pending(No problem, if they don't cause any trouble on Cell Blades).

By the way, why do you suggest to use polling for auto-neg, Ben-san? 
Is there a merit to use polling, or is there a problem to use interrupt?
Sorry, we couldn't find the reason why sungem use polling for auto-neg. 

They might not be necessary, if we use polling to handle LINK status as
Ben-san said.

3
>> - mii_phy_probe(phy, phy->mii_id);
> It seems that PHY reset is necessary before auto negotiation,
> in the case that ethernet card is disconnected from an ethernet switch
> then connected to another ethernet switch.
> We can't call directly reset routine from driver, so we call
mii_phy_probe().
Pending.

After all, we need phy reset.
> If you really need to reset it, then change sungem_phy.c to export the
> reset function. But I'm surprised you need that. Another option is to
> reset the PHY in your PHY's setup_aneg() function.
We still wonder which is the best way, and mii_phy_probe() still remains
so far.

Best regards,
Kou Ishizaki

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2007-02-06 10:43 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-26 13:09 spidernet: dynamic phy setup code Jens Osterkamp
2007-01-26 17:58 ` Linas Vepstas
     [not found]   ` <200701262150.52882.jens@de.ibm.com>
2007-01-26 22:15     ` Linas Vepstas
2007-01-26 22:30       ` Jens Osterkamp
2007-01-26 20:21 ` Benjamin Herrenschmidt
2007-02-01 10:50   ` Jens Osterkamp
2007-02-01  8:05 ` [Cbe-oss-dev] " Ishizaki Kou
2007-02-01 11:04   ` Jens Osterkamp
2007-02-02 10:20     ` Ishizaki Kou
2007-02-05  0:08       ` Benjamin Herrenschmidt
2007-02-02 10:29     ` [RFC/PATCH 2.6.20-rc6 1/4] spidernet: autoneg support for Celleb Ishizaki Kou
2007-02-02 10:30     ` [RFC/PATCH 2.6.20-rc6 2/4] spidernet: load firmaware when open Ishizaki Kou
2007-02-02 10:31     ` [RFC/PATCH 2.6.20-rc6 3/4] spidernet: add support for Celleb Ishizaki Kou
2007-02-02 10:33     ` [RFC/PATCH 2.6.20-rc6 4/4] spidernet: remove txram full logging Ishizaki Kou
2007-02-04 23:44     ` [Cbe-oss-dev] spidernet: dynamic phy setup code Benjamin Herrenschmidt
  -- strict thread matches above, loose matches on Subject: below --
2007-02-01  7:54 kou.ishizaki
2007-02-06 10:42 ` spidernet: dynamic phy setup code Ishizaki Kou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).