ixgbe: Refactor overtemp event handling
[ 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>
This commit is contained in:
parent
e16c254f60
commit
f8bccfa175
@ -2766,7 +2766,6 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
|
|||||||
{
|
{
|
||||||
struct ixgbe_hw *hw = &adapter->hw;
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
u32 eicr = adapter->interrupt_event;
|
u32 eicr = adapter->interrupt_event;
|
||||||
s32 rc;
|
|
||||||
|
|
||||||
if (test_bit(__IXGBE_DOWN, &adapter->state))
|
if (test_bit(__IXGBE_DOWN, &adapter->state))
|
||||||
return;
|
return;
|
||||||
@ -2800,14 +2799,13 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is not due to overtemp */
|
/* 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;
|
return;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IXGBE_DEV_ID_X550EM_A_1G_T:
|
case IXGBE_DEV_ID_X550EM_A_1G_T:
|
||||||
case IXGBE_DEV_ID_X550EM_A_1G_T_L:
|
case IXGBE_DEV_ID_X550EM_A_1G_T_L:
|
||||||
rc = hw->phy.ops.check_overtemp(hw);
|
if (!hw->phy.ops.check_overtemp(hw))
|
||||||
if (rc != IXGBE_ERR_OVERTEMP)
|
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -7844,7 +7842,7 @@ static void ixgbe_service_timer(struct timer_list *t)
|
|||||||
static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter)
|
static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct ixgbe_hw *hw = &adapter->hw;
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
u32 status;
|
bool overtemp;
|
||||||
|
|
||||||
if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT))
|
if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT))
|
||||||
return;
|
return;
|
||||||
@ -7854,11 +7852,9 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter)
|
|||||||
if (!hw->phy.ops.handle_lasi)
|
if (!hw->phy.ops.handle_lasi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
status = hw->phy.ops.handle_lasi(&adapter->hw);
|
hw->phy.ops.handle_lasi(&adapter->hw, &overtemp);
|
||||||
if (status != IXGBE_ERR_OVERTEMP)
|
if (overtemp)
|
||||||
return;
|
e_crit(drv, "%s\n", ixgbe_overheat_msg);
|
||||||
|
|
||||||
e_crit(drv, "%s\n", ixgbe_overheat_msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
|
static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
|
||||||
|
@ -405,8 +405,7 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
/* Don't reset PHY if it's shut down due to overtemp. */
|
/* Don't reset PHY if it's shut down due to overtemp. */
|
||||||
if (!hw->phy.reset_if_overtemp &&
|
if (!hw->phy.reset_if_overtemp && hw->phy.ops.check_overtemp(hw))
|
||||||
(IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Blocked by MNG FW so bail */
|
/* Blocked by MNG FW so bail */
|
||||||
@ -2617,22 +2616,24 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
|
|||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
*
|
*
|
||||||
* Checks if the LASI temp alarm status was triggered due to overtemp
|
* 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;
|
u16 phy_data = 0;
|
||||||
|
u32 status;
|
||||||
|
|
||||||
if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
|
if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* Check that the LASI temp alarm status was triggered */
|
/* Check that the LASI temp alarm status was triggered */
|
||||||
hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
|
status = hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
|
||||||
MDIO_MMD_PMAPMD, &phy_data);
|
MDIO_MMD_PMAPMD, &phy_data);
|
||||||
|
if (status)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
|
return !!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM);
|
||||||
return 0;
|
|
||||||
|
|
||||||
return IXGBE_ERR_OVERTEMP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ixgbe_set_copper_phy_power - Control power for copper phy
|
/** ixgbe_set_copper_phy_power - Control power for copper phy
|
||||||
|
@ -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,
|
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
|
||||||
u16 *list_offset,
|
u16 *list_offset,
|
||||||
u16 *data_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,
|
s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||||
u8 dev_addr, u8 *data);
|
u8 dev_addr, u8 *data);
|
||||||
s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
|
s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
|
||||||
|
@ -3505,10 +3505,10 @@ struct ixgbe_phy_operations {
|
|||||||
s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
|
s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
|
||||||
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
|
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
|
||||||
s32 (*write_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 (*set_phy_power)(struct ixgbe_hw *, bool on);
|
||||||
s32 (*enter_lplu)(struct ixgbe_hw *);
|
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,
|
s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
|
||||||
u8 *value);
|
u8 *value);
|
||||||
s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
|
s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
|
||||||
|
@ -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);
|
rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
|
if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
|
||||||
return IXGBE_ERR_OVERTEMP;
|
return -EIO;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2319,18 +2321,18 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
|
|||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @lsc: pointer to boolean flag which indicates whether external Base T
|
* @lsc: pointer to boolean flag which indicates whether external Base T
|
||||||
* PHY interrupt is lsc
|
* PHY interrupt is lsc
|
||||||
|
* @is_overtemp: indicate whether an overtemp event encountered
|
||||||
*
|
*
|
||||||
* Determime if external Base T PHY interrupt cause is high temperature
|
* Determime if external Base T PHY interrupt cause is high temperature
|
||||||
* failure alarm or link status change.
|
* 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;
|
u32 status;
|
||||||
u16 reg;
|
u16 reg;
|
||||||
|
|
||||||
|
*is_overtemp = false;
|
||||||
*lsc = false;
|
*lsc = false;
|
||||||
|
|
||||||
/* Vendor alarm triggered */
|
/* Vendor alarm triggered */
|
||||||
@ -2362,7 +2364,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) {
|
if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
|
||||||
/* power down the PHY in case the PHY FW didn't already */
|
/* power down the PHY in case the PHY FW didn't already */
|
||||||
ixgbe_set_copper_phy_power(hw, false);
|
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) {
|
if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
|
||||||
/* device fault alarm triggered */
|
/* device fault alarm triggered */
|
||||||
@ -2376,7 +2379,8 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
|
|||||||
if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
|
if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
|
||||||
/* power down the PHY in case the PHY FW didn't */
|
/* power down the PHY in case the PHY FW didn't */
|
||||||
ixgbe_set_copper_phy_power(hw, false);
|
ixgbe_set_copper_phy_power(hw, false);
|
||||||
return IXGBE_ERR_OVERTEMP;
|
*is_overtemp = true;
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2412,12 +2416,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)
|
static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
|
bool lsc, overtemp;
|
||||||
u32 status;
|
u32 status;
|
||||||
u16 reg;
|
u16 reg;
|
||||||
bool lsc;
|
|
||||||
|
|
||||||
/* Clear interrupt flags */
|
/* 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 */
|
/* Enable link status change alarm */
|
||||||
|
|
||||||
@ -2496,21 +2500,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
|
* ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
|
* @is_overtemp: indicate whether an overtemp event encountered
|
||||||
*
|
*
|
||||||
* Handle external Base T PHY interrupt. If high temperature
|
* Handle external Base T PHY interrupt. If high temperature
|
||||||
* failure alarm then return error, else if link status change
|
* failure alarm then return error, else if link status change
|
||||||
* then setup internal/external PHY link
|
* 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;
|
struct ixgbe_phy_info *phy = &hw->phy;
|
||||||
bool lsc;
|
bool lsc;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
|
||||||
status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
|
status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, is_overtemp);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@ -3138,21 +3141,23 @@ static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
|
|||||||
/**
|
/**
|
||||||
* ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
|
* ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
|
||||||
* @hw: pointer to hardware structure
|
* @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 };
|
u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
|
||||||
s32 rc;
|
s32 rc;
|
||||||
|
|
||||||
rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
|
rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return false;
|
||||||
|
|
||||||
if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
|
if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
|
||||||
ixgbe_shutdown_fw_phy(hw);
|
ixgbe_shutdown_fw_phy(hw);
|
||||||
return IXGBE_ERR_OVERTEMP;
|
return true;
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user