[v2,142/148] net/ice/base: rework multiple functions

Message ID c5ab854829203318627e6c654e1770447afca6dc.1718204529.git.anatoly.burakov@intel.com (mailing list archive)
State Superseded
Delegated to: Bruce Richardson
Headers
Series Update net/ice base driver to latest upstream snapshot |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Anatoly Burakov June 12, 2024, 3:02 p.m. UTC
  From: Ian Stokes <ian.stokes@intel.com>

Multpiple functions that have been implemented, rework and removed are contained
in this patch. Specifaclly the patch combines the following commits:

- Implement TX interrupt enablement functions.

  Introduce functions enabling/disabling TX TS interrupts for the E822 and ETH56G
  PHYs

- Remove bypass modeRemove bypass mode.

  Previous implementation switches between bypass and Vernier mode dynamically.
  However bypass mode should be removed due to low precision.

- Make Tx and Rx vernier offset calibration independent. The Tx and Rx
  calibration and timestamp generation blocks are independent. It is not required
  to wait for both to complete before programming the offsets. Instead, we can
  program the offset for each independently as soon as they are ready.

  Remove the ice_phy_calc_vernier_e822 function. Modify the
  ice_phy_cfg_tx_offset_e822 and ice_phy_cfg_rx_offset_e822 functions with the
  following additions:

 a) Check the relevant P_REG_*_OR bit first and do nothing if the offset has
    already been programmed

 b) Check the P_REG_*_OV_STATUS bit to determine if the offset status is ready,
    meaning that the hardware vernier calibration steps have completed. Return
    ICE_ERR_NOT_READY if the offset is not yet read.

    The driver can now simply call ice_phy_cfg_rx_offset_e822
    and ice_phy_cfg_tx_offset_e822 periodically until the
    offsets have been programmed.

    In this way, the Tx and Rx blocks will be enabled
    independently without each waiting on the other block to
    complete. This can enable faster calibration on some setups
    which have a low rate of either Tx or Rx traffic.

Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Signed-off-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Siddaraju DH <siddaraju.dh@intel.com>
Signed-off-by: Ian Stokes <ian.stokes@intel.com>
---
 drivers/net/ice/base/ice_ptp_hw.c | 282 +++++++++++-------------------
 drivers/net/ice/base/ice_ptp_hw.h |  10 +-
 drivers/net/ice/ice_ethdev.c      |   2 +-
 3 files changed, 112 insertions(+), 182 deletions(-)
  

Patch

diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c
index b351784f4a..f7d397ae51 100644
--- a/drivers/net/ice/base/ice_ptp_hw.c
+++ b/drivers/net/ice/base/ice_ptp_hw.c
@@ -2040,6 +2040,41 @@  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_phy_cfg_intr_eth56g - Configure TX timestamp interrupt
+ * @hw: pointer to the HW struct
+ * @port: the timestamp port
+ * @ena: enable or disable interrupt
+ * @threshold: interrupt threshold
+ *
+ * Configure TX timestamp interrupt for the specified port
+ */
+
+int
+ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold)
+{
+	int err;
+	u32 val;
+
+	err = ice_read_phy_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG,
+				      &val);
+	if (err)
+		return err;
+
+	if (ena) {
+		val |= PHY_TS_INT_CONFIG_ENA_M;
+		val &= ~PHY_TS_INT_CONFIG_THRESHOLD_M;
+		val |= ((threshold << PHY_TS_INT_CONFIG_THRESHOLD_S) &
+			PHY_TS_INT_CONFIG_THRESHOLD_M);
+	} else {
+		val &= ~PHY_TS_INT_CONFIG_ENA_M;
+	}
+
+	err = ice_write_phy_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG,
+				       val);
+	return err;
+}
+
 /**
  * ice_ptp_clear_phy_offset_ready_eth56g - Clear PHY OFFSET_READY registers
  * @hw: pointer to the HW struct
@@ -2228,7 +2263,6 @@  ice_stop_phy_timer_eth56g(struct ice_hw *hw, u8 port, bool soft_reset)
  * ice_start_phy_timer_eth56g - Start the PHY clock timer
  * @hw: pointer to the HW struct
  * @port: the PHY port to start
- * @bypass: unused, for compatibility
  *
  * Start the clock of a PHY port. This must be done as part of the flow to
  * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
@@ -2236,7 +2270,7 @@  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, bool bypass)
+ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port)
 {
 	int err;
 	u32 lo, hi;
@@ -3837,6 +3871,28 @@  int ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port)
 	enum ice_ptp_fec_mode fec_mode;
 	u64 total_offset, val;
 	int err;
+	u32 reg;
+
+	/* Nothing to do if we've already programmed the offset */
+	err = ice_read_phy_reg_e822(hw, port, P_REG_TX_OR, &reg);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OR for port %u, err %d\n",
+			  port, err);
+		return err;
+	}
+
+	if (reg)
+		return 0;
+
+	err = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &reg);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, err %d\n",
+			  port, err);
+		return err;
+	}
+
+	if (!(reg & P_REG_TX_OV_STATUS_OV_M))
+		return ICE_ERR_NOT_READY;
 
 	err = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
 	if (err)
