Thread (1 message) 1 message, 1 author, 2009-01-21

Fwd: Question regarding e1000 link status

From: Jonathan Fournier <hidden>
Date: 2009-01-21 20:12:28

Hi,

I'm forwarding to netdev, a little thread I created yesterday on
e1000-devel (3 posted messages). Trying to reach a wider audience.

Cheers,

/jonathan

---------- Forwarded message ----------
From: Jonathan Fournier <redacted>
Date: Tue, Jan 20, 2009 at 6:47 PM
Subject: Re: Question regarding e1000 link status
To: e1000-devel@lists.sourceforge.net

From e1000_hw.c: e1000_set_media_type()
...
       default:
           status = er32(STATUS);
           if (status & E1000_STATUS_TBIMODE) {
               hw->media_type = e1000_media_type_fiber;
               /* tbi_compatibility not valid on fiber */
               hw->tbi_compatibility_en = false;
           } else {
               hw->media_type = e1000_media_type_copper;
           }
           break;
       }

Could it be possible that the media_type is set to fiber by error here?

I'm trying to compare with the source of the last version 8.0.9, and
only finding assignments to "phy.media_type" in those files:

e1000_82540.c:164:              hw->phy.media_type = e1000_media_type_fiber;
e1000_82540.c:168:              hw->phy.media_type =
e1000_media_type_internal_serdes;
e1000_82540.c:171:              hw->phy.media_type = e1000_media_type_copper;
e1000_82541.c:224:      hw->phy.media_type = e1000_media_type_copper;
e1000_82542.c:100:      hw->phy.media_type = e1000_media_type_fiber;
e1000_82543.c:196:              hw->phy.media_type = e1000_media_type_fiber;
e1000_82543.c:199:              hw->phy.media_type = e1000_media_type_copper;

Cheers,

/jonathan

On Tue, Jan 20, 2009 at 6:00 PM, Jonathan Fournier
[off-list ref] wrote:
quoted hunk
Hi,

I've found more information to share about my problem.

I'm debugging on the ATCA-7101, I initially thought from the datasheet
that it had a 82546EB, but by printing the pdev->device it has a value
of 0x1079 = E1000_DEV_ID_82546GB_COPPER.

Since in the patch I've previously provided, I was wondering why the
PHY Reset hacks were done based on the hw.media_type ==
e1000_media_type_fiber || e1000_media_type_internal_serdes.

I also added info in the printk displayed at boot time:

       /* print bus type/speed/width info */
-       DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
+       DPRINTK(PROBE, INFO, "(PCI%s:%s:%s:%04x:%d) ",
               ((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
                (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
               ((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
@@ -1194,7 +1198,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
               ((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
                (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
                (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
-                "32-bit"));
+                "32-bit"), pdev->device, hw->media_type);

--------->--------->--------->--------->--------->--------->--------->--------->--------->---------
Intel(R) PRO/1000 Network Driver - version 7.3.20-k3-NAPI
Copyright (c) 1999-2006 Intel Corporation.
ACPI: PCI Interrupt Link [LNKA] enabled at IRQ 10
PCI: setting IRQ 10 as level-triggered
e1000 0000:0b:01.0: PCI INT A -> Link[LNKA] -> GSI 10 (level, low) -> IRQ 10
e1000: 0000:0b:01.0: e1000_probe: (PCI-X:133MHz:64-bit:1079:0) 00:01:af:15:82:f2
e1000: eth0: e1000_probe: Intel(R) PRO/1000 Network Connection
e1000 0000:0b:01.1: PCI INT B -> Link[LNKA] -> GSI 10 (level, low) -> IRQ 10
e1000: 0000:0b:01.1: e1000_probe: (PCI-X:133MHz:64-bit:1079:0) 00:01:af:15:82:f3
Switched to high resolution mode on CPU 0
e1000: eth1: e1000_probe: Intel(R) PRO/1000 Network Connection
e1000 0000:0a:01.0: PCI INT A -> Link[LNKA] -> GSI 10 (level, low) -> IRQ 10
e1000: 0000:0a:01.0: e1000_probe: (PCI-X:133MHz:64-bit:1079:1) 00:01:af:15:82:f0
e1000: eth2: e1000_probe: Intel(R) PRO/1000 Network Connection
e1000 0000:0a:01.1: PCI INT B -> Link[LNKA] -> GSI 10 (level, low) -> IRQ 10
e1000: 0000:0a:01.1: e1000_probe: (PCI-X:133MHz:64-bit:1079:1) 00:01:af:15:82:f1
e1000: eth3: e1000_probe: Intel(R) PRO/1000 Network Connection
ACPI: PCI Interrupt Link [LNKB] enabled at IRQ 7
PCI: setting IRQ 7 as level-triggered
e1000 0000:07:01.0: PCI INT A -> Link[LNKB] -> GSI 7 (level, low) -> IRQ 7
e1000: 0000:07:01.0: e1000_probe: (PCI-X:133MHz:64-bit:1079:0) 00:01:af:15:82:f4
e1000: eth4: e1000_probe: Intel(R) PRO/1000 Network Connection
e1000 0000:07:01.1: PCI INT B -> Link[LNKB] -> GSI 7 (level, low) -> IRQ 7
e1000: 0000:07:01.1: e1000_probe: (PCI-X:133MHz:64-bit:1079:0) 00:01:af:15:82:f5
e1000: eth5: e1000_probe: Intel(R) PRO/1000 Network Connection

--------->--------->--------->--------->--------->--------->--------->--------->--------->---------

To my surprise, two of the interface had this: (PCI-X:133MHz:64-bit:1079:1)

pdev->device = E1000_DEV_ID_82546GB_COPPER = 0x1079
hw->media_type = e1000_media_type_fiber = 1

Is it really possible that a 82546GB_COPPER uses fiber as it's media
type? If not that could explain why such an hack was introduced to
make sure the PHY reset occured?

I don't know much about e1000 internals, so I'm asking if it's an
error, and how come the media_type could be set wrong then?

Cheers,

/jonathan

On Mon, Jan 19, 2009 at 5:09 PM, Jonathan Fournier
[off-list ref] wrote:
quoted
Hi,

I'm currently doing some cleanup in *very* old patches I had against
2.6.10. (patch inlined below)

At that time a patch was provided to me to fix link status problems on
two ATCA boards (Mot ATCA-7101 and Mot ATCA-6101). If I'm correct the
7101 is using a variant of the 82546EB, and the 6101 a variant of the
82546GB.

I'm trying to achieve two things with that patch:

1. Cleanup the #if defined (CONFIG_ ...) that are introducing
useless kernel CONFIG options that are probably not board specific.

       1.a If needed move those to check based on DEVID or media_type
       1.b If not needed, trash them.

2. Asking around if playing with those PHY registers is the best
approach.
       2.a Submit patch upstream when cleaned up

I'm currently testing with the e1000 driver as of "commit
c6c427835cd755115a0f86da1aa9c97b2f8ffff8" (2.6.27.11)

When issuing ifdown on the interfaces I get some hanging, so I believe
those old changes might still be required in their current form, or
rebased for the current driver.

I think I've identified where in the current driver where that code
could fit, just asking around if you think it could be needed.

Cheers,

/jonathan

----------------------------------------------------------------------
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -29,6 +29,9 @@
 #include "e1000.h"

 /* Change Log
+ * 5.3.13      3/23/06
+ * - synchronize physical link with interface (j.pietro@xxx)
+ *
 * 5.3.12      6/7/04
 * - kcompat NETIF_MSG for older kernels (2.4.9) <sean.p.mcdermott@xxx>
 * - if_mii support and associated kcompat for older kernels
@@ -258,12 +261,35 @@
       /* hardware has been reset, we need to reload some things */

       /* Reset the PHY if it was previously powered down */
-       if(adapter->hw.media_type == e1000_media_type_copper) {
+       if(adapter->hw.media_type == e1000_media_type_copper)
+       {
               uint16_t mii_reg;
               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
               if(mii_reg & MII_CR_POWER_DOWN)
                       e1000_phy_reset(&adapter->hw);
       }
+#if defined(CONFIG_PPC_ATCA6101) || defined(CONFIG_INTEL_ATCA7101)
+       else if((adapter->hw.media_type == e1000_media_type_fiber) ||
+               (adapter->hw.media_type == e1000_media_type_internal_serdes))
+       {
+               int32_t  ret_val;
+               int32_t  ret_val2;
+               uint16_t default_page = 0;
+               uint16_t phy_data;
+
+               /* Set PHY register 30, page 31, bits 15:0 <= 0h */
+               ret_val2 = ret_val = e1000_read_phy_reg(&adapter->hw,
M88E1000_PHY_PAGE_SELECT, &default_page);
+               if(ret_val == E1000_SUCCESS)
+                       ret_val = e1000_write_phy_reg(&adapter->hw,
M88E1000_PHY_PAGE_SELECT, 31);
+               if(ret_val == E1000_SUCCESS)
+                       ret_val = e1000_read_phy_reg(&adapter->hw,
M88E1000_PHY_GEN_CONTROL, &phy_data);
+               phy_data &= 0xFFFF0000;
+               if(ret_val == E1000_SUCCESS)
+                       e1000_write_phy_reg(&adapter->hw,
M88E1000_PHY_GEN_CONTROL, phy_data);
+               if(ret_val2 == E1000_SUCCESS)
+                       e1000_write_phy_reg(&adapter->hw,
M88E1000_PHY_PAGE_SELECT, default_page);
+       }
+#endif

       e1000_set_multi(netdev);
@@ -306,12 +332,43 @@

       /* If WoL is not enabled
        * Power down the PHY so no link is implied when interface is down */
+#if defined(CONFIG_PPC_ATCA6101) || defined(CONFIG_INTEL_ATCA7101)
+       if(!adapter->wol)
+       {
+               if(adapter->hw.media_type == e1000_media_type_copper)
+               {
+#else
       if(!adapter->wol && adapter->hw.media_type == e1000_media_type_copper) {
+#endif
               uint16_t mii_reg;
               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
               mii_reg |= MII_CR_POWER_DOWN;
               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
       }
+#if defined(CONFIG_PPC_ATCA6101) || defined(CONFIG_INTEL_ATCA7101)
+               else if((adapter->hw.media_type == e1000_media_type_fiber) ||
+                       (adapter->hw.media_type ==
e1000_media_type_internal_serdes))
+               {
+                       int32_t  ret_val;
+                       int32_t  ret_val2;
+                       uint16_t default_page = 0;
+                       uint16_t phy_data;
+
+                       /* Set PHY register 30, page 31, bits 15:0 <= 2001h */
+                       ret_val2 = ret_val =
e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_PAGE_SELECT,
&default_page);
+                       if(ret_val == E1000_SUCCESS)
+                               ret_val =
e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_PAGE_SELECT, 31);
+                       if(ret_val == E1000_SUCCESS)
+                               ret_val =
e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
+                       phy_data &= 0xFFFF0000;
+                       phy_data |= 0x2001;
+                       if(ret_val == E1000_SUCCESS)
+                               ret_val =
e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_GEN_CONTROL, phy_data);
+                       if(ret_val2 == E1000_SUCCESS)
+                               e1000_write_phy_reg(&adapter->hw,
M88E1000_PHY_PAGE_SELECT, default_page);
+               }
+       }
+#endif
 }

 void
@@ -588,6 +645,42 @@
       if((err = register_netdev(netdev)))
               goto err_register;

+#if defined(CONFIG_PPC_ATCA6101) || defined(CONFIG_INTEL_ATCA7101)
+       /* If WoL is not enabled
+        * Power down the PHY so no link is implied when interface is down */
+       if(!adapter->wol)
+       {
+               if(adapter->hw.media_type == e1000_media_type_copper)
+               {
+                       uint16_t mii_reg;
+                       e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
+                       mii_reg |= MII_CR_POWER_DOWN;
+                       e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
+               }
+               else if((adapter->hw.media_type == e1000_media_type_fiber) ||
+                       (adapter->hw.media_type ==
e1000_media_type_internal_serdes))
+               {
+                       int32_t  ret_val;
+                       int32_t  ret_val2;
+                       uint16_t default_page = 0;
+                       uint16_t phy_data;
+
+                       /* Set PHY register 30, page 31, bits 15:0 <= 2001h */
+                       ret_val2 = ret_val =
e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_PAGE_SELECT,
&default_page);
+                       if(ret_val == E1000_SUCCESS)
+                               ret_val =
e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_PAGE_SELECT, 31);
+                       if(ret_val == E1000_SUCCESS)
+                               ret_val =
e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
+                       phy_data &= 0xFFFF0000;
+                       phy_data |= 0x2001;
+                       if(ret_val == E1000_SUCCESS)
+                               ret_val =
e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_GEN_CONTROL, phy_data);
+                       if(ret_val2 == E1000_SUCCESS)
+                               e1000_write_phy_reg(&adapter->hw,
M88E1000_PHY_PAGE_SELECT, default_page);
+               }
+       }
+#endif
+
       DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");

       cards_found++;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help