Cache the primary ice_hw pointer to ensure consistency between calls (both parts of a value will be read from the same NAC). ice_get_primary_hw() will never return NULL, but during the ctrl_pf cleanup there may be a case when one call will return the pointer to the ctrl_pf->hw and the subsequent one - to the pf->hw which generally are not the same. Struct ice_hw is embedded in the struct ice_pf so it is protected by the same critical section - no additional synchronization is needed. Fixes: e2193f9f9ec9 ("ice: enable timesync operation on 2xNAC E825 devices") Signed-off-by: Sergey Temerkhanov Reviewed-by: Aleksandr Loktionov Reviewed-by: Arkadiusz Kubalewski Tested-by: Frederick Lawler --- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index 9ea72d5f59cc..a2b7f709f3c0 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -4,6 +4,7 @@ #include #include #include +#include "ice.h" #include "ice_common.h" #include "ice_ptp_hw.h" #include "ice_ptp_consts.h" @@ -1957,10 +1958,14 @@ static int ice_read_phy_and_phc_time_eth56g(struct ice_hw *hw, u8 port, zo = rd32(hw, GLTSYN_SHTIME_0(tmr_idx)); lo = rd32(hw, GLTSYN_SHTIME_L(tmr_idx)); } else { + struct ice_hw *pri_hw; + guard(rcu)(); - zo = rd32(ice_get_primary_hw(pf), GLTSYN_SHTIME_0(tmr_idx)); - lo = rd32(ice_get_primary_hw(pf), GLTSYN_SHTIME_L(tmr_idx)); + pri_hw = ice_get_primary_hw(pf); + + zo = rd32(pri_hw, GLTSYN_SHTIME_0(tmr_idx)); + lo = rd32(pri_hw, GLTSYN_SHTIME_L(tmr_idx)); } *phc_time = (u64)lo << 32 | zo; @@ -2128,10 +2133,14 @@ int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port) lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx)); hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx)); } else { + struct ice_hw *pri_hw; + guard(rcu)(); - lo = rd32(ice_get_primary_hw(pf), GLTSYN_INCVAL_L(tmr_idx)); - hi = rd32(ice_get_primary_hw(pf), GLTSYN_INCVAL_H(tmr_idx)); + pri_hw = ice_get_primary_hw(pf); + + lo = rd32(pri_hw, GLTSYN_INCVAL_L(tmr_idx)); + hi = rd32(pri_hw, GLTSYN_INCVAL_H(tmr_idx)); } incval = (u64)hi << 32 | lo; -- 2.53.0