@@ -3894,47 +3950,6 @@  int ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port)
 	return 0;
 }
 
-/**
- * ice_phy_cfg_fixed_tx_offset_e822 - Configure Tx offset for bypass mode
- * @hw: pointer to the HW struct
- * @port: the PHY port to configure
- *
- * Calculate and program the fixed Tx offset, and indicate that the offset is
- * ready. This can be used when operating in bypass mode.
- */
-static int
-ice_phy_cfg_fixed_tx_offset_e822(struct ice_hw *hw, u8 port)
-{
-	enum ice_ptp_link_spd link_spd;
-	enum ice_ptp_fec_mode fec_mode;
-	int err;
-	u64 total_offset;
-
-	err = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
-	if (err)
-		return err;
-
-	total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
-
-	/* Program the fixed Tx offset into the P_REG_TOTAL_TX_OFFSET_L
-	 * register, then indicate that the Tx offset is ready. After this,
-	 * timestamps will be enabled.
-	 *
-	 * Note that this skips including the more precise offsets generated
-	 * by the Vernier calibration.
-	 */
-	err = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
-					    total_offset);
-	if (err)
-		return err;
-
-	err = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
-	if (err)
-		return err;
-
-	return 0;
-}
-
 /**
  * ice_phy_calc_pmd_adj_e822 - Calculate PMD adjustment for Rx
  * @hw: pointer to the HW struct
@@ -4157,6 +4172,28 @@  int ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port)
 	enum ice_ptp_fec_mode fec_mode;
 	u64 total_offset, pmd, val;
 	int err;
+	u32 reg;
+
+	/* Nothing to do if we've already programmed the offset */
+	err = ice_read_phy_reg_e822(hw, port, P_REG_RX_OR, &reg);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OR for port %u, err %d\n",
+			  port, err);
+		return err;
+	}
+
+	if (reg)
+		return 0;
+
+	err = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &reg);
+	if (err) {
+		ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, err %d\n",
+			  port, err);
+		return err;
+	}
+
+	if (!(reg & P_REG_RX_OV_STATUS_OV_M))
+		return ICE_ERR_NOT_READY;
 
 	err = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
 	if (err)
@@ -4253,47 +4290,6 @@  static int ice_ptp_clear_phy_offset_ready_e822(struct ice_hw *hw)
 	return 0;
 }
 
