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
* (no subject)
@ 2007-02-01  7:54 kou.ishizaki
  2007-02-06 10:42 ` spidernet: dynamic phy setup code Ishizaki Kou
  0 siblings, 1 reply; 16+ messages in thread
From: kou.ishizaki @ 2007-02-01  7:54 UTC (permalink / raw)
  To: jens; +Cc: linuxppc-dev, netdev

jgarzik@pobox.com, jim@jklewis.com
Subject: Re: [Cbe-oss-dev] spidernet: dynamic phy setup code
In-Reply-To: <200701261409.29537.jens@de.ibm.com>
From: Ishizaki Kou <kouish@swc.toshiba.co.jp>
X-Mailer: Mew version 4.2 on Emacs 21.3 / Mule 5.0 (SAKAKI)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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

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).