]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/e1000e/lib.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
[linux-2.6-omap-h63xx.git] / drivers / net / e1000e / lib.c
index 089578f6855a21500188034b6f4fd09809658dfc..66741104ffd1b3e6c02ab4af574e915540591f58 100644 (file)
@@ -575,20 +575,42 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
                 */
                /* SYNCH bit and IV bit are sticky. */
                udelay(10);
-               if (E1000_RXCW_SYNCH & er32(RXCW)) {
+               rxcw = er32(RXCW);
+               if (rxcw & E1000_RXCW_SYNCH) {
                        if (!(rxcw & E1000_RXCW_IV)) {
-                               mac->serdes_has_link = 1;
-                               hw_dbg(hw, "SERDES: Link is up.\n");
+                               mac->serdes_has_link = true;
+                               hw_dbg(hw, "SERDES: Link up - forced.\n");
                        }
                } else {
-                       mac->serdes_has_link = 0;
-                       hw_dbg(hw, "SERDES: Link is down.\n");
+                       mac->serdes_has_link = false;
+                       hw_dbg(hw, "SERDES: Link down - force failed.\n");
                }
        }
 
        if (E1000_TXCW_ANE & er32(TXCW)) {
                status = er32(STATUS);
-               mac->serdes_has_link = (status & E1000_STATUS_LU);
+               if (status & E1000_STATUS_LU) {
+                       /* SYNCH bit and IV bit are sticky, so reread rxcw.  */
+                       udelay(10);
+                       rxcw = er32(RXCW);
+                       if (rxcw & E1000_RXCW_SYNCH) {
+                               if (!(rxcw & E1000_RXCW_IV)) {
+                                       mac->serdes_has_link = true;
+                                       hw_dbg(hw, "SERDES: Link up - autoneg "
+                                          "completed sucessfully.\n");
+                               } else {
+                                       mac->serdes_has_link = false;
+                                       hw_dbg(hw, "SERDES: Link down - invalid"
+                                          "codewords detected in autoneg.\n");
+                               }
+                       } else {
+                               mac->serdes_has_link = false;
+                               hw_dbg(hw, "SERDES: Link down - no sync.\n");
+                       }
+               } else {
+                       mac->serdes_has_link = false;
+                       hw_dbg(hw, "SERDES: Link down - autoneg failed\n");
+               }
        }
 
        return 0;
@@ -623,12 +645,12 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
        }
 
        if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
-               hw->fc.type = e1000_fc_none;
+               hw->fc.requested_mode = e1000_fc_none;
        else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
                 NVM_WORD0F_ASM_DIR)
-               hw->fc.type = e1000_fc_tx_pause;
+               hw->fc.requested_mode = e1000_fc_tx_pause;
        else
-               hw->fc.type = e1000_fc_full;
+               hw->fc.requested_mode = e1000_fc_full;
 
        return 0;
 }
@@ -656,23 +678,23 @@ s32 e1000e_setup_link(struct e1000_hw *hw)
                return 0;
 
        /*
-        * If flow control is set to default, set flow control based on
-        * the EEPROM flow control settings.
+        * If requested flow control is set to default, set flow control
+        * based on the EEPROM flow control settings.
         */
-       if (hw->fc.type == e1000_fc_default) {
+       if (hw->fc.requested_mode == e1000_fc_default) {
                ret_val = e1000_set_default_fc_generic(hw);
                if (ret_val)
                        return ret_val;
        }
 
        /*
-        * We want to save off the original Flow Control configuration just
-        * in case we get disconnected and then reconnected into a different
-        * hub or switch with different Flow Control capabilities.
+        * Save off the requested flow control mode for use later.  Depending
+        * on the link partner's capabilities, we may or may not use this mode.
         */
-       hw->fc.original_type = hw->fc.type;
+       hw->fc.current_mode = hw->fc.requested_mode;
 
-       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
+       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n",
+               hw->fc.current_mode);
 
        /* Call the necessary media_type subroutine to configure the link. */
        ret_val = mac->ops.setup_physical_interface(hw);
@@ -724,7 +746,7 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
         *        do not support receiving pause frames).
         *      3:  Both Rx and Tx flow control (symmetric) are enabled.
         */
-       switch (hw->fc.type) {
+       switch (hw->fc.current_mode) {
        case e1000_fc_none:
                /* Flow control completely disabled by a software over-ride. */
                txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
@@ -906,7 +928,7 @@ s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
         * ability to transmit pause frames is not enabled, then these
         * registers will be set to 0.
         */
-       if (hw->fc.type & e1000_fc_tx_pause) {
+       if (hw->fc.current_mode & e1000_fc_tx_pause) {
                /*
                 * We need to set up the Receive Threshold high and low water
                 * marks as well as (optionally) enabling the transmission of
@@ -945,7 +967,7 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw)
         * receive flow control.
         *
         * The "Case" statement below enables/disable flow control
-        * according to the "hw->fc.type" parameter.
+        * according to the "hw->fc.current_mode" parameter.
         *
         * The possible values of the "fc" parameter are:
         *      0:  Flow control is completely disabled
@@ -956,9 +978,9 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw)
         *      3:  Both Rx and Tx flow control (symmetric) is enabled.
         *  other:  No other values should be possible at this point.
         */
-       hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);
+       hw_dbg(hw, "hw->fc.current_mode = %u\n", hw->fc.current_mode);
 
-       switch (hw->fc.type) {
+       switch (hw->fc.current_mode) {
        case e1000_fc_none:
                ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
                break;
@@ -1102,11 +1124,11 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                         * ONLY. Hence, we must now check to see if we need to
                         * turn OFF  the TRANSMISSION of PAUSE frames.
                         */
-                       if (hw->fc.original_type == e1000_fc_full) {
-                               hw->fc.type = e1000_fc_full;
+                       if (hw->fc.requested_mode == e1000_fc_full) {
+                               hw->fc.current_mode = e1000_fc_full;
                                hw_dbg(hw, "Flow Control = FULL.\r\n");
                        } else {
-                               hw->fc.type = e1000_fc_rx_pause;
+                               hw->fc.current_mode = e1000_fc_rx_pause;
                                hw_dbg(hw, "Flow Control = "
                                         "RX PAUSE frames only.\r\n");
                        }
@@ -1124,7 +1146,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                          (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                          (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                          (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                       hw->fc.type = e1000_fc_tx_pause;
+                       hw->fc.current_mode = e1000_fc_tx_pause;
                        hw_dbg(hw, "Flow Control = Tx PAUSE frames only.\r\n");
                }
                /*
@@ -1140,14 +1162,14 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                         (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                         !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                         (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                       hw->fc.type = e1000_fc_rx_pause;
+                       hw->fc.current_mode = e1000_fc_rx_pause;
                        hw_dbg(hw, "Flow Control = Rx PAUSE frames only.\r\n");
                } else {
                        /*
                         * Per the IEEE spec, at this point flow control
                         * should be disabled.
                         */
-                       hw->fc.type = e1000_fc_none;
+                       hw->fc.current_mode = e1000_fc_none;
                        hw_dbg(hw, "Flow Control = NONE.\r\n");
                }
 
@@ -1163,7 +1185,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                }
 
                if (duplex == HALF_DUPLEX)
-                       hw->fc.type = e1000_fc_none;
+                       hw->fc.current_mode = e1000_fc_none;
 
                /*
                 * Now we call a subroutine to actually force the MAC