-/**
- * ice_phy_cfg_fixed_rx_offset_e822 - Configure fixed Rx offset for bypass mode
- * @hw: pointer to the HW struct
- * @port: the PHY port to configure
- *
- * Calculate and program the fixed Rx offset, and indicate that the offset is
- * ready. This can be used when operating in bypass mode.
- */
-static int
-ice_phy_cfg_fixed_rx_offset_e822(struct ice_hw *hw, u8 port)
-{
-	enum ice_ptp_link_spd link_spd;
-	enum ice_ptp_fec_mode fec_mode;
-	int err;
-	u64 total_offset;
-
-	err = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
-	if (err)
-		return err;
-
-	total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
-
-	/* Program the fixed Rx offset into the P_REG_TOTAL_RX_OFFSET_L
-	 * register, then indicate that the Rx offset is ready. After this,
-	 * timestamps will be enabled.
-	 *
-	 * Note that this skips including the more precise offsets generated
-	 * by Vernier calibration.
-	 */
-	err = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
-					    total_offset);
-	if (err)
-		return err;
-
-	err = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
-	if (err)
-		return err;
-
-	return 0;
-}
-
 /**
  * ice_read_phy_and_phc_time_e822 - Simultaneously capture PHC and PHY time
  * @hw: pointer to the HW struct
@@ -4474,19 +4470,14 @@  ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset)
  * ice_start_phy_timer_e822 - Start the PHY clock timer
  * @hw: pointer to the HW struct
  * @port: the PHY port to start
- * @bypass: if true, start the PHY in bypass mode
  *
  * Start the clock of a PHY port. This must be done as part of the flow to
  * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
  * initialized or when link speed changes.
  *
- * Bypass mode enables timestamps immediately without waiting for Vernier
- * calibration to complete. Hardware will still continue taking Vernier
- * measurements on Tx or Rx of packets, but they will not be applied to
- * timestamps. Use ice_phy_exit_bypass_e822 to exit bypass mode once hardware
- * has completed offset calculation.
+ * Hardware will take Vernier measurements on Tx or Rx of packets.
  */
-int ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass)
+int ice_start_phy_timer_e822(struct ice_hw *hw, u8 port)
 {
 	u32 lo, hi, val;
 	u64 incval;
@@ -4567,23 +4558,6 @@  int ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass)
 	if (err)
 		return err;
 
-	if (bypass) {
-		val |= P_REG_PS_BYPASS_MODE_M;
-		/* Enter BYPASS mode, enabling timestamps immediately. */
-		err = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
-		if (err)
-			return err;
-
-		/* Program the fixed Tx offset */
-		err = ice_phy_cfg_fixed_tx_offset_e822(hw, port);
-		if (err)
-			return err;
-
-		/* Program the fixed Rx offset */
-		err = ice_phy_cfg_fixed_rx_offset_e822(hw, port);
-		if (err)
-			return err;
-	}
 
 	ice_debug(hw, ICE_DBG_PTP, "Enabled clock on PHY port %u\n", port);
 
@@ -4626,87 +4600,41 @@  ice_get_phy_tx_tstamp_ready_e822(struct ice_hw *hw, u8 quad, u64 *tstamp_ready)
 }
 
 /**
- * ice_phy_exit_bypass_e822 - Exit bypass mode, after vernier calculations
+ * ice_phy_cfg_intr_e822 - Configure TX timestamp interrupt
  * @hw: pointer to the HW struct
- * @port: the PHY port to configure
+ * @quad: the timestamp quad
+ * @ena: enable or disable interrupt
+ * @threshold: interrupt threshold
  *
- * After hardware finishes vernier calculations for the Tx and Rx offset, this
- * function can be used to exit bypass mode by updating the total Tx and Rx
- * offsets, and then disabling bypass. This will enable hardware to include
- * the more precise offset calibrations, increasing precision of the generated
- * timestamps.
- *
- * This cannot be done until hardware has measured the offsets, which requires
- * waiting until at least one packet has been sent and received by the device.
+ * Configure TX timestamp interrupt for the specified quad
  */
-int ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port)
+
+int
+ice_phy_cfg_intr_e822(struct ice_hw *hw, u8 quad, bool ena, u8 threshold)
 {
 	int err;
 	u32 val;
 
-	err = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &val);
-	if (err) {
-		ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, err %d\n",
-			  port, err);
+	err = ice_read_quad_reg_e822(hw, quad,
+				     Q_REG_TX_MEM_GBL_CFG,
+				     &val);
+	if (err)
 		return err;
