Thu, Aug 08, 2024 at 01:20:13PM CEST, arkadiusz.kubalewski@xxxxxxxxx wrote: >Allow the user to get and set configuration of Embedded SYNC feature >on the ice driver dpll pins. > >Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@xxxxxxxxx> >Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@xxxxxxxxx> >--- > drivers/net/ethernet/intel/ice/ice_dpll.c | 241 +++++++++++++++++++++- > drivers/net/ethernet/intel/ice/ice_dpll.h | 1 + > 2 files changed, 239 insertions(+), 3 deletions(-) > >diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c >index e92be6f130a3..0664bbe98769 100644 >--- a/drivers/net/ethernet/intel/ice/ice_dpll.c >+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c >@@ -394,8 +394,8 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, > > switch (pin_type) { > case ICE_DPLL_PIN_TYPE_INPUT: >- ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, NULL, NULL, >- NULL, &pin->flags[0], >+ ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status, >+ NULL, NULL, &pin->flags[0], > &pin->freq, &pin->phase_adjust); > if (ret) > goto err; >@@ -430,7 +430,7 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, > goto err; > > parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL; >- if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) { >+ if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) { > pin->state[pf->dplls.eec.dpll_idx] = > parent == pf->dplls.eec.dpll_idx ? > DPLL_PIN_STATE_CONNECTED : >@@ -1098,6 +1098,237 @@ ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv, > return 0; > } > >+/** >+ * ice_dpll_output_e_sync_set - callback for setting embedded sync >+ * @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 >+ * @e_sync_freq: requested embedded sync frequency >+ * @extack: error reporting >+ * >+ * Dpll subsystem callback. Handler for setting embedded sync frequency value >+ * on output pin. >+ * >+ * Context: Acquires pf->dplls.lock >+ * Return: >+ * * 0 - success >+ * * negative - error >+ */ >+static int >+ice_dpll_output_e_sync_set(const struct dpll_pin *pin, void *pin_priv, >+ const struct dpll_device *dpll, void *dpll_priv, >+ u64 e_sync_freq, struct netlink_ext_ack *extack) >+{ >+ struct ice_dpll_pin *p = pin_priv; >+ struct ice_dpll *d = dpll_priv; >+ struct ice_pf *pf = d->pf; >+ u8 flags = 0; >+ int ret; >+ >+ if (ice_dpll_is_reset(pf, extack)) >+ return -EBUSY; >+ mutex_lock(&pf->dplls.lock); >+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN) >+ flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN; >+ if (e_sync_freq == DPLL_PIN_FREQUENCY_1_HZ) { >+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) { >+ ret = 0; >+ } else { >+ flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN; >+ ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags, >+ 0, 0, 0); >+ } >+ } else { >+ if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) { >+ ret = 0; >+ } else { >+ flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN; >+ ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags, >+ 0, 0, 0); >+ } >+ } >+ mutex_unlock(&pf->dplls.lock); >+ if (ret) >+ NL_SET_ERR_MSG_FMT(extack, >+ "err:%d %s failed to set e-sync freq\n", Odd. Ret is pass all the way up to the userspace. Putting it to message does not make any sense to me. >+ ret, >+ ice_aq_str(pf->hw.adminq.sq_last_status)); >+ return ret; >+} >+ >+/** >+ * ice_dpll_output_e_sync_get - callback for getting embedded sync config >+ * @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 >+ * @e_sync_freq: on success holds embedded sync frequency of a pin >+ * @e_sync_range: on success holds embedded sync frequency range for a pin >+ * @pulse: on success holds embedded sync pulse type >+ * @extack: error reporting >+ * >+ * Dpll subsystem callback. Handler for getting embedded sync frequency value >+ * and capabilities on output pin. >+ * >+ * Context: Acquires pf->dplls.lock >+ * Return: >+ * * 0 - success >+ * * negative - error >+ */ >+static int >+ice_dpll_output_e_sync_get(const struct dpll_pin *pin, void *pin_priv, >+ const struct dpll_device *dpll, void *dpll_priv, >+ u64 *e_sync_freq, >+ struct dpll_pin_frequency *e_sync_range, >+ enum dpll_pin_e_sync_pulse *pulse, >+ struct netlink_ext_ack *extack) >+{ >+ struct ice_dpll_pin *p = pin_priv; >+ struct ice_dpll *d = dpll_priv; >+ struct ice_pf *pf = d->pf; >+ >+ if (ice_dpll_is_reset(pf, extack)) >+ return -EBUSY; >+ mutex_lock(&pf->dplls.lock); >+ if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY)) { >+ mutex_unlock(&pf->dplls.lock); >+ return -EOPNOTSUPP; >+ } >+ *pulse = DPLL_PIN_E_SYNC_PULSE_NONE; >+ e_sync_range->min = 0; >+ if (p->freq == DPLL_PIN_FREQUENCY_10_MHZ) { >+ e_sync_range->max = DPLL_PIN_FREQUENCY_1_HZ; >+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) { >+ *e_sync_freq = DPLL_PIN_FREQUENCY_1_HZ; >+ *pulse = DPLL_PIN_E_SYNC_PULSE_25_75; >+ } else { >+ *e_sync_freq = 0; >+ } >+ } else { >+ e_sync_range->max = 0; >+ *e_sync_freq = 0; >+ } >+ mutex_unlock(&pf->dplls.lock); >+ return 0; >+} >+ >+/** >+ * ice_dpll_input_e_sync_set - callback for setting embedded sync >+ * @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 >+ * @e_sync_freq: requested embedded sync frequency >+ * @extack: error reporting >+ * >+ * Dpll subsystem callback. Handler for setting embedded sync frequency value >+ * on input pin. >+ * >+ * Context: Acquires pf->dplls.lock >+ * Return: >+ * * 0 - success >+ * * negative - error >+ */ >+static int >+ice_dpll_input_e_sync_set(const struct dpll_pin *pin, void *pin_priv, >+ const struct dpll_device *dpll, void *dpll_priv, >+ u64 e_sync_freq, struct netlink_ext_ack *extack) >+{ >+ struct ice_dpll_pin *p = pin_priv; >+ struct ice_dpll *d = dpll_priv; >+ struct ice_pf *pf = d->pf; >+ u8 flags_en = 0; >+ int ret; >+ >+ if (ice_dpll_is_reset(pf, extack)) >+ return -EBUSY; >+ mutex_lock(&pf->dplls.lock); >+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN) >+ flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN; >+ if (e_sync_freq == DPLL_PIN_FREQUENCY_1_HZ) { >+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) { >+ ret = 0; >+ } else { >+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN; >+ ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0, >+ flags_en, 0, 0); >+ } >+ } else { >+ if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) { >+ ret = 0; >+ } else { >+ flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN; >+ ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0, >+ flags_en, 0, 0); >+ } >+ } >+ mutex_unlock(&pf->dplls.lock); >+ if (ret) >+ NL_SET_ERR_MSG_FMT(extack, >+ "err:%d %s failed to set e-sync freq\n", Same here. >+ ret, >+ ice_aq_str(pf->hw.adminq.sq_last_status)); >+ >+ return ret; >+} >+ >+/** >+ * ice_dpll_input_e_sync_get - callback for getting embedded sync config >+ * @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 >+ * @e_sync_freq: on success holds embedded sync frequency of a pin >+ * @e_sync_range: on success holds embedded sync frequency range for a pin >+ * @pulse: on success holds embedded sync pulse type >+ * @extack: error reporting >+ * >+ * Dpll subsystem callback. Handler for getting embedded sync frequency value >+ * and capabilities on input pin. >+ * >+ * Context: Acquires pf->dplls.lock >+ * Return: >+ * * 0 - success >+ * * negative - error >+ */ >+static int >+ice_dpll_input_e_sync_get(const struct dpll_pin *pin, void *pin_priv, >+ const struct dpll_device *dpll, void *dpll_priv, >+ u64 *e_sync_freq, >+ struct dpll_pin_frequency *e_sync_range, >+ enum dpll_pin_e_sync_pulse *pulse, >+ struct netlink_ext_ack *extack) >+{ >+ struct ice_dpll_pin *p = pin_priv; >+ struct ice_dpll *d = dpll_priv; >+ struct ice_pf *pf = d->pf; >+ >+ if (ice_dpll_is_reset(pf, extack)) >+ return -EBUSY; >+ mutex_lock(&pf->dplls.lock); >+ if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP)) { >+ mutex_unlock(&pf->dplls.lock); >+ return -EOPNOTSUPP; >+ } >+ *pulse = DPLL_PIN_E_SYNC_PULSE_NONE; >+ e_sync_range->min = 0; >+ if (p->freq == DPLL_PIN_FREQUENCY_10_MHZ) { >+ e_sync_range->max = DPLL_PIN_FREQUENCY_1_HZ; >+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) { >+ *e_sync_freq = DPLL_PIN_FREQUENCY_1_HZ; >+ *pulse = DPLL_PIN_E_SYNC_PULSE_25_75; >+ } else { >+ *e_sync_freq = 0; >+ } >+ } else { >+ e_sync_range->max = 0; >+ *e_sync_freq = 0; >+ } >+ mutex_unlock(&pf->dplls.lock); >+ return 0; >+} >+ > /** > * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin > * @pin: pointer to a pin >@@ -1222,6 +1453,8 @@ static const struct dpll_pin_ops ice_dpll_input_ops = { > .phase_adjust_get = ice_dpll_pin_phase_adjust_get, > .phase_adjust_set = ice_dpll_input_phase_adjust_set, > .phase_offset_get = ice_dpll_phase_offset_get, >+ .e_sync_set = ice_dpll_input_e_sync_set, >+ .e_sync_get = ice_dpll_input_e_sync_get, > }; > > static const struct dpll_pin_ops ice_dpll_output_ops = { >@@ -1232,6 +1465,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = { > .direction_get = ice_dpll_output_direction, > .phase_adjust_get = ice_dpll_pin_phase_adjust_get, > .phase_adjust_set = ice_dpll_output_phase_adjust_set, >+ .e_sync_set = ice_dpll_output_e_sync_set, >+ .e_sync_get = ice_dpll_output_e_sync_get, > }; > > static const struct dpll_device_ops ice_dpll_ops = { >diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h >index 93172e93995b..c320f1bf7d6d 100644 >--- a/drivers/net/ethernet/intel/ice/ice_dpll.h >+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h >@@ -31,6 +31,7 @@ struct ice_dpll_pin { > struct dpll_pin_properties prop; > u32 freq; > s32 phase_adjust; >+ u8 status; > }; > > /** ice_dpll - store info required for DPLL control >-- >2.38.1 >