mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
Merge branch 'intel-wired-lan-driver-updates-2026-04-20-ice'
Jacob Keller says: ==================== Intel Wired LAN Driver Updates 2026-04-20 (ice) Since this is a set of related fixes for just the ice driver, Jake provides the following description for the series: We recently ran into a nasty corner case issue with a customer operating E825C cards seeing some strange behavior with missing Tx timestamps. During the course of debugging. This series contains a few fixes found during this debugging process. The primary issue discovered in the investigation is a misconfiguration of the E825C PHY timestamp interrupt register, PHY_REG_TS_INT_CONFIG. This register is responsible for programming the Tx timestamp behavior of a PHY port. The driver programs two values here: a threshold for when to interrupt and whether the interrupt is enabled. The threshold value is used by hardware to determine when to trigger a Tx timestamp interrupt. The interrupt cause for the port is raised when the number of outstanding timestamps in the PHY port timestamp memory meets the threshold. The interrupt cause is not cleared until the number of outstanding timestamps drops *below* the threshold. It is considered a misconfiguration if the threshold is programmed to 0. If the interrupt is enabled while the threshold is zero, hardware will raise the interrupt cause at the next time it checks. Once raised, the interrupt cause for the port will never lower, since you cannot have fewer than zero outstanding timestamps. Worse, the timestamp status for the port will remain high even if the PHY_REG_TS_INT_CONFIG is reprogrammed with a new threshold. The PHY is a separate hardware block from the MAC, and thus the interrupt status for the port will remain high even if you reset the device MAC with a PF reset, CORE reset, or GLOBAL reset. PHY ports are connected together into quads. Each quad muxes the PHY interrupt status for the 4 ports on the quad together before connecting that to the MACs miscellaneous interrupt vector. As a result, if a single PHY port in the quad is stuck, no timestamp interrupts will be generated for any timestamp on any port on that quad. The ice driver never directly writes a value of 0 for the threshold. Indeed, the desired behavior is to set the threshold to 1, so that interrupts are generated as soon as a single timestamp is captured. Unfortunately, it turns out that for the E825C PHY, programming the threshold and enable bit in the same write may cause a race in the PHY timestamp block. The PHY may "see" the interrupt as enabled first before it sees the threshold value. If the previous threshold value is zero (such as when the register is initialized to zero at a cold power on), the hardware may race with programming the threshold and set the PHY interrupt status to high as described above. The first patch in this series corrects that programming order, ensuring that the threshold is always written first in a separate transaction from enabling the interrupt bit. Additionally, an explicit check against writing a 0 is added to make it clear to future readers that writing 0 to the threshold while enabling the interrupt is not safe. The PHY timestamp block does not reset with the MAC, and seems to only reset during cold power on. This makes recovery from the faulty configuration difficult. To address this, perform an explicit reset of the PHY PTP block during initialization. This is achieved by writing the PHY_REG_GLOBAL register. This performs a PHY soft reset, which completely resets the timestamp block. This includes clearing the timestamp memory, the PHY timestamp interrupt status, and the PHY PTP counter. A soft reset of all ports on the device is done as part of ice_ptp_init_phc() during early initialization of the PTP functionality by the PTP clock owner, prior to programming each PHY. The ice_ptp_init_phc() function is called at driver init and during reinitialization after all forms of device reset. This ensures that the driver begins operation at a clean slate, rather than carrying over the stale and potentially buggy configuration of a previous driver. While attempting to root cause the issue with the PHY timestamp interrupt, we also discovered that the driver incorrectly assumes that it is operating on E822 hardware when reading the PHY timestamp memory status registers in a few places. This includes the check at the end of the interrupt handler, as well as the check done inside the PTP auxiliary function. This prevented the driver from detecting waiting timestamps on ports other than the first two. Finally, the ice_ptp_read_tx_hwstamp_status_eth56g() function was discovered to only read the timestamp interrupt status value from the first quad due to mistaking the port index for a PHY quad index. This resulted in reporting the timestamp status for the second quad as identical to the first quad instead of properly reporting its value. This is a minor fix since the function currently is only used for diagnostic purposes and does not impact driver decision logic. ==================== Link: https://patch.msgid.link/20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-0-bc2240f42251@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
9d146a5d10
|
|
@ -2710,7 +2710,7 @@ static bool ice_any_port_has_timestamps(struct ice_pf *pf)
|
|||
bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* Check software indicator */
|
||||
switch (pf->ptp.tx_interrupt_mode) {
|
||||
|
|
@ -2731,16 +2731,19 @@ bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf)
|
|||
}
|
||||
|
||||
/* Check hardware indicator */
|
||||
for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
|
||||
u64 tstamp_ready = 0;
|
||||
int err;
|
||||
|
||||
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
if (err || tstamp_ready)
|
||||
return true;
|
||||
ret = ice_check_phy_tx_tstamp_ready(hw);
|
||||
if (ret < 0) {
|
||||
dev_dbg(ice_pf_to_dev(pf), "Unable to read PHY Tx timestamp ready bitmap, err %d\n",
|
||||
ret);
|
||||
/* Stop triggering IRQs if we're unable to read PHY */
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
/* ice_check_phy_tx_tstamp_ready() returns 1 if there are timestamps
|
||||
* available, 0 if there are no waiting timestamps, and a negative
|
||||
* value if there was an error (which we checked for above).
|
||||
*/
|
||||
return ret > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2824,8 +2827,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
|||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
bool trigger_oicr = false;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (!pf->ptp.port.tx.has_ready_bitmap)
|
||||
return;
|
||||
|
|
@ -2833,21 +2835,11 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
|||
if (!ice_pf_src_tmr_owned(pf))
|
||||
return;
|
||||
|
||||
for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
if (!err && tstamp_ready) {
|
||||
trigger_oicr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (trigger_oicr) {
|
||||
/* Trigger a software interrupt, to ensure this data
|
||||
* gets processed.
|
||||
*/
|
||||
ret = ice_check_phy_tx_tstamp_ready(hw);
|
||||
if (ret < 0) {
|
||||
dev_dbg(dev, "PTP periodic task unable to read PHY timestamp ready bitmap, err %d\n",
|
||||
ret);
|
||||
} else if (ret) {
|
||||
dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
|
||||
|
||||
wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
|
|
|
|||
|
|
@ -377,6 +377,31 @@ static void ice_ptp_cfg_sync_delay(const struct ice_hw *hw, u32 delay)
|
|||
* The following functions operate on devices with the ETH 56G PHY.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ice_ptp_init_phc_e825c - Perform E825C specific PHC initialization
|
||||
* @hw: pointer to HW struct
|
||||
*
|
||||
* Perform E825C-specific PTP hardware clock initialization steps.
|
||||
*
|
||||
* Return: 0 on success, or a negative error value on failure.
|
||||
*/
|
||||
static int ice_ptp_init_phc_e825c(struct ice_hw *hw)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Soft reset all ports, to ensure everything is at a clean state */
|
||||
for (int port = 0; port < hw->ptp.num_lports; port++) {
|
||||
err = ice_ptp_phy_soft_reset_eth56g(hw, port);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to soft reset port %d, err %d\n",
|
||||
port, err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_get_dest_dev_e825 - get destination PHY for given port number
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -1847,6 +1872,8 @@ static int ice_phy_cfg_mac_eth56g(struct ice_hw *hw, u8 port)
|
|||
* @ena: enable or disable interrupt
|
||||
* @threshold: interrupt threshold
|
||||
*
|
||||
* The threshold cannot be 0 while the interrupt is enabled.
|
||||
*
|
||||
* Configure TX timestamp interrupt for the specified port
|
||||
*
|
||||
* Return:
|
||||
|
|
@ -1858,19 +1885,45 @@ int ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold)
|
|||
int err;
|
||||
u32 val;
|
||||
|
||||
if (ena && !threshold)
|
||||
return -EINVAL;
|
||||
|
||||
err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val &= ~PHY_TS_INT_CONFIG_ENA_M;
|
||||
if (ena) {
|
||||
val |= PHY_TS_INT_CONFIG_ENA_M;
|
||||
val &= ~PHY_TS_INT_CONFIG_THRESHOLD_M;
|
||||
val |= FIELD_PREP(PHY_TS_INT_CONFIG_THRESHOLD_M, threshold);
|
||||
} else {
|
||||
val &= ~PHY_TS_INT_CONFIG_ENA_M;
|
||||
err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG,
|
||||
val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP,
|
||||
"Failed to update 'threshold' PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n",
|
||||
port, !!ena, threshold);
|
||||
return err;
|
||||
}
|
||||
val |= PHY_TS_INT_CONFIG_ENA_M;
|
||||
}
|
||||
|
||||
return ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, val);
|
||||
err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP,
|
||||
"Failed to update 'ena' PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n",
|
||||
port, !!ena, threshold);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, &val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP,
|
||||
"Failed to read PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n",
|
||||
port, !!ena, threshold);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2115,6 +2168,35 @@ int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_check_phy_tx_tstamp_ready_eth56g - Check Tx memory status for all ports
|
||||
* @hw: pointer to the HW struct
|
||||
*
|
||||
* Check the PHY_REG_TX_MEMORY_STATUS for all ports. A set bit indicates
|
||||
* a waiting timestamp.
|
||||
*
|
||||
* Return: 1 if any port has at least one timestamp ready bit set,
|
||||
* 0 otherwise, and a negative error code if unable to read the bitmap.
|
||||
*/
|
||||
static int ice_check_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw)
|
||||
{
|
||||
int port;
|
||||
|
||||
for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
err = ice_get_phy_tx_tstamp_ready(hw, port, &tstamp_ready);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (tstamp_ready)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_read_tx_hwtstamp_status_eth56g - Get TX timestamp status
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -2137,13 +2219,19 @@ int ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status)
|
|||
*ts_status = 0;
|
||||
|
||||
for (phy = 0; phy < params->num_phys; phy++) {
|
||||
u8 port;
|
||||
int err;
|
||||
|
||||
err = ice_read_phy_eth56g(hw, phy, PHY_PTP_INT_STATUS, &status);
|
||||
/* ice_read_phy_eth56g expects a port index, so use the first
|
||||
* port of the PHY
|
||||
*/
|
||||
port = phy * hw->ptp.ports_per_phy;
|
||||
|
||||
err = ice_read_phy_eth56g(hw, port, PHY_PTP_INT_STATUS, &status);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*ts_status |= (status & mask) << (phy * hw->ptp.ports_per_phy);
|
||||
*ts_status |= (status & mask) << port;
|
||||
}
|
||||
|
||||
ice_debug(hw, ICE_DBG_PTP, "PHY interrupt err: %x\n", *ts_status);
|
||||
|
|
@ -2151,6 +2239,69 @@ int ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_phy_soft_reset_eth56g - Perform a PHY soft reset on ETH56G
|
||||
* @hw: pointer to the HW structure
|
||||
* @port: PHY port number
|
||||
*
|
||||
* Trigger a soft reset of the ETH56G PHY by toggling the soft reset
|
||||
* bit in the PHY global register. The reset sequence consists of:
|
||||
* 1. Clearing the soft reset bit
|
||||
* 2. Asserting the soft reset bit
|
||||
* 3. Clearing the soft reset bit again
|
||||
*
|
||||
* Short delays are inserted between each step to allow the hardware
|
||||
* to settle. This provides a controlled way to reinitialize the PHY
|
||||
* without requiring a full device reset.
|
||||
*
|
||||
* Return: 0 on success, or a negative error code on failure when
|
||||
* reading or writing the PHY register.
|
||||
*/
|
||||
int ice_ptp_phy_soft_reset_eth56g(struct ice_hw *hw, u8 port)
|
||||
{
|
||||
u32 global_val;
|
||||
int err;
|
||||
|
||||
err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, &global_val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_REG_GLOBAL for port %d, err %d\n",
|
||||
port, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
global_val &= ~PHY_REG_GLOBAL_SOFT_RESET_M;
|
||||
ice_debug(hw, ICE_DBG_PTP, "Clearing soft reset bit for port %d, val: 0x%x\n",
|
||||
port, global_val);
|
||||
err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n",
|
||||
port, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
usleep_range(5000, 6000);
|
||||
|
||||
global_val |= PHY_REG_GLOBAL_SOFT_RESET_M;
|
||||
ice_debug(hw, ICE_DBG_PTP, "Set soft reset bit for port %d, val: 0x%x\n",
|
||||
port, global_val);
|
||||
err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n",
|
||||
port, err);
|
||||
return err;
|
||||
}
|
||||
usleep_range(5000, 6000);
|
||||
|
||||
global_val &= ~PHY_REG_GLOBAL_SOFT_RESET_M;
|
||||
ice_debug(hw, ICE_DBG_PTP, "Clear soft reset bit for port %d, val: 0x%x\n",
|
||||
port, global_val);
|
||||
err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val);
|
||||
if (err)
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n",
|
||||
port, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_phy_tx_tstamp_ready_eth56g - Read the Tx memory status register
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -4202,6 +4353,35 @@ ice_get_phy_tx_tstamp_ready_e82x(struct ice_hw *hw, u8 quad, u64 *tstamp_ready)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_check_phy_tx_tstamp_ready_e82x - Check Tx memory status for all quads
|
||||
* @hw: pointer to the HW struct
|
||||
*
|
||||
* Check the Q_REG_TX_MEMORY_STATUS for all quads. A set bit indicates
|
||||
* a waiting timestamp.
|
||||
*
|
||||
* Return: 1 if any quad has at least one timestamp ready bit set,
|
||||
* 0 otherwise, and a negative error value if unable to read the bitmap.
|
||||
*/
|
||||
static int ice_check_phy_tx_tstamp_ready_e82x(struct ice_hw *hw)
|
||||
{
|
||||
int quad;
|
||||
|
||||
for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
err = ice_get_phy_tx_tstamp_ready(hw, quad, &tstamp_ready);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (tstamp_ready)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_phy_cfg_intr_e82x - Configure TX timestamp interrupt
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -4755,6 +4935,23 @@ ice_get_phy_tx_tstamp_ready_e810(struct ice_hw *hw, u8 port, u64 *tstamp_ready)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_check_phy_tx_tstamp_ready_e810 - Check Tx memory status register
|
||||
* @hw: pointer to the HW struct
|
||||
*
|
||||
* The E810 devices do not have a Tx memory status register. Note this is
|
||||
* intentionally different behavior from ice_get_phy_tx_tstamp_ready_e810
|
||||
* which always says that all bits are ready. This function is called in cases
|
||||
* where code will trigger interrupts if timestamps are waiting, and should
|
||||
* not be called for E810 hardware.
|
||||
*
|
||||
* Return: 0.
|
||||
*/
|
||||
static int ice_check_phy_tx_tstamp_ready_e810(struct ice_hw *hw)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* E810 SMA functions
|
||||
*
|
||||
* The following functions operate specifically on E810 hardware and are used
|
||||
|
|
@ -5009,6 +5206,21 @@ static void ice_get_phy_tx_tstamp_ready_e830(const struct ice_hw *hw, u8 port,
|
|||
*tstamp_ready |= rd32(hw, E830_PRTMAC_TS_TX_MEM_VALID_L);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_check_phy_tx_tstamp_ready_e830 - Check Tx memory status register
|
||||
* @hw: pointer to the HW struct
|
||||
*
|
||||
* Return: 1 if the device has waiting timestamps, 0 otherwise.
|
||||
*/
|
||||
static int ice_check_phy_tx_tstamp_ready_e830(struct ice_hw *hw)
|
||||
{
|
||||
u64 tstamp_ready;
|
||||
|
||||
ice_get_phy_tx_tstamp_ready_e830(hw, 0, &tstamp_ready);
|
||||
|
||||
return !!tstamp_ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_init_phy_e830 - initialize PHY parameters
|
||||
* @ptp: pointer to the PTP HW struct
|
||||
|
|
@ -5564,7 +5776,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
|||
case ICE_MAC_GENERIC:
|
||||
return ice_ptp_init_phc_e82x(hw);
|
||||
case ICE_MAC_GENERIC_3K_E825:
|
||||
return 0;
|
||||
return ice_ptp_init_phc_e825c(hw);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
@ -5601,6 +5813,33 @@ int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_check_phy_tx_tstamp_ready - Check PHY Tx timestamp memory status
|
||||
* @hw: pointer to the HW struct
|
||||
*
|
||||
* Check the PHY for Tx timestamp memory status on all ports. If you need to
|
||||
* see individual timestamp status for each index, use
|
||||
* ice_get_phy_tx_tstamp_ready() instead.
|
||||
*
|
||||
* Return: 1 if any port has timestamps available, 0 if there are no timestamps
|
||||
* available, and a negative error code on failure.
|
||||
*/
|
||||
int ice_check_phy_tx_tstamp_ready(struct ice_hw *hw)
|
||||
{
|
||||
switch (hw->mac_type) {
|
||||
case ICE_MAC_E810:
|
||||
return ice_check_phy_tx_tstamp_ready_e810(hw);
|
||||
case ICE_MAC_E830:
|
||||
return ice_check_phy_tx_tstamp_ready_e830(hw);
|
||||
case ICE_MAC_GENERIC:
|
||||
return ice_check_phy_tx_tstamp_ready_e82x(hw);
|
||||
case ICE_MAC_GENERIC_3K_E825:
|
||||
return ice_check_phy_tx_tstamp_ready_eth56g(hw);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_cgu_get_pin_desc_e823 - get pin description array
|
||||
* @hw: pointer to the hw struct
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ void ice_ptp_reset_ts_memory(struct ice_hw *hw);
|
|||
int ice_ptp_init_phc(struct ice_hw *hw);
|
||||
void ice_ptp_init_hw(struct ice_hw *hw);
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready);
|
||||
int ice_check_phy_tx_tstamp_ready(struct ice_hw *hw);
|
||||
int ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port,
|
||||
enum ice_ptp_tmr_cmd configured_cmd);
|
||||
|
||||
|
|
@ -374,6 +375,7 @@ int ice_stop_phy_timer_eth56g(struct ice_hw *hw, u8 port, bool soft_reset);
|
|||
int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port);
|
||||
int ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold);
|
||||
int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port);
|
||||
int ice_ptp_phy_soft_reset_eth56g(struct ice_hw *hw, u8 port);
|
||||
|
||||
#define ICE_ETH56G_NOMINAL_INCVAL 0x140000000ULL
|
||||
#define ICE_ETH56G_NOMINAL_PCS_REF_TUS 0x100000000ULL
|
||||
|
|
@ -676,6 +678,9 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw)
|
|||
#define ICE_P0_GNSS_PRSNT_N BIT(4)
|
||||
|
||||
/* ETH56G PHY register addresses */
|
||||
#define PHY_REG_GLOBAL 0x0
|
||||
#define PHY_REG_GLOBAL_SOFT_RESET_M BIT(11)
|
||||
|
||||
/* Timestamp PHY incval registers */
|
||||
#define PHY_REG_TIMETUS_L 0x8
|
||||
#define PHY_REG_TIMETUS_U 0xC
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user