lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <SJ2PR11MB8452414E4F138EE7B34C2B4C9B22A@SJ2PR11MB8452.namprd11.prod.outlook.com>
Date: Tue, 5 Aug 2025 14:30:04 +0000
From: "Kubalewski, Arkadiusz" <arkadiusz.kubalewski@...el.com>
To: "Nitka, Grzegorz" <grzegorz.nitka@...el.com>,
	"intel-wired-lan@...ts.osuosl.org" <intel-wired-lan@...ts.osuosl.org>
CC: "netdev@...r.kernel.org" <netdev@...r.kernel.org>, "Nguyen, Anthony L"
	<anthony.l.nguyen@...el.com>, "Kitszel, Przemyslaw"
	<przemyslaw.kitszel@...el.com>, "Korba, Przemyslaw"
	<przemyslaw.korba@...el.com>, "Olech, Milena" <milena.olech@...el.com>
Subject: RE: [PATCH v8 iwl-next] ice: add recovery clock and clock 1588
 control for E825c

>From: Nitka, Grzegorz <grzegorz.nitka@...el.com>
>Sent: Thursday, July 24, 2025 2:28 PM
>
>From: Przemyslaw Korba <przemyslaw.korba@...el.com>
>
>Add control for E825 input pins: phy clock recovery and clock 1588.
>E825 does not provide control over platform level DPLL but it
>provides control over PHY clock recovery, and PTP/timestamp driven
>inputs for platform level DPLL.
>
>Introduce a software controlled layer of abstraction to:
>- create a DPLL of type EEC for E825c,
>- create recovered clock pin for each PF, and control them through
>writing to registers,
>- create pin to control clock 1588 for PF0, and control it through
>writing to registers.
>
>Usage example:
>- to get EEC PLL info
>$ ynl --family dpll --dump device-get
>[{'clock-id': 0,
>  'id': 6,
>  'lock-status': 'locked',
>  'mode': 'manual',
>  'mode-supported': ['manual'],
>  'module-name': 'ice',
>  'type': 'eec'},
>...
>  ]
>
>- to get 1588 and rclk pins info
>(note: in the output below, pin id=31 is a representor for 1588 input,
>while pins 32..35 corresponds to PHY clock inputs to SyncE  module)
>$ ynl --family dpll --dump pin-get
>[{'board-label': 'CLK_IN_0',
>  'capabilities': set(),
>  'clock-id': 0,
>  'id': 27,
>  'module-name': 'ice',
>  'parent-device': [{'direction': 'input',
>                     'parent-id': 6,
>                     'state': 'connected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'mux'},
> {'board-label': 'CLK_IN_1',
>  'capabilities': set(),
>  'clock-id': 0,
>  'id': 28,
>  'module-name': 'ice',
>  'parent-device': [{'direction': 'input',
>                     'parent-id': 6,
>                     'state': 'connected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'mux'},
> {'board-label': 'pin_1588',
>  'capabilities': {'state-can-change'},
>  'clock-id': 0,
>  'id': 31,
>  'module-name': 'ice',
>  'parent-pin': [{'parent-id': 27, 'state': 'disconnected'},
>                 {'parent-id': 28, 'state': 'disconnected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'synce-eth-port'},
> {'capabilities': {'state-can-change'},
>  'clock-id': 0,
>  'id': 32,
>  'module-name': 'ice',
>  'parent-pin': [{'parent-id': 27, 'state': 'disconnected'},
>                 {'parent-id': 28, 'state': 'disconnected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'synce-eth-port'},
> {'capabilities': {'state-can-change'},
>  'clock-id': 0,
>  'id': 33,
>  'module-name': 'ice',
>  'parent-pin': [{'parent-id': 27, 'state': 'disconnected'},
>                 {'parent-id': 28, 'state': 'disconnected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'synce-eth-port'},
> {'capabilities': {'state-can-change'},
>  'clock-id': 0,
>  'id': 34,
>  'module-name': 'ice',
>  'parent-pin': [{'parent-id': 27, 'state': 'disconnected'},
>                 {'parent-id': 28, 'state': 'disconnected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'synce-eth-port'},
> {'capabilities': {'state-can-change'},
>  'clock-id': 0,
>  'id': 35,
>  'module-name': 'ice',
>  'parent-pin': [{'parent-id': 27, 'state': 'disconnected'},
>                 {'parent-id': 28, 'state': 'disconnected'}],
>  'phase-adjust-max': 0,
>  'phase-adjust-min': 0,
>  'type': 'synce-eth-port'}]
>
>- to set PHY0 clock as SyncE module input
>$ ynl --family dpll --do pin-set --json '{"id":32,"parent-pin":\
>    {"parent-id":27, "state":"connected"}}'
>
>- to set 1588 Main Timer as source into SyncE module
>$ ynl --family dpll --do pin-set --json '{"id":31,"parent-pin":\
>    {"parent-id":27, "state":"connected"}}'
>
>Reviewed-by: Milena Olech <milena.olech@...el.com>
>Co-developed-by: Grzegorz Nitka <grzegorz.nitka@...el.com>
>Signed-off-by: Grzegorz Nitka <grzegorz.nitka@...el.com>
>Signed-off-by: Przemyslaw Korba <przemyslaw.korba@...el.com>
>---
>v7->v8:
>- rebased
>- removed unrelated changes
>- change pin_1588 type to DPLL_PIN_TYPE_EXT
>- use ICE_SYNCE_CLK_NUM to determine the number of rclk pins
>---
> drivers/net/ethernet/intel/ice/ice_dpll.c   | 852 ++++++++++++++++++--
> drivers/net/ethernet/intel/ice/ice_dpll.h   |  24 +
> drivers/net/ethernet/intel/ice/ice_lib.c    |   3 +
> drivers/net/ethernet/intel/ice/ice_ptp_hw.c |  34 +-
> drivers/net/ethernet/intel/ice/ice_ptp_hw.h |   1 +
> drivers/net/ethernet/intel/ice/ice_tspll.h  |   7 +
> drivers/net/ethernet/intel/ice/ice_type.h   |   6 +
> 7 files changed, 869 insertions(+), 58 deletions(-)
>
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index 53b54e395a2e..f89dec5e532e 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -9,6 +9,7 @@
> #define ICE_CGU_STATE_ACQ_ERR_THRESHOLD		50
> #define ICE_DPLL_PIN_IDX_INVALID		0xff
> #define ICE_DPLL_RCLK_NUM_PER_PF		1
>+#define ICE_DPLL_PIN_1588_NUM			1
> #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT	25
> #define ICE_DPLL_PIN_GEN_RCLK_FREQ		1953125
> #define ICE_DPLL_PIN_PRIO_OUTPUT		0xff
>@@ -74,6 +75,7 @@ static const char * const pin_type_name[] = {
>
> static const char * const ice_dpll_sw_pin_sma[] = { "SMA1", "SMA2" };
> static const char * const ice_dpll_sw_pin_ufl[] = { "U.FL1", "U.FL2" };
>+static const char ice_dpll_pin_1588[] = "pin_1588";
>
> static const struct dpll_pin_frequency ice_esync_range[] = {
> 	DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
>@@ -528,6 +530,117 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct
>ice_dpll_pin *pin,
> 	return ret;
> }
>
>+/**
>+ * ice_dpll_rclk_update_e825c - updates the state of rclk pin on e825c
>device
>+ * @pf: private board struct
>+ * @pin: pointer to a pin
>+ *
>+ * Update struct holding pin states info, states are separate for each
>parent
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - OK
>+ * * negative - error
>+ */
>+static int ice_dpll_rclk_update_e825c(struct ice_pf *pf,
>+				      struct ice_dpll_pin *pin)
>+{
>+	u8 rclk_bits;
>+	int err;
>+	u32 reg;
>+
>+	if (pf->dplls.rclk.num_parents > ICE_SYNCE_CLK_NUM)
>+		return -EINVAL;
>+
>+	err = ice_read_cgu_reg(&pf->hw, ICE_CGU_R10, &reg);
>+	if (err)
>+		return err;
>+	rclk_bits = FIELD_GET(ICE_CGU_R10_SYNCE_S_REF_CLK, reg);
>+	SET_PIN_STATE(pin, ICE_SYNCE_CLK0, rclk_bits ==
>+		     (pf->ptp.port.port_num +
>ICE_CGU_BYPASS_MUX_OFFSET_E825C));
>+
>+	err = ice_read_cgu_reg(&pf->hw, ICE_CGU_R11, &reg);
>+	if (err)
>+		return err;
>+	rclk_bits = FIELD_GET(ICE_CGU_R11_SYNCE_S_BYP_CLK, reg);
>+	SET_PIN_STATE(pin, ICE_SYNCE_CLK1, rclk_bits ==
>+		     (pf->ptp.port.port_num +
>ICE_CGU_BYPASS_MUX_OFFSET_E825C));
>+	return 0;
>+}
>+
>+/**
>+ * ice_dpll_rclk_update - updates the state of rclk pin on a device
>+ * @pf: private board struct
>+ * @pin: pointer to a pin
>+ * @port_num: port number
>+ *
>+ * Update struct holding pin states info, states are separate for each
>parent
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - OK
>+ * * negative - error
>+ */
>+static int ice_dpll_rclk_update(struct ice_pf *pf, struct ice_dpll_pin
>*pin,
>+				u8 port_num)
>+{
>+	int ret;
>+
>+	for (u8 parent = 0; parent < pf->dplls.rclk.num_parents; parent++) {
>+		ret = ice_aq_get_phy_rec_clk_out(&pf->hw, &parent, &port_num,
>+						 &pin->flags[parent], NULL);
>+		if (ret)
>+			return ret;
>+		SET_PIN_STATE(pin, parent,
>+			      ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
>+			      pin->flags[parent]);
>+	}
>+
>+	return 0;
>+}
>+
>+/**
>+ * ice_dpll_update_pin_1588_e825c - updates the state of clock 1588 pin
>+ * @hw: board private hw structure
>+ * @pin: pointer to a pin
>+ * @parent: clock source identifier
>+ *
>+ * Update struct holding pin states info, states are separate for each
>parent
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - OK
>+ * * negative - error
>+ */
>+static int ice_dpll_update_pin_1588_e825c(struct ice_hw *hw,
>+					  struct ice_dpll_pin *pin,
>+					  enum ice_synce_clk parent)
>+{
>+	u8 bits_clk;
>+	int err;
>+	u32 reg;
>+
>+	switch (parent) {
>+	case ICE_SYNCE_CLK0:
>+		err = ice_read_cgu_reg(hw, ICE_CGU_R10, &reg);
>+		if (err)
>+			return err;
>+		bits_clk = FIELD_GET(ICE_CGU_R10_SYNCE_S_REF_CLK, reg);
>+		break;
>+	case ICE_SYNCE_CLK1:
>+		err = ice_read_cgu_reg(hw, ICE_CGU_R11, &reg);
>+		if (err)
>+			return err;
>+		bits_clk = FIELD_GET(ICE_CGU_R11_SYNCE_S_BYP_CLK, reg);
>+		break;
>+	default:
>+		return -EINVAL;
>+	}
>+	SET_PIN_STATE(pin, parent, bits_clk == ICE_CGU_NCOCLK);
>+
>+	return 0;
>+}
>+
> /**
>  * ice_dpll_sw_pins_update - update status of all SW pins
>  * @pf: private board struct
>@@ -668,22 +781,14 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct
>ice_dpll_pin *pin,
> 		}
> 		break;
> 	case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
>-		for (parent = 0; parent < pf->dplls.rclk.num_parents;
>-		     parent++) {
>-			u8 p = parent;
>-
>-			ret = ice_aq_get_phy_rec_clk_out(&pf->hw, &p,
>-							 &port_num,
>-							 &pin->flags[parent],
>-							 NULL);
>+		if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
>+			ret = ice_dpll_rclk_update_e825c(pf, pin);
>+			if (ret)
>+				goto err;
>+		} else {
>+			ret = ice_dpll_rclk_update(pf, pin, port_num);
> 			if (ret)
> 				goto err;
>-			if (ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
>-			    pin->flags[parent])
>-				pin->state[parent] = DPLL_PIN_STATE_CONNECTED;
>-			else
>-				pin->state[parent] =
>-					DPLL_PIN_STATE_DISCONNECTED;
> 		}
> 		break;
> 	case ICE_DPLL_PIN_TYPE_SOFTWARE:
>@@ -1021,6 +1126,33 @@ ice_dpll_pin_state_get(const struct dpll_pin *pin,
>void *pin_priv,
> 	return ret;
> }
>
>+/**
>+ * ice_dpll_pin_state_get_e825c - update e825c device pin's state on dpll
>+ * @pin: pointer to a pin
>+ * @pin_priv: private data pointer passed on pin registration
>+ * @dpll: registered dpll pointer
>+ * @dpll_priv: private data pointer passed on dpll registration
>+ * @state: on success holds state of the pin
>+ * @extack: error reporting
>+ *
>+ * Set pin state of e825c device to connected.
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - success
>+ */
>+static int ice_dpll_pin_state_get_e825c(const struct dpll_pin *pin,
>+					void *pin_priv,
>+					const struct dpll_device *dpll,
>+					void *dpll_priv,
>+					enum dpll_pin_state *state,
>+					struct netlink_ext_ack *extack)
>+{
>+	*state = DPLL_PIN_STATE_CONNECTED;
>+
>+	return 0;
>+}
>+
> /**
>  * ice_dpll_output_state_get - get output pin state on dpll device
>  * @pin: pointer to a pin
>@@ -1842,6 +1974,228 @@ ice_dpll_phase_offset_get(const struct dpll_pin
>*pin, void *pin_priv,
> 	return 0;
> }
>
>+/**
>+ * ice_dpll_cfg_bypass_mux_e825c - check if the given port recovered clock
>+ * or clock 1588 is set active
>+ * @hw: Pointer to the HW struct
>+ * @ena: true to enable the reference, false if disable
>+ * @port_num: Number of the port
>+ * @output: Output pin, we have two in E825C
>+ * @clock_1588: true to enable 1588 reference, false to recover from port
>+ *
>+ * Dpll subsystem callback. Handler for setting the correct registers to
>+ * enable a functionality on e825c device.
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - success
>+ * * negative - error
>+ */
>+static int
>+ice_dpll_cfg_bypass_mux_e825c(struct ice_hw *hw, bool ena,
>+			      u32 port_num, enum ice_synce_clk output,
>+			      bool clock_1588)

There is now new file ice_tspll.c, where this code could belong, then just
provide interface for this code.

>+{
>+	u8 first_mux;
>+	int err;
>+	u32 r10;
>+
>+	err = ice_read_cgu_reg(hw, ICE_CGU_R10, &r10);
>+	if (err)
>+		return err;
>+
>+	if (!ena)
>+		first_mux = ICE_CGU_NET_REF_CLK0;
>+	else if (clock_1588)
>+		first_mux = ICE_CGU_NCOCLK;
>+	else
>+		first_mux = port_num + ICE_CGU_BYPASS_MUX_OFFSET_E825C;
>+
>+	r10 &= ~(ICE_CGU_R10_SYNCE_DCK_RST | ICE_CGU_R10_SYNCE_DCK2_RST);
>+
>+	switch (output) {
>+	case ICE_SYNCE_CLK0:
>+		r10 &= ~(ICE_CGU_R10_SYNCE_ETHCLKO_SEL |
>+			 ICE_CGU_R10_SYNCE_ETHDIV_LOAD |
>+			 ICE_CGU_R10_SYNCE_S_REF_CLK);
>+		r10 |= FIELD_PREP(ICE_CGU_R10_SYNCE_S_REF_CLK, first_mux);
>+		if (clock_1588)
>+			r10 |= FIELD_PREP(ICE_CGU_R10_SYNCE_ETHCLKO_SEL,
>+					  ICE_CGU_REF_CLK_BYP0);
>+		else
>+			r10 |= FIELD_PREP(ICE_CGU_R10_SYNCE_ETHCLKO_SEL,
>+					  ICE_CGU_REF_CLK_BYP0_DIV);
>+		break;
>+	case ICE_SYNCE_CLK1:
>+	{
>+		u32 val;
>+
>+		err = ice_read_cgu_reg(hw, ICE_CGU_R11, &val);
>+		if (err)
>+			return err;
>+		val &= ~ICE_CGU_R11_SYNCE_S_BYP_CLK;
>+		val |= FIELD_PREP(ICE_CGU_R11_SYNCE_S_BYP_CLK, first_mux);
>+		err = ice_write_cgu_reg(hw, ICE_CGU_R11, val);
>+		if (err)
>+			return err;
>+		r10 &= ~(ICE_CGU_R10_SYNCE_CLKODIV_LOAD |
>+			 ICE_CGU_R10_SYNCE_CLKO_SEL);
>+		if (clock_1588)
>+			r10 |= FIELD_PREP(ICE_CGU_R10_SYNCE_CLKO_SEL,
>+					  ICE_CGU_REF_CLK_BYP1);
>+		else
>+			r10 |= FIELD_PREP(ICE_CGU_R10_SYNCE_CLKO_SEL,
>+					  ICE_CGU_REF_CLK_BYP1_DIV);
>+		break;
>+	}
>+	default:
>+		return -EINVAL;
>+	}
>+
>+	err = ice_write_cgu_reg(hw, ICE_CGU_R10, r10);
>+	if (err)
>+		return err;
>+
>+	return 0;
>+}
>+
>+/**
>+ * ice_dpll_get_div_e825c - get the divider for the given speed
>+ * @link_speed: link speed of the port
>+ * @divider: output value, calculated divider
>+ *
>+ * Dpll subsystem callback. Handler for setting the divider on e825c
>device.
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - success
>+ * * negative - error
>+ */
>+static int ice_dpll_get_div_e825c(u16 link_speed, u8 *divider)
>+{
>+	switch (link_speed) {
>+	case ICE_AQ_LINK_SPEED_100GB:
>+	case ICE_AQ_LINK_SPEED_50GB:
>+	case ICE_AQ_LINK_SPEED_25GB:
>+		*divider = 10;
>+		break;
>+	case ICE_AQ_LINK_SPEED_40GB:
>+	case ICE_AQ_LINK_SPEED_10GB:
>+		*divider = 4;
>+		break;
>+	case ICE_AQ_LINK_SPEED_5GB:
>+	case ICE_AQ_LINK_SPEED_2500MB:
>+	case ICE_AQ_LINK_SPEED_1000MB:
>+		*divider = 2;
>+		break;
>+	case ICE_AQ_LINK_SPEED_100MB:
>+		*divider = 1;
>+		break;
>+	default:
>+		return -EOPNOTSUPP;
>+	}
>+
>+	return 0;
>+}
>+
>+/**
>+ * ice_dpll_cfg_synce_ethdiv_e825c - set the divider on the mux
>+ * @hw: Pointer to the HW struct
>+ * @output: Output pin, we have two in E825C
>+ *
>+ * Dpll subsystem callback. Set the correct divider for RCLKA or RCLKB.
>+ *
>+ * Context: Called under pf->dplls.lock
>+ * Return:
>+ * * 0 - success
>+ * * negative - error
>+ */
>+static int ice_dpll_cfg_synce_ethdiv_e825c(struct ice_hw *hw,
>+					   enum ice_synce_clk output)

Ditto.

Thank you!

[..]

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