@@ -1981,6 +1981,38 @@ int ice_phy_cfg_rx_offset_eth56g(struct ice_hw *hw, u8 port)
return ice_write_phy_reg_eth56g(hw, port, PHY_REG_RX_OFFSET_READY, 1);
}
+/**
+ * ice_ptp_clear_phy_offset_ready_eth56g - Clear PHY OFFSET_READY registers
+ * @hw: pointer to the HW struct
+ *
+ * Clear PHY TX_/RX_OFFSET_READY registers, effectively marking all transmitted
+ * and received timestamps as invalid.
+ */
+static int ice_ptp_clear_phy_offset_ready_eth56g(struct ice_hw *hw)
+{
+ u8 port;
+
+ for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
+ int err;
+
+ err = ice_write_phy_reg_eth56g(hw, port,
+ PHY_REG_TX_OFFSET_READY, 0);
+ if (err) {
+ ice_warn(hw, "Failed to clear PHY TX_OFFSET_READY register\n");
+ return err;
+ }
+
+ err = ice_write_phy_reg_eth56g(hw, port,
+ PHY_REG_RX_OFFSET_READY, 0);
+ if (err) {
+ ice_warn(hw, "Failed to clear PHY RX_OFFSET_READY register\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
/**
* ice_read_phy_and_phc_time_eth56g - Simultaneously capture PHC and PHY time
* @hw: pointer to the HW struct
@@ -4068,6 +4100,36 @@ int ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port)
return 0;
}
+/**
+ * ice_ptp_clear_phy_offset_ready_e822 - Clear PHY TX_/RX_OFFSET_READY registers
+ * @hw: pointer to the HW struct
+ *
+ * Clear PHY TX_/RX_OFFSET_READY registers, effectively marking all transmitted
+ * and received timestamps as invalid.
+ */
+static int ice_ptp_clear_phy_offset_ready_e822(struct ice_hw *hw)
+{
+ u8 port;
+
+ for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
+ int err;
+
+ err = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 0);
+ if (err) {
+ ice_warn(hw, "Failed to clear PHY TX_OFFSET_READY register\n");
+ return err;
+ }
+
+ err = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 0);
+ if (err) {
+ ice_warn(hw, "Failed to clear PHY RX_OFFSET_READY register\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
/**
* ice_phy_cfg_fixed_rx_offset_e822 - Configure fixed Rx offset for bypass mode
* @hw: pointer to the HW struct
@@ -5801,6 +5863,28 @@ ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
return ice_ptp_tmr_cmd(hw, ICE_PTP_ADJ_TIME_AT_TIME, true);
}
+/**
+ * ice_ptp_clear_phy_offset_ready - Clear PHY TX_/RX_OFFSET_READY registers
+ * @hw: pointer to the HW struct
+ *
+ * Clear PHY TX_/RX_OFFSET_READY registers, effectively marking all transmitted
+ * and received timestamps as invalid.
+ */
+int ice_ptp_clear_phy_offset_ready(struct ice_hw *hw)
+{
+ switch (hw->phy_cfg) {
+ case ICE_PHY_ETH56G:
+ return ice_ptp_clear_phy_offset_ready_eth56g(hw);
+ case ICE_PHY_E830:
+ case ICE_PHY_E810:
+ return 0;
+ case ICE_PHY_E822:
+ return ice_ptp_clear_phy_offset_ready_e822(hw);
+ default:
+ return ICE_ERR_NOT_SUPPORTED;
+ }
+}
+
/**
* ice_read_phy_tstamp - Read a PHY timestamp from the timestamp block
* @hw: pointer to the HW struct
@@ -137,6 +137,7 @@ int ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval);
int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq);
int
ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj);
+int ice_ptp_clear_phy_offset_ready(struct ice_hw *hw);
int
ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp);
int