Merge branch 'x86-txt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[profile/ivi/kernel-x86-ivi.git] / drivers / net / e1000e / ich8lan.c
index 9e23f50..99df2ab 100644 (file)
@@ -338,9 +338,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
-       u32 gfpreg;
-       u32 sector_base_addr;
-       u32 sector_end_addr;
+       u32 gfpreg, sector_base_addr, sector_end_addr;
        u16 i;
 
        /* Can't read flash registers if the register set isn't mapped. */
@@ -446,6 +444,95 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
        return 0;
 }
 
+/**
+ *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks to see of the link status of the hardware has changed.  If a
+ *  change in link status has been detected, then we read the PHY registers
+ *  to get the current speed/duplex if link exists.
+ **/
+static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       s32 ret_val;
+       bool link;
+
+       /*
+        * We only want to go out to the PHY registers to see if Auto-Neg
+        * has completed and/or if our link status has changed.  The
+        * get_link_status flag is set upon receiving a Link Status
+        * Change or Rx Sequence Error interrupt.
+        */
+       if (!mac->get_link_status) {
+               ret_val = 0;
+               goto out;
+       }
+
+       if (hw->mac.type == e1000_pchlan) {
+               ret_val = e1000e_write_kmrn_reg(hw,
+                                                  E1000_KMRNCTRLSTA_K1_CONFIG,
+                                                  E1000_KMRNCTRLSTA_K1_ENABLE);
+               if (ret_val)
+                       goto out;
+       }
+
+       /*
+        * First we want to see if the MII Status Register reports
+        * link.  If so, then we want to get the current speed/duplex
+        * of the PHY.
+        */
+       ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
+       if (ret_val)
+               goto out;
+
+       if (!link)
+               goto out; /* No link detected */
+
+       mac->get_link_status = false;
+
+       if (hw->phy.type == e1000_phy_82578) {
+               ret_val = e1000_link_stall_workaround_hv(hw);
+               if (ret_val)
+                       goto out;
+       }
+
+       /*
+        * Check if there was DownShift, must be checked
+        * immediately after link-up
+        */
+       e1000e_check_downshift(hw);
+
+       /*
+        * If we are forcing speed/duplex, then we simply return since
+        * we have already determined whether we have link or not.
+        */
+       if (!mac->autoneg) {
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       /*
+        * Auto-Neg is enabled.  Auto Speed Detection takes care
+        * of MAC speed/duplex configuration.  So we only need to
+        * configure Collision Distance in the MAC.
+        */
+       e1000e_config_collision_dist(hw);
+
+       /*
+        * Configure Flow Control now that Auto-Neg has completed.
+        * First, we need to restore the desired flow control
+        * settings because we may have had to re-autoneg with a
+        * different link partner.
+        */
+       ret_val = e1000e_config_fc_after_link_up(hw);
+       if (ret_val)
+               hw_dbg(hw, "Error configuring flow control\n");
+
+out:
+       return ret_val;
+}
+
 static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
@@ -490,8 +577,8 @@ static DEFINE_MUTEX(nvm_mutex);
  **/
 static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 {
-       u32 extcnf_ctrl;
-       u32 timeout = PHY_CFG_TIMEOUT;
+       u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
+       s32 ret_val = 0;
 
        might_sleep();
 
@@ -499,28 +586,46 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
        while (timeout) {
                extcnf_ctrl = er32(EXTCNF_CTRL);
+               if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
+                       break;
 
-               if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) {
-                       extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
-                       ew32(EXTCNF_CTRL, extcnf_ctrl);
+               mdelay(1);
+               timeout--;
+       }
+
+       if (!timeout) {
+               hw_dbg(hw, "SW/FW/HW has locked the resource for too long.\n");
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       timeout = PHY_CFG_TIMEOUT * 2;
+
+       extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
+       ew32(EXTCNF_CTRL, extcnf_ctrl);
+
+       while (timeout) {
+               extcnf_ctrl = er32(EXTCNF_CTRL);
+               if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
+                       break;
 
-                       extcnf_ctrl = er32(EXTCNF_CTRL);
-                       if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
-                               break;
-               }
                mdelay(1);
                timeout--;
        }
 
        if (!timeout) {
-               hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
+               hw_dbg(hw, "Failed to acquire the semaphore.\n");
                extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
                ew32(EXTCNF_CTRL, extcnf_ctrl);
-               mutex_unlock(&nvm_mutex);
-               return -E1000_ERR_CONFIG;
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
        }
 
-       return 0;
+out:
+       if (ret_val)
+               mutex_unlock(&nvm_mutex);
+
+       return ret_val;
 }
 
 /**
@@ -694,6 +799,38 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 }
 
 /**
+ *  e1000_lan_init_done_ich8lan - Check for PHY config completion
+ *  @hw: pointer to the HW structure
+ *
+ *  Check the appropriate indication the MAC has finished configuring the
+ *  PHY after a software reset.
+ **/
+static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw)
+{
+       u32 data, loop = E1000_ICH8_LAN_INIT_TIMEOUT;
+
+       /* Wait for basic configuration completes before proceeding */
+       do {
+               data = er32(STATUS);
+               data &= E1000_STATUS_LAN_INIT_DONE;
+               udelay(100);
+       } while ((!data) && --loop);
+
+       /*
+        * If basic configuration is incomplete before the above loop
+        * count reaches 0, loading the configuration from NVM will
+        * leave the PHY in a bad state possibly resulting in no link.
+        */
+       if (loop == 0)
+               hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n");
+
+       /* Clear the Init Done bit for the next init event */
+       data = er32(STATUS);
+       data &= ~E1000_STATUS_LAN_INIT_DONE;
+       ew32(STATUS, data);
+}
+
+/**
  *  e1000_phy_hw_reset_ich8lan - Performs a PHY reset
  *  @hw: pointer to the HW structure
  *
@@ -707,13 +844,15 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
        u32 i;
        u32 data, cnf_size, cnf_base_addr, sw_cfg_mask;
        s32 ret_val;
-       u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT;
        u16 word_addr, reg_data, reg_addr, phy_page = 0;
 
        ret_val = e1000e_phy_hw_reset_generic(hw);
        if (ret_val)
                return ret_val;
 
+       /* Allow time for h/w to get to a quiescent state after reset */
+       mdelay(10);
+
        if (hw->mac.type == e1000_pchlan) {
                ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
                if (ret_val)
@@ -741,26 +880,8 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
                if (!(data & sw_cfg_mask))
                        return 0;
 
-               /* Wait for basic configuration completes before proceeding*/
-               do {
-                       data = er32(STATUS);
-                       data &= E1000_STATUS_LAN_INIT_DONE;
-                       udelay(100);
-               } while ((!data) && --loop);
-
-               /*
-                * If basic configuration is incomplete before the above loop
-                * count reaches 0, loading the configuration from NVM will
-                * leave the PHY in a bad state possibly resulting in no link.
-                */
-               if (loop == 0) {
-                       hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n");
-               }
-
-               /* Clear the Init Done bit for the next init event */
-               data = er32(STATUS);
-               data &= ~E1000_STATUS_LAN_INIT_DONE;
-               ew32(STATUS, data);
+               /* Wait for basic configuration completes before proceeding */
+               e1000_lan_init_done_ich8lan(hw);
 
                /*
                 * Make sure HW does not configure LCD from PHY
@@ -961,12 +1082,14 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
                phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
                ew32(PHY_CTRL, phy_ctrl);
 
+               if (phy->type != e1000_phy_igp_3)
+                       return 0;
+
                /*
                 * Call gig speed drop workaround on LPLU before accessing
                 * any PHY registers
                 */
-               if ((hw->mac.type == e1000_ich8lan) &&
-                   (hw->phy.type == e1000_phy_igp_3))
+               if (hw->mac.type == e1000_ich8lan)
                        e1000e_gig_downshift_workaround_ich8lan(hw);
 
                /* When LPLU is enabled, we should disable SmartSpeed */
@@ -979,6 +1102,9 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
                phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
                ew32(PHY_CTRL, phy_ctrl);
 
+               if (phy->type != e1000_phy_igp_3)
+                       return 0;
+
                /*
                 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
                 * during Dx states where the power conservation is most
@@ -1038,6 +1164,10 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
        if (!active) {
                phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
                ew32(PHY_CTRL, phy_ctrl);
+
+               if (phy->type != e1000_phy_igp_3)
+                       return 0;
+
                /*
                 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
                 * during Dx states where the power conservation is most
@@ -1073,12 +1203,14 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
                phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
                ew32(PHY_CTRL, phy_ctrl);
 
+               if (phy->type != e1000_phy_igp_3)
+                       return 0;
+
                /*
                 * Call gig speed drop workaround on LPLU before accessing
                 * any PHY registers
                 */
-               if ((hw->mac.type == e1000_ich8lan) &&
-                   (hw->phy.type == e1000_phy_igp_3))
+               if (hw->mac.type == e1000_ich8lan)
                        e1000e_gig_downshift_workaround_ich8lan(hw);
 
                /* When LPLU is enabled, we should disable SmartSpeed */
@@ -1175,7 +1307,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
        struct e1000_nvm_info *nvm = &hw->nvm;
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
        u32 act_offset;
-       s32 ret_val;
+       s32 ret_val = 0;
        u32 bank = 0;
        u16 i, word;
 
@@ -1190,12 +1322,15 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                goto out;
 
        ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
-       if (ret_val)
-               goto release;
+       if (ret_val) {
+               hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n");
+               bank = 0;
+       }
 
        act_offset = (bank) ? nvm->flash_bank_size : 0;
        act_offset += offset;
 
+       ret_val = 0;
        for (i = 0; i < words; i++) {
                if ((dev_spec->shadow_ram) &&
                    (dev_spec->shadow_ram[offset+i].modified)) {
@@ -1210,7 +1345,6 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                }
        }
 
-release:
        e1000_release_swflag_ich8lan(hw);
 
 out:
@@ -1461,7 +1595,6 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
-       s32 ret_val;
        u16 i;
 
        if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
@@ -1470,17 +1603,11 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                return -E1000_ERR_NVM;
        }
 
-       ret_val = e1000_acquire_swflag_ich8lan(hw);
-       if (ret_val)
-               return ret_val;
-
        for (i = 0; i < words; i++) {
                dev_spec->shadow_ram[offset+i].modified = 1;
                dev_spec->shadow_ram[offset+i].value = data[i];
        }
 
-       e1000_release_swflag_ich8lan(hw);
-
        return 0;
 }
 
@@ -1521,8 +1648,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
         */
        ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
        if (ret_val) {
-               e1000_release_swflag_ich8lan(hw);
-               goto out;
+               hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n");
+               bank = 0;
        }
 
        if (bank == 0) {
@@ -1905,19 +2032,15 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
                break;
        case 1:
                sector_size = ICH_FLASH_SEG_SIZE_4K;
-               iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K;
+               iteration = 1;
                break;
        case 2:
-               if (hw->mac.type == e1000_ich9lan) {
-                       sector_size = ICH_FLASH_SEG_SIZE_8K;
-                       iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K;
-               } else {
-                       return -E1000_ERR_NVM;
-               }
+               sector_size = ICH_FLASH_SEG_SIZE_8K;
+               iteration = 1;
                break;
        case 3:
                sector_size = ICH_FLASH_SEG_SIZE_64K;
-               iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K;
+               iteration = 1;
                break;
        default:
                return -E1000_ERR_NVM;
@@ -1925,7 +2048,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 
        /* Start with the base address, then add the sector offset. */
        flash_linear_addr = hw->nvm.flash_base_addr;
-       flash_linear_addr += (bank) ? (sector_size * iteration) : 0;
+       flash_linear_addr += (bank) ? flash_bank_size : 0;
 
        for (j = 0; j < iteration ; j++) {
                do {
@@ -2143,6 +2266,12 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        ctrl = er32(CTRL);
 
        if (!e1000_check_reset_block(hw)) {
+               /* Clear PHY Reset Asserted bit */
+               if (hw->mac.type >= e1000_pchlan) {
+                       u32 status = er32(STATUS);
+                       ew32(STATUS, status & ~E1000_STATUS_PHYRA);
+               }
+
                /*
                 * PHY HW reset requires MAC CORE reset at the same
                 * time to make sure the interface between MAC and the
@@ -2156,23 +2285,34 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        ew32(CTRL, (ctrl | E1000_CTRL_RST));
        msleep(20);
 
-       if (!ret_val) {
-               /* release the swflag because it is not reset by
-                * hardware reset
-                */
+       if (!ret_val)
                e1000_release_swflag_ich8lan(hw);
-       }
 
-       ret_val = e1000e_get_auto_rd_done(hw);
-       if (ret_val) {
-               /*
-                * When auto config read does not complete, do not
-                * return with an error. This can happen in situations
-                * where there is no eeprom and prevents getting link.
-                */
-               hw_dbg(hw, "Auto Read Done did not complete\n");
+       if (ctrl & E1000_CTRL_PHY_RST)
+               ret_val = hw->phy.ops.get_cfg_done(hw);
+
+       if (hw->mac.type >= e1000_ich10lan) {
+               e1000_lan_init_done_ich8lan(hw);
+       } else {
+               ret_val = e1000e_get_auto_rd_done(hw);
+               if (ret_val) {
+                       /*
+                        * When auto config read does not complete, do not
+                        * return with an error. This can happen in situations
+                        * where there is no eeprom and prevents getting link.
+                        */
+                       hw_dbg(hw, "Auto Read Done did not complete\n");
+               }
        }
 
+       /*
+        * For PCH, this write will make sure that any noise
+        * will be detected as a CRC error and be dropped rather than show up
+        * as a bad packet to the DMA engine.
+        */
+       if (hw->mac.type == e1000_pchlan)
+               ew32(CRC_OFFSET, 0x65656565);
+
        ew32(IMC, 0xffffffff);
        icr = er32(ICR);
 
@@ -2222,6 +2362,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
        for (i = 0; i < mac->mta_reg_count; i++)
                E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
 
+       /*
+        * The 82578 Rx buffer will stall if wakeup is enabled in host and
+        * the ME.  Reading the BM_WUC register will clear the host wakeup bit.
+        * Reset the phy after disabling host wakeup to reset the Rx buffer.
+        */
+       if (hw->phy.type == e1000_phy_82578) {
+               hw->phy.ops.read_phy_reg(hw, BM_WUC, &i);
+               ret_val = e1000_phy_hw_reset_ich8lan(hw);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /* Setup link and flow control */
        ret_val = e1000_setup_link_ich8lan(hw);
 
@@ -2254,16 +2406,6 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
        ew32(CTRL_EXT, ctrl_ext);
 
        /*
-        * The 82578 Rx buffer will stall if wakeup is enabled in host and
-        * the ME.  Reading the BM_WUC register will clear the host wakeup bit.
-        * Reset the phy after disabling host wakeup to reset the Rx buffer.
-        */
-       if (hw->phy.type == e1000_phy_82578) {
-               e1e_rphy(hw, BM_WUC, &i);
-               e1000e_phy_hw_reset_generic(hw);
-       }
-
-       /*
         * Clear all of the statistics registers (clear on read).  It is
         * important that we do this after we have tried to establish link
         * because the symbol error count will increment wildly if there
@@ -2485,6 +2627,14 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
        if (ret_val)
                return ret_val;
 
+       if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) {
+               ret_val = e1000e_write_kmrn_reg(hw,
+                                                 E1000_KMRNCTRLSTA_K1_CONFIG,
+                                                 E1000_KMRNCTRLSTA_K1_DISABLE);
+               if (ret_val)
+                       return ret_val;
+       }
+
        if ((hw->mac.type == e1000_ich8lan) &&
            (hw->phy.type == e1000_phy_igp_3) &&
            (*speed == SPEED_1000)) {
@@ -2850,6 +3000,16 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
 {
        u32 bank = 0;
 
+       if (hw->mac.type >= e1000_pchlan) {
+               u32 status = er32(STATUS);
+
+               if (status & E1000_STATUS_PHYRA)
+                       ew32(STATUS, status & ~E1000_STATUS_PHYRA);
+               else
+                       hw_dbg(hw,
+                              "PHY Reset Asserted not set - needs delay\n");
+       }
+
        e1000e_get_cfg_done(hw);
 
        /* If EEPROM is not marked present, init the IGP 3 PHY manually */
@@ -2921,7 +3081,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
 static struct e1000_mac_operations ich8_mac_ops = {
        .id_led_init            = e1000e_id_led_init,
        .check_mng_mode         = e1000_check_mng_mode_ich8lan,
-       .check_for_link         = e1000e_check_for_copper_link,
+       .check_for_link         = e1000_check_for_copper_link_ich8lan,
        /* cleanup_led dependent on mac type */
        .clear_hw_cntrs         = e1000_clear_hw_cntrs_ich8lan,
        .get_bus_info           = e1000_get_bus_info_ich8lan,