net/virtio: fix MAC address read
[dpdk.git] / drivers / net / ixgbe / base / ixgbe_x540.c
index af29b13..0e51813 100644 (file)
@@ -81,8 +81,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
        /* PHY */
        phy->ops.init = ixgbe_init_phy_ops_generic;
        phy->ops.reset = NULL;
-       if (!ixgbe_mng_present(hw))
-               phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
+       phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
 
        /* MAC */
        mac->ops.reset_hw = ixgbe_reset_hw_X540;
@@ -100,6 +99,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
        mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic;
        mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540;
        mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540;
+       mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540;
        mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
        mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
 
@@ -137,8 +137,8 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
         * ARC supported; valid only if manageability features are
         * enabled.
         */
-       mac->arc_subsystem_valid = (IXGBE_READ_REG(hw, IXGBE_FWSM) &
-                                  IXGBE_FWSM_MODE_MASK) ? true : false;
+       mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
+                                    & IXGBE_FWSM_MODE_MASK);
 
        hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
 
@@ -208,6 +208,7 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
 {
        s32 status;
        u32 ctrl, i;
+       u32 swfw_mask = hw->phy.phy_semaphore_mask;
 
        DEBUGFUNC("ixgbe_reset_hw_X540");
 
@@ -220,10 +221,17 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
        ixgbe_clear_tx_pending(hw);
 
 mac_reset_top:
+       status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+       if (status != IXGBE_SUCCESS) {
+               ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+                       "semaphore failed with %d", status);
+               return IXGBE_ERR_SWFW_SYNC;
+       }
        ctrl = IXGBE_CTRL_RST;
        ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
        IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
        IXGBE_WRITE_FLUSH(hw);
+       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 
        /* Poll for reset bit to self-clear indicating reset is complete */
        for (i = 0; i < 10; i++) {
@@ -269,12 +277,16 @@ mac_reset_top:
 
        /* Add the SAN MAC address to the RAR only if it's a valid address */
        if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
-               hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-                                   hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
                /* Save the SAN MAC RAR index */
                hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+               hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+                                   hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+               /* clear VMDq pool/queue selection for this RAR */
+               hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+                                      IXGBE_CLEAR_VMDQ_ALL);
+
                /* Reserve the last RAR for the SAN MAC address */
                hw->mac.num_rar_entries--;
        }
@@ -317,9 +329,9 @@ out:
  *
  *  Determines physical layer capabilities of the current configuration.
  **/
-u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
+u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
 {
-       u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
        u16 ext_ability = 0;
 
        DEBUGFUNC("ixgbe_get_supported_physical_layer_X540");
@@ -355,7 +367,7 @@ s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
                eeprom->semaphore_delay = 10;
                eeprom->type = ixgbe_flash;
 
-               eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+               eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
                eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
                                    IXGBE_EEC_SIZE_SHIFT);
                eeprom->word_size = 1 << (eeprom_size +
@@ -487,7 +499,6 @@ s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
        u16 length = 0;
        u16 pointer = 0;
        u16 word = 0;
-       u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM;
        u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
 
        /* Do not use hw->eeprom.ops.read because we do not want to take
@@ -497,14 +508,15 @@ s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
 
        DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
 
-       /* Include 0x0-0x3F in the checksum */
-       for (i = 0; i <= checksum_last_word; i++) {
+       /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the
+        * checksum itself
+        */
+       for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
                if (ixgbe_read_eerd_generic(hw, i, &word)) {
                        DEBUGOUT("EEPROM read failed\n");
                        return IXGBE_ERR_EEPROM;
                }
-               if (i != IXGBE_EEPROM_CHECKSUM)
-                       checksum += word;
+               checksum += word;
        }
 
        /* Include all data from pointers 0x3, 0x6-0xE.  This excludes the
@@ -680,8 +692,8 @@ s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
                goto out;
        }
 
-       flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP;
-       IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
+       flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
 
        status = ixgbe_poll_flash_update_done_X540(hw);
        if (status == IXGBE_SUCCESS)
@@ -690,11 +702,11 @@ s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
                DEBUGOUT("Flash update time out\n");
 
        if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) {
-               flup = IXGBE_READ_REG(hw, IXGBE_EEC);
+               flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
 
                if (flup & IXGBE_EEC_SEC1VAL) {
                        flup |= IXGBE_EEC_FLUP;
-                       IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
+                       IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
                }
 
                status = ixgbe_poll_flash_update_done_X540(hw);
@@ -723,7 +735,7 @@ STATIC s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
        DEBUGFUNC("ixgbe_poll_flash_update_done_X540");
 
        for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
-               reg = IXGBE_READ_REG(hw, IXGBE_EEC);
+               reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
                if (reg & IXGBE_EEC_FLUDONE) {
                        status = IXGBE_SUCCESS;
                        break;
@@ -771,15 +783,17 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
                /* SW NVM semaphore bit is used for access to all
                 * SW_FW_SYNC bits (not just NVM)
                 */
-               if (ixgbe_get_swfw_sync_semaphore(hw))
+               if (ixgbe_get_swfw_sync_semaphore(hw)) {
+                       DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n");
                        return IXGBE_ERR_SWFW_SYNC;
+               }
 
-               swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+               swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
                if (!(swfw_sync & (fwmask | swmask | hwmask))) {
                        swfw_sync |= swmask;
-                       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
+                       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw),
+                                       swfw_sync);
                        ixgbe_release_swfw_sync_semaphore(hw);
-                       msec_delay(5);
                        return IXGBE_SUCCESS;
                }
                /* Firmware currently using resource (fwmask), hardware
@@ -794,6 +808,7 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
        if (swmask == IXGBE_GSSR_SW_MNG_SM) {
                ERROR_REPORT1(IXGBE_ERROR_POLLING,
                             "Failed to get SW only semaphore");
+               DEBUGOUT("Failed to get SW only semaphore, returning IXGBE_ERR_SWFW_SYNC\n");
                return IXGBE_ERR_SWFW_SYNC;
        }
 
@@ -802,12 +817,14 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
         * of the requested resource(s) while ignoring the corresponding FW/HW
         * bits in the SW_FW_SYNC register.
         */
-       if (ixgbe_get_swfw_sync_semaphore(hw))
+       if (ixgbe_get_swfw_sync_semaphore(hw)) {
+               DEBUGOUT("Failed to get NVM sempahore and register semaphore while forcefully ignoring FW sempahore bit(s) and setting SW semaphore bit(s), returning IXGBE_ERR_SWFW_SYNC\n");
                return IXGBE_ERR_SWFW_SYNC;
-       swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+       }
+       swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
        if (swfw_sync & (fwmask | hwmask)) {
                swfw_sync |= swmask;
-               IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
+               IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
                ixgbe_release_swfw_sync_semaphore(hw);
                msec_delay(5);
                return IXGBE_SUCCESS;
@@ -825,9 +842,11 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
                        rmask |= IXGBE_GSSR_I2C_MASK;
                ixgbe_release_swfw_sync_X540(hw, rmask);
                ixgbe_release_swfw_sync_semaphore(hw);
+               DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n");
                return IXGBE_ERR_SWFW_SYNC;
        }
        ixgbe_release_swfw_sync_semaphore(hw);
+       DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n");
 
        return IXGBE_ERR_SWFW_SYNC;
 }
@@ -851,12 +870,12 @@ void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
                swmask |= mask & IXGBE_GSSR_I2C_MASK;
        ixgbe_get_swfw_sync_semaphore(hw);
 
-       swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+       swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
        swfw_sync &= ~swmask;
-       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
+       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
 
        ixgbe_release_swfw_sync_semaphore(hw);
-       msec_delay(5);
+       msec_delay(2);
 }
 
 /**
@@ -880,7 +899,7 @@ STATIC s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
                 * If the SMBI bit is 0 when we read it, then the bit will be
                 * set and we have the semaphore
                 */
-               swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+               swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
                if (!(swsm & IXGBE_SWSM_SMBI)) {
                        status = IXGBE_SUCCESS;
                        break;
@@ -891,7 +910,7 @@ STATIC s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
        /* Now get the semaphore between SW/FW through the REGSMP bit */
        if (status == IXGBE_SUCCESS) {
                for (i = 0; i < timeout; i++) {
-                       swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+                       swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
                        if (!(swsm & IXGBE_SWFW_REGSMP))
                                break;
 
@@ -931,17 +950,36 @@ STATIC void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
 
        /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
 
-       swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
-       swsm &= ~IXGBE_SWSM_SMBI;
-       IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
-
-       swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+       swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
        swsm &= ~IXGBE_SWFW_REGSMP;
-       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm);
+       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm);
+
+       swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
+       swsm &= ~IXGBE_SWSM_SMBI;
+       IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm);
 
        IXGBE_WRITE_FLUSH(hw);
 }
 
+/**
+ *  ixgbe_init_swfw_sync_X540 - Release hardware semaphore
+ *  @hw: pointer to hardware structure
+ *
+ *  This function reset hardware semaphore bits for a semaphore that may
+ *  have be left locked due to a catastrophic failure.
+ **/
+void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
+{
+       /* First try to grab the semaphore but we don't need to bother
+        * looking to see whether we got the lock or  not since we do
+        * the same thing regardless of whether we got the lock or not.
+        * We got the lock - we release it.
+        * We timeout trying to get the lock - we force its release.
+        */
+       ixgbe_get_swfw_sync_semaphore(hw);
+       ixgbe_release_swfw_sync_semaphore(hw);
+}
+
 /**
  * ixgbe_blink_led_start_X540 - Blink LED based on index.
  * @hw: pointer to hardware structure
@@ -959,6 +997,9 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
 
        DEBUGFUNC("ixgbe_blink_led_start_X540");
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        /*
         * Link should be up in order for the blink bit in the LED control
         * register to work. Force link and speed in the MAC if link is down.
@@ -993,6 +1034,9 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
        u32 macc_reg;
        u32 ledctl_reg;
 
+       if (index > 3)
+               return IXGBE_ERR_PARAM;
+
        DEBUGFUNC("ixgbe_blink_led_stop_X540");
 
        /* Restore the LED to its default value. */