-	}
-
-	if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
-		ice_debug(hw, ICE_DBG_PTP, "Tx offset is not yet valid for port %u\n",
-			  port);
-		return ICE_ERR_NOT_READY;
-	}
-
-	err = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &val);
-	if (err) {
-		ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, err %d\n",
-			  port, err);
-		return err;
-	}
-
-	if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
-		ice_debug(hw, ICE_DBG_PTP, "Rx offset is not yet valid for port %u\n",
-			  port);
-		return ICE_ERR_NOT_READY;
-	}
 
-	err = ice_phy_cfg_tx_offset_e822(hw, port);
-	if (err) {
-		ice_debug(hw, ICE_DBG_PTP, "Failed to program total Tx offset for port %u, err %d\n",
-			  port, err);
-		return err;
-	}
-
-	err = ice_phy_cfg_rx_offset_e822(hw, port);
-	if (err) {
-		ice_debug(hw, ICE_DBG_PTP, "Failed to program total Rx offset for port %u, err %d\n",
-			  port, err);
-		return err;
-	}
-
-	/* Exit bypass mode now that the offset has been updated */
-	err = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
-	if (err) {
-		ice_debug(hw, ICE_DBG_PTP, "Failed to read P_REG_PS for port %u, err %d\n",
-			  port, err);
-		return err;
-	}
-
-	if (!(val & P_REG_PS_BYPASS_MODE_M))
-		ice_debug(hw, ICE_DBG_PTP, "Port %u not in bypass mode\n",
-			  port);
-
-	val &= ~P_REG_PS_BYPASS_MODE_M;
-	err = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
-	if (err) {
-		ice_debug(hw, ICE_DBG_PTP, "Failed to disable bypass for port %u, err %d\n",
-			  port, err);
-		return err;
+	if (ena) {
+		val |= Q_REG_TX_MEM_GBL_CFG_INTR_ENA_M;
+		val &= ~Q_REG_TX_MEM_GBL_CFG_INTR_THR_M;
+		val |= ((threshold << Q_REG_TX_MEM_GBL_CFG_INTR_THR_S) &
+			Q_REG_TX_MEM_GBL_CFG_INTR_THR_M);
+	} else {
+		val &= ~Q_REG_TX_MEM_GBL_CFG_INTR_ENA_M;
 	}
 
-	ice_info(hw, "Exiting bypass mode on PHY port %u\n", port);
+	err = ice_write_quad_reg_e822(hw, quad,
+				      Q_REG_TX_MEM_GBL_CFG,
+				      val);
 
-	return 0;
+	return err;
 }
 
 /* E810 functions
diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h
index 90db99327c..345d343a5a 100644
--- a/drivers/net/ice/base/ice_ptp_hw.h
+++ b/drivers/net/ice/base/ice_ptp_hw.h
@@ -256,11 +256,11 @@  ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
 void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port);
 int
 ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset);
-int
-ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass);
+int ice_start_phy_timer_e822(struct ice_hw *hw, u8 port);
 int ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port);
 int ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port);
-int ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port);
+int
+ice_phy_cfg_intr_e822(struct ice_hw *hw, u8 quad, bool ena, u8 threshold);
 
 /* E810 family functions */
 int ice_ptp_init_phy_e810(struct ice_hw *hw);
@@ -301,9 +301,11 @@  ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status);
 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, bool bypass);
+ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port);
 int ice_phy_cfg_tx_offset_eth56g(struct ice_hw *hw, u8 port);
 int ice_phy_cfg_rx_offset_eth56g(struct ice_hw *hw, u8 port);
+int
+ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold);
 
 #define ICE_ETH56G_PLL_FREQ		800000000
 #define ICE_ETH56G_NOMINAL_INCVAL	0x140000000ULL
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index f4394487a8..5c1d83e605 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -2504,7 +2504,7 @@  ice_dev_init(struct rte_eth_dev *dev)
 		hw->phy_model = ICE_PHY_E822;
 
 	if (hw->phy_model == ICE_PHY_E822) {
-		ret = ice_start_phy_timer_e822(hw, hw->pf_id, true);
+		ret = ice_start_phy_timer_e822(hw, hw->pf_id);
 		if (ret)
 			PMD_INIT_LOG(ERR, "Failed to start phy timer\n");
 	}