DORMANTno replies

[PATCH 2.4 10/13] e1000: Added workaround to prevent inadvertent gigabit waveform to be sent out on the wire due to init-time operations on the IGP phy

From: Ganesh Venkatesan <hidden>
Date: 2005-01-07 01:20:17

Signed-off-by: Ganesh Venkatesan <redacted>
diff -up net-drivers-2.4/drivers/net/e1000/e1000_hw.c net-drivers-2.4/drivers/net/e1000.new/e1000_hw.c
--- net-drivers-2.4/drivers/net/e1000/e1000_hw.c	2004-12-06 08:43:11.629382832 -0800
+++ net-drivers-2.4/drivers/net/e1000.new/e1000_hw.c	2004-12-06 08:43:12.460256520 -0800
@@ -123,17 +123,31 @@ e1000_set_phy_type(struct e1000_hw *hw)
 static void
 e1000_phy_init_script(struct e1000_hw *hw)
 {
+    uint32_t ret_val;
+    uint16_t phy_saved_data;
+
     DEBUGFUNC("e1000_phy_init_script");
 
-    
+
     if(hw->phy_init_script) {
         msec_delay(20);
 
+        /* Save off the current value of register 0x2F5B to be restored at
+         * the end of this routine. */
+        ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+        /* Disabled the PHY transmitter */
+        e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+        msec_delay(20);
+
         e1000_write_phy_reg(hw,0x0000,0x0140);
 
         msec_delay(5);
 
-        if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
+        switch(hw->mac_type) {
+        case e1000_82541:
+        case e1000_82547:
             e1000_write_phy_reg(hw, 0x1F95, 0x0001);
 
             e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
@@ -151,12 +165,23 @@ e1000_phy_init_script(struct e1000_hw *h
             e1000_write_phy_reg(hw, 0x1F96, 0x003F);
 
             e1000_write_phy_reg(hw, 0x2010, 0x0008);
-        } else {
+            break;
+
+        case e1000_82541_rev_2:
+        case e1000_82547_rev_2:
             e1000_write_phy_reg(hw, 0x1F73, 0x0099);
+            break;
+        default:
+            break;
         }
 
         e1000_write_phy_reg(hw, 0x0000, 0x3300);
 
+        msec_delay(20);
+
+        /* Now enable the transmitter */
+        e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
         if(hw->mac_type == e1000_82547) {
             uint16_t fused, fine, coarse;
 
@@ -968,7 +993,7 @@ e1000_setup_copper_link(struct e1000_hw 
 
             if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
                 hw->dsp_config_state = e1000_dsp_config_disabled;
-                /* Force MDI for IGP B-0 PHY */
+                /* Force MDI for earlier revs of the IGP PHY */
                 phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
                               IGP01E1000_PSCR_FORCE_MDI_MDIX);
                 hw->mdix = 1;
@@ -4924,7 +4949,7 @@ e1000_config_dsp_after_link_change(struc
                                    boolean_t link_up)
 {
     int32_t ret_val;
-    uint16_t phy_data, speed, duplex, i;
+    uint16_t phy_data, phy_saved_data, speed, duplex, i;
     uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
                                         {IGP01E1000_PHY_AGC_PARAM_A,
                                         IGP01E1000_PHY_AGC_PARAM_B,
@@ -5005,6 +5030,21 @@ e1000_config_dsp_after_link_change(struc
         }
     } else {
         if(hw->dsp_config_state == e1000_dsp_config_activated) {
+            /* Save off the current value of register 0x2F5B to be restored at
+             * the end of the routines. */
+            ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
+            /* Disable the PHY transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+            if(ret_val)
+                return ret_val;
+
+            msec_delay(20);
+
             ret_val = e1000_write_phy_reg(hw, 0x0000,
                                           IGP01E1000_IEEE_FORCE_GIGA);
             if(ret_val)
@@ -5027,10 +5067,33 @@ e1000_config_dsp_after_link_change(struc
             if(ret_val)
                 return ret_val;
 
+            msec_delay(20);
+
+            /* Now enable the transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
             hw->dsp_config_state = e1000_dsp_config_enabled;
         }
 
         if(hw->ffe_config_state == e1000_ffe_config_active) {
+            /* Save off the current value of register 0x2F5B to be restored at
+             * the end of the routines. */
+            ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
+            /* Disable the PHY transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+            if(ret_val)
+                return ret_val;
+
+            msec_delay(20);
+
             ret_val = e1000_write_phy_reg(hw, 0x0000,
                                           IGP01E1000_IEEE_FORCE_GIGA);
             if(ret_val)
@@ -5044,6 +5107,15 @@ e1000_config_dsp_after_link_change(struc
                                           IGP01E1000_IEEE_RESTART_AUTONEG);
             if(ret_val)
                 return ret_val;
+
+            msec_delay(20);
+
+            /* Now enable the transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
             hw->ffe_config_state = e1000_ffe_config_enabled;
         }
     }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help