ixgbe: Refactor overtemp event handling
authorJedrzej Jagielski <jedrzej.jagielski@intel.com>
Mon, 18 Dec 2023 10:39:25 +0000 (11:39 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Feb 2024 20:14:35 +0000 (20:14 +0000)
[ Upstream commit 6c1b4af8c1b20c70dde01e58381685d6a4a1d2c8 ]

Currently ixgbe driver is notified of overheating events
via internal IXGBE_ERR_OVERTEMP error code.

Change the approach for handle_lasi() to use freshly introduced
is_overtemp function parameter which set when such event occurs.
Change check_overtemp() to bool and return true if overtemp
event occurs.

Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c

index f7c6482..9d4f808 100644 (file)
@@ -2756,7 +2756,6 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        u32 eicr = adapter->interrupt_event;
-       s32 rc;
 
        if (test_bit(__IXGBE_DOWN, &adapter->state))
                return;
@@ -2790,14 +2789,13 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
                }
 
                /* Check if this is not due to overtemp */
-               if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP)
+               if (!hw->phy.ops.check_overtemp(hw))
                        return;
 
                break;
        case IXGBE_DEV_ID_X550EM_A_1G_T:
        case IXGBE_DEV_ID_X550EM_A_1G_T_L:
-               rc = hw->phy.ops.check_overtemp(hw);
-               if (rc != IXGBE_ERR_OVERTEMP)
+               if (!hw->phy.ops.check_overtemp(hw))
                        return;
                break;
        default:
@@ -7938,7 +7936,7 @@ static void ixgbe_service_timer(struct timer_list *t)
 static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 status;
+       bool overtemp;
 
        if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT))
                return;
@@ -7948,11 +7946,9 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter)
        if (!hw->phy.ops.handle_lasi)
                return;
 
-       status = hw->phy.ops.handle_lasi(&adapter->hw);
-       if (status != IXGBE_ERR_OVERTEMP)
-               return;
-
-       e_crit(drv, "%s\n", ixgbe_overheat_msg);
+       hw->phy.ops.handle_lasi(&adapter->hw, &overtemp);
+       if (overtemp)
+               e_crit(drv, "%s\n", ixgbe_overheat_msg);
 }
 
 static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
index 7c0a1a0..930dc50 100644 (file)
@@ -408,8 +408,7 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
                return status;
 
        /* Don't reset PHY if it's shut down due to overtemp. */
-       if (!hw->phy.reset_if_overtemp &&
-           (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
+       if (!hw->phy.reset_if_overtemp && hw->phy.ops.check_overtemp(hw))
                return 0;
 
        /* Blocked by MNG FW so bail */
@@ -2748,22 +2747,24 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
  *  @hw: pointer to hardware structure
  *
  *  Checks if the LASI temp alarm status was triggered due to overtemp
+ *
+ *  Return true when an overtemp event detected, otherwise false.
  **/
-s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
+bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
 {
        u16 phy_data = 0;
+       u32 status;
 
        if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
-               return 0;
+               return false;
 
        /* Check that the LASI temp alarm status was triggered */
-       hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
-                            MDIO_MMD_PMAPMD, &phy_data);
-
-       if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
-               return 0;
+       status = hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
+                                     MDIO_MMD_PMAPMD, &phy_data);
+       if (status)
+               return false;
 
-       return IXGBE_ERR_OVERTEMP;
+       return !!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM);
 }
 
 /** ixgbe_set_copper_phy_power - Control power for copper phy
index 6544c45..ef72729 100644 (file)
@@ -155,7 +155,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
 s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
                                        u16 *list_offset,
                                        u16 *data_offset);
-s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw);
+bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw);
 s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                u8 dev_addr, u8 *data);
 s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
index 4b19b12..61b9774 100644 (file)
@@ -3509,10 +3509,10 @@ struct ixgbe_phy_operations {
        s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
        s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
        s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
-       s32 (*check_overtemp)(struct ixgbe_hw *);
+       bool (*check_overtemp)(struct ixgbe_hw *);
        s32 (*set_phy_power)(struct ixgbe_hw *, bool on);
        s32 (*enter_lplu)(struct ixgbe_hw *);
-       s32 (*handle_lasi)(struct ixgbe_hw *hw);
+       s32 (*handle_lasi)(struct ixgbe_hw *hw, bool *);
        s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
                                      u8 *value);
        s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
index 19de265..fe2d2d2 100644 (file)
@@ -600,8 +600,10 @@ static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
        if (rc)
                return rc;
+
        if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
-               return IXGBE_ERR_OVERTEMP;
+               return -EIO;
+
        return 0;
 }
 
@@ -2369,18 +2371,18 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
  * @hw: pointer to hardware structure
  * @lsc: pointer to boolean flag which indicates whether external Base T
  *      PHY interrupt is lsc
+ * @is_overtemp: indicate whether an overtemp event encountered
  *
  * Determime if external Base T PHY interrupt cause is high temperature
  * failure alarm or link status change.
- *
- * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
- * failure alarm, else return PHY access status.
  **/
-static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
+static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc,
+                                      bool *is_overtemp)
 {
        u32 status;
        u16 reg;
 
+       *is_overtemp = false;
        *lsc = false;
 
        /* Vendor alarm triggered */
@@ -2412,7 +2414,8 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
        if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
                /* power down the PHY in case the PHY FW didn't already */
                ixgbe_set_copper_phy_power(hw, false);
-               return IXGBE_ERR_OVERTEMP;
+               *is_overtemp = true;
+               return -EIO;
        }
        if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
                /*  device fault alarm triggered */
@@ -2426,7 +2429,8 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
                if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
                        /* power down the PHY in case the PHY FW didn't */
                        ixgbe_set_copper_phy_power(hw, false);
-                       return IXGBE_ERR_OVERTEMP;
+                       *is_overtemp = true;
+                       return -EIO;
                }
        }
 
@@ -2462,12 +2466,12 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
  **/
 static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
 {
+       bool lsc, overtemp;
        u32 status;
        u16 reg;
-       bool lsc;
 
        /* Clear interrupt flags */
-       status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
+       status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, &overtemp);
 
        /* Enable link status change alarm */
 
@@ -2546,21 +2550,20 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
 /**
  * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
  * @hw: pointer to hardware structure
+ * @is_overtemp: indicate whether an overtemp event encountered
  *
  * Handle external Base T PHY interrupt. If high temperature
  * failure alarm then return error, else if link status change
  * then setup internal/external PHY link
- *
- * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
- * failure alarm, else return PHY access status.
  **/
-static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
+static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw,
+                                         bool *is_overtemp)
 {
        struct ixgbe_phy_info *phy = &hw->phy;
        bool lsc;
        u32 status;
 
-       status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
+       status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, is_overtemp);
        if (status)
                return status;
 
@@ -3188,21 +3191,23 @@ static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
 /**
  * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
  * @hw: pointer to hardware structure
+ *
+ * Return true when an overtemp event detected, otherwise false.
  */
-static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
+static bool ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
 {
        u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
        s32 rc;
 
        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
        if (rc)
-               return rc;
+               return false;
 
        if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
                ixgbe_shutdown_fw_phy(hw);
-               return IXGBE_ERR_OVERTEMP;
+               return true;
        }
-       return 0;
+       return false;
 }
 
 /**