Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH net-next v1 0/4] dpll: add all inputs phase offset monitor
@ 2025-04-09 15:25 Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 1/4] dpll: add features and capabilities to dpll device spec Arkadiusz Kubalewski
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Arkadiusz Kubalewski @ 2025-04-09 15:25 UTC (permalink / raw)
  To: donald.hunter, kuba, davem, edumazet, pabeni, horms,
	vadim.fedorenko, jiri, anthony.l.nguyen, przemyslaw.kitszel,
	andrew+netdev, saeedm, leon, tariqt, jonathan.lemon,
	richardcochran, aleksandr.loktionov, milena.olech
  Cc: netdev, linux-kernel, intel-wired-lan, linux-rdma,
	Arkadiusz Kubalewski

Add simple dpll device level feature and capabilities infrastructure over
netlink dpll interface.
Using new infrastructure add new feature: ALL_INPUTS_PHASE_OFFSET_MONITOR.
Allow users control with two new attributes:
- DPLL_A_CAPABILITIES - for checking if dpll device is capable,
- DPLL_A_FEATURES - for enable/disable a features.
Implement feature in ice driver for dpll-enabled devices.

Arkadiusz Kubalewski (4):
  dpll: add features and capabilities to dpll device spec
  dpll: pass capabilities on device register
  dpll: features_get/set callbacks
  ice: add phase offset monitor for all PPS dpll inputs

 Documentation/netlink/specs/dpll.yaml         |  25 +++
 drivers/dpll/dpll_core.c                      |   5 +-
 drivers/dpll/dpll_core.h                      |   2 +
 drivers/dpll/dpll_netlink.c                   |  78 +++++++-
 drivers/dpll/dpll_nl.c                        |   5 +-
 .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  20 ++
 drivers/net/ethernet/intel/ice/ice_common.c   |  26 +++
 drivers/net/ethernet/intel/ice/ice_common.h   |   3 +
 drivers/net/ethernet/intel/ice/ice_dpll.c     | 188 +++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_dpll.h     |   6 +
 drivers/net/ethernet/intel/ice/ice_main.c     |   4 +
 .../net/ethernet/mellanox/mlx5/core/dpll.c    |   2 +-
 drivers/ptp/ptp_ocp.c                         |   2 +-
 include/linux/dpll.h                          |   7 +-
 include/uapi/linux/dpll.h                     |  13 ++
 15 files changed, 374 insertions(+), 12 deletions(-)


base-commit: 420aabef3ab5fa743afb4d3d391f03ef0e777ca8
-- 
2.38.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net-next v1 1/4] dpll: add features and capabilities to dpll device spec
  2025-04-09 15:25 [PATCH net-next v1 0/4] dpll: add all inputs phase offset monitor Arkadiusz Kubalewski
@ 2025-04-09 15:25 ` Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 2/4] dpll: pass capabilities on device register Arkadiusz Kubalewski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Arkadiusz Kubalewski @ 2025-04-09 15:25 UTC (permalink / raw)
  To: donald.hunter, kuba, davem, edumazet, pabeni, horms,
	vadim.fedorenko, jiri, anthony.l.nguyen, przemyslaw.kitszel,
	andrew+netdev, saeedm, leon, tariqt, jonathan.lemon,
	richardcochran, aleksandr.loktionov, milena.olech
  Cc: netdev, linux-kernel, intel-wired-lan, linux-rdma,
	Arkadiusz Kubalewski

Add infrastructure for adding simple control over dpll device level
features.
Add define for new dpll device level feature:
DPLL_FEATURES_ALL_INPUTS_PHASE_OFFSET_MONITOR - control over monitoring of
all input pins phase offsets.

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
---
 Documentation/netlink/specs/dpll.yaml | 25 +++++++++++++++++++++++++
 drivers/dpll/dpll_nl.c                |  5 +++--
 include/uapi/linux/dpll.h             | 13 +++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
index 8feefeae5376..c9a3873e03f6 100644
--- a/Documentation/netlink/specs/dpll.yaml
+++ b/Documentation/netlink/specs/dpll.yaml
@@ -240,6 +240,18 @@ definitions:
       integer part of a measured phase offset value.
       Value of (DPLL_A_PHASE_OFFSET % DPLL_PHASE_OFFSET_DIVIDER) is a
       fractional part of a measured phase offset value.
+  -
+    type: flags
+    name: features
+    doc: |
+      Allow simple control (enable/disable) and status checking over features
+      available per single dpll device.
+    entries:
+      -
+        name: all-inputs-phase-offset-monitor
+        doc: |
+          select if phase offset values are measured and reported for
+          all the input pins available for given dpll device
 
 attribute-sets:
   -
@@ -293,6 +305,16 @@ attribute-sets:
           be put to message multiple times to indicate possible parallel
           quality levels (e.g. one specified by ITU option 1 and another
           one specified by option 2).
+      -
+        name: capabilities
+        type: u32
+        enum: features
+        doc: Features available for a dpll device.
+      -
+        name: features
+        type: u32
+        enum: features
+        doc: Features enabled for a dpll device.
   -
     name: pin
     enum-name: dpll_a_pin
@@ -483,6 +505,8 @@ operations:
             - temp
             - clock-id
             - type
+            - capabilities
+            - features
 
       dump:
         reply: *dev-attrs
@@ -499,6 +523,7 @@ operations:
         request:
           attributes:
             - id
+            - features
     -
       name: device-create-ntf
       doc: Notification about device appearing
diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c
index fe9b6893d261..3712a693c458 100644
--- a/drivers/dpll/dpll_nl.c
+++ b/drivers/dpll/dpll_nl.c
@@ -37,8 +37,9 @@ static const struct nla_policy dpll_device_get_nl_policy[DPLL_A_ID + 1] = {
 };
 
 /* DPLL_CMD_DEVICE_SET - do */
-static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_ID + 1] = {
+static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_FEATURES + 1] = {
 	[DPLL_A_ID] = { .type = NLA_U32, },
+	[DPLL_A_FEATURES] = NLA_POLICY_MASK(NLA_U32, 0x1),
 };
 
 /* DPLL_CMD_PIN_ID_GET - do */
@@ -105,7 +106,7 @@ static const struct genl_split_ops dpll_nl_ops[] = {
 		.doit		= dpll_nl_device_set_doit,
 		.post_doit	= dpll_post_doit,
 		.policy		= dpll_device_set_nl_policy,
-		.maxattr	= DPLL_A_ID,
+		.maxattr	= DPLL_A_FEATURES,
 		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
 	},
 	{
diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
index bf97d4b6d51f..7c8e929831aa 100644
--- a/include/uapi/linux/dpll.h
+++ b/include/uapi/linux/dpll.h
@@ -192,6 +192,17 @@ enum dpll_pin_capabilities {
 
 #define DPLL_PHASE_OFFSET_DIVIDER	1000
 
+/**
+ * enum dpll_features - Allow simple control (enable/disable) and status
+ *   checking over features available per single dpll device.
+ * @DPLL_FEATURES_ALL_INPUTS_PHASE_OFFSET_MONITOR: select if phase offset
+ *   values are measured and reported for all the input pins available for
+ *   given dpll device
+ */
+enum dpll_features {
+	DPLL_FEATURES_ALL_INPUTS_PHASE_OFFSET_MONITOR = 1,
+};
+
 enum dpll_a {
 	DPLL_A_ID = 1,
 	DPLL_A_MODULE_NAME,
@@ -204,6 +215,8 @@ enum dpll_a {
 	DPLL_A_TYPE,
 	DPLL_A_LOCK_STATUS_ERROR,
 	DPLL_A_CLOCK_QUALITY_LEVEL,
+	DPLL_A_CAPABILITIES,
+	DPLL_A_FEATURES,
 
 	__DPLL_A_MAX,
 	DPLL_A_MAX = (__DPLL_A_MAX - 1)
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v1 2/4] dpll: pass capabilities on device register
  2025-04-09 15:25 [PATCH net-next v1 0/4] dpll: add all inputs phase offset monitor Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 1/4] dpll: add features and capabilities to dpll device spec Arkadiusz Kubalewski
@ 2025-04-09 15:25 ` Arkadiusz Kubalewski
  2025-04-09 16:34   ` Loktionov, Aleksandr
  2025-04-09 15:25 ` [PATCH net-next v1 3/4] dpll: features_get/set callbacks Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 4/4] ice: add phase offset monitor for all PPS dpll inputs Arkadiusz Kubalewski
  3 siblings, 1 reply; 6+ messages in thread
From: Arkadiusz Kubalewski @ 2025-04-09 15:25 UTC (permalink / raw)
  To: donald.hunter, kuba, davem, edumazet, pabeni, horms,
	vadim.fedorenko, jiri, anthony.l.nguyen, przemyslaw.kitszel,
	andrew+netdev, saeedm, leon, tariqt, jonathan.lemon,
	richardcochran, aleksandr.loktionov, milena.olech
  Cc: netdev, linux-kernel, intel-wired-lan, linux-rdma,
	Arkadiusz Kubalewski

Add new argument on dpll device register, a capabilities bitmask of
features supported by the dpll device.
Provide capability value on dpll device dump.

Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
---
 drivers/dpll/dpll_core.c                       | 5 ++++-
 drivers/dpll/dpll_core.h                       | 2 ++
 drivers/dpll/dpll_netlink.c                    | 2 ++
 drivers/net/ethernet/intel/ice/ice_dpll.c      | 2 +-
 drivers/net/ethernet/mellanox/mlx5/core/dpll.c | 2 +-
 drivers/ptp/ptp_ocp.c                          | 2 +-
 include/linux/dpll.h                           | 3 ++-
 7 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
index 20bdc52f63a5..563ac37c83ad 100644
--- a/drivers/dpll/dpll_core.c
+++ b/drivers/dpll/dpll_core.c
@@ -342,6 +342,7 @@ dpll_device_registration_find(struct dpll_device *dpll,
  * dpll_device_register - register the dpll device in the subsystem
  * @dpll: pointer to a dpll
  * @type: type of a dpll
+ * @capabilities: mask of available features supported by dpll
  * @ops: ops for a dpll device
  * @priv: pointer to private information of owner
  *
@@ -353,7 +354,8 @@ dpll_device_registration_find(struct dpll_device *dpll,
  * * negative - error value
  */
 int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
-			 const struct dpll_device_ops *ops, void *priv)
+			 u32 capabilities, const struct dpll_device_ops *ops,
+			 void *priv)
 {
 	struct dpll_device_registration *reg;
 	bool first_registration = false;
@@ -382,6 +384,7 @@ int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
 	reg->ops = ops;
 	reg->priv = priv;
 	dpll->type = type;
+	dpll->capabilities = capabilities;
 	first_registration = list_empty(&dpll->registration_list);
 	list_add_tail(&reg->list, &dpll->registration_list);
 	if (!first_registration) {
diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h
index 2b6d8ef1cdf3..70bbafb9b635 100644
--- a/drivers/dpll/dpll_core.h
+++ b/drivers/dpll/dpll_core.h
@@ -21,6 +21,7 @@
  * @clock_id:		unique identifier (clock_id) of a dpll
  * @module:		module of creator
  * @type:		type of a dpll
+ * @capabilities:	capabilities of a dpll
  * @pin_refs:		stores pins registered within a dpll
  * @refcount:		refcount
  * @registration_list:	list of registered ops and priv data of dpll owners
@@ -31,6 +32,7 @@ struct dpll_device {
 	u64 clock_id;
 	struct module *module;
 	enum dpll_type type;
+	u32 capabilities;
 	struct xarray pin_refs;
 	refcount_t refcount;
 	struct list_head registration_list;
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index c130f87147fa..41aed0d29be2 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -591,6 +591,8 @@ dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
 		return ret;
 	if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type))
 		return -EMSGSIZE;
+	if (nla_put_u32(msg, DPLL_A_CAPABILITIES, dpll->capabilities))
+		return -EMSGSIZE;
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index bce3ad6ca2a6..614a813c7772 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -2012,7 +2012,7 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
 	d->pf = pf;
 	if (cgu) {
 		ice_dpll_update_state(pf, d, true);
-		ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d);
+		ret = dpll_device_register(d->dpll, type, 0, &ice_dpll_ops, d);
 		if (ret) {
 			dpll_device_put(d->dpll);
 			return ret;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
index 1e5522a19483..0e430f93b047 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
@@ -444,7 +444,7 @@ static int mlx5_dpll_probe(struct auxiliary_device *adev,
 		goto err_free_mdpll;
 	}
 
-	err = dpll_device_register(mdpll->dpll, DPLL_TYPE_EEC,
+	err = dpll_device_register(mdpll->dpll, DPLL_TYPE_EEC, 0,
 				   &mlx5_dpll_device_ops, mdpll);
 	if (err)
 		goto err_put_dpll_device;
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index b25635c5c745..87b9890d8ef2 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -4745,7 +4745,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		goto out;
 	}
 
-	err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp);
+	err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, 0, &dpll_ops, bp);
 	if (err)
 		goto out;
 
diff --git a/include/linux/dpll.h b/include/linux/dpll.h
index 5e4f9ab1cf75..dde8dee83dc6 100644
--- a/include/linux/dpll.h
+++ b/include/linux/dpll.h
@@ -171,7 +171,8 @@ dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module);
 void dpll_device_put(struct dpll_device *dpll);
 
 int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
-			 const struct dpll_device_ops *ops, void *priv);
+			 u32 capabilities, const struct dpll_device_ops *ops,
+			 void *priv);
 
 void dpll_device_unregister(struct dpll_device *dpll,
 			    const struct dpll_device_ops *ops, void *priv);
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v1 3/4] dpll: features_get/set callbacks
  2025-04-09 15:25 [PATCH net-next v1 0/4] dpll: add all inputs phase offset monitor Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 1/4] dpll: add features and capabilities to dpll device spec Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 2/4] dpll: pass capabilities on device register Arkadiusz Kubalewski
@ 2025-04-09 15:25 ` Arkadiusz Kubalewski
  2025-04-09 15:25 ` [PATCH net-next v1 4/4] ice: add phase offset monitor for all PPS dpll inputs Arkadiusz Kubalewski
  3 siblings, 0 replies; 6+ messages in thread
From: Arkadiusz Kubalewski @ 2025-04-09 15:25 UTC (permalink / raw)
  To: donald.hunter, kuba, davem, edumazet, pabeni, horms,
	vadim.fedorenko, jiri, anthony.l.nguyen, przemyslaw.kitszel,
	andrew+netdev, saeedm, leon, tariqt, jonathan.lemon,
	richardcochran, aleksandr.loktionov, milena.olech
  Cc: netdev, linux-kernel, intel-wired-lan, linux-rdma,
	Arkadiusz Kubalewski

Add new callback ops for a dpll device.
- features_get(..) - to obtain currently configured features from dpll
  device,
- feature_set(..) - to allow dpll device features configuration.
Provide features attribute and allow control over it to the users if
device driver implements callbacks.

Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
---
 drivers/dpll/dpll_netlink.c | 76 ++++++++++++++++++++++++++++++++++++-
 include/linux/dpll.h        |  4 ++
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index 41aed0d29be2..41eb848ce021 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -126,6 +126,25 @@ dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll,
 	return 0;
 }
 
+static int
+dpll_msg_add_features(struct sk_buff *msg, struct dpll_device *dpll,
+		      struct netlink_ext_ack *extack)
+{
+	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
+	u32 features;
+	int ret;
+
+	if (!ops->features_get)
+		return 0;
+	ret = ops->features_get(dpll, dpll_priv(dpll), &features, extack);
+	if (ret)
+		return ret;
+	if (nla_put_u32(msg, DPLL_A_FEATURES, features))
+		return -EMSGSIZE;
+
+	return 0;
+}
+
 static int
 dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll,
 			 struct netlink_ext_ack *extack)
@@ -593,6 +612,9 @@ dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
 		return -EMSGSIZE;
 	if (nla_put_u32(msg, DPLL_A_CAPABILITIES, dpll->capabilities))
 		return -EMSGSIZE;
+	ret = dpll_msg_add_features(msg, dpll, extack);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -748,6 +770,33 @@ int dpll_pin_change_ntf(struct dpll_pin *pin)
 }
 EXPORT_SYMBOL_GPL(dpll_pin_change_ntf);
 
+static int
+dpll_features_set(struct dpll_device *dpll, struct nlattr *a,
+		  struct netlink_ext_ack *extack)
+{
+	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
+	u32 features = nla_get_u32(a), old_features;
+	int ret;
+
+	if (features && !(dpll->capabilities & features)) {
+		NL_SET_ERR_MSG_ATTR(extack, a, "dpll device not capable of this features");
+		return -EOPNOTSUPP;
+	}
+	if (!ops->features_get || !ops->features_set) {
+		NL_SET_ERR_MSG(extack, "dpll device not supporting any features");
+		return -EOPNOTSUPP;
+	}
+	ret = ops->features_get(dpll, dpll_priv(dpll), &old_features, extack);
+	if (ret) {
+		NL_SET_ERR_MSG(extack, "unable to get old features value");
+		return ret;
+	}
+	if (old_features == features)
+		return -EINVAL;
+
+	return ops->features_set(dpll, dpll_priv(dpll), features, extack);
+}
+
 static int
 dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
 		  struct netlink_ext_ack *extack)
@@ -1535,10 +1584,33 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
 	return genlmsg_reply(msg, info);
 }
 
+static int
+dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info)
+{
+	struct nlattr *a;
+	int rem, ret;
+
+	nla_for_each_attr(a, genlmsg_data(info->genlhdr),
+			  genlmsg_len(info->genlhdr), rem) {
+		switch (nla_type(a)) {
+		case DPLL_A_FEATURES:
+			ret = dpll_features_set(dpll, a, info->extack);
+			if (ret)
+				return ret;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
 int dpll_nl_device_set_doit(struct sk_buff *skb, struct genl_info *info)
 {
-	/* placeholder for set command */
-	return 0;
+	struct dpll_device *dpll = info->user_ptr[0];
+
+	return dpll_set_from_nlattr(dpll, info);
 }
 
 int dpll_nl_device_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
diff --git a/include/linux/dpll.h b/include/linux/dpll.h
index dde8dee83dc6..5432d8479ed5 100644
--- a/include/linux/dpll.h
+++ b/include/linux/dpll.h
@@ -30,6 +30,10 @@ struct dpll_device_ops {
 				       void *dpll_priv,
 				       unsigned long *qls,
 				       struct netlink_ext_ack *extack);
+	int (*features_set)(const struct dpll_device *dpll, void *dpll_priv,
+			    u32 features, struct netlink_ext_ack *extack);
+	int (*features_get)(const struct dpll_device *dpll, void *dpll_priv,
+			    u32 *features, struct netlink_ext_ack *extack);
 };
 
 struct dpll_pin_ops {
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v1 4/4] ice: add phase offset monitor for all PPS dpll inputs
  2025-04-09 15:25 [PATCH net-next v1 0/4] dpll: add all inputs phase offset monitor Arkadiusz Kubalewski
                   ` (2 preceding siblings ...)
  2025-04-09 15:25 ` [PATCH net-next v1 3/4] dpll: features_get/set callbacks Arkadiusz Kubalewski
@ 2025-04-09 15:25 ` Arkadiusz Kubalewski
  3 siblings, 0 replies; 6+ messages in thread
From: Arkadiusz Kubalewski @ 2025-04-09 15:25 UTC (permalink / raw)
  To: donald.hunter, kuba, davem, edumazet, pabeni, horms,
	vadim.fedorenko, jiri, anthony.l.nguyen, przemyslaw.kitszel,
	andrew+netdev, saeedm, leon, tariqt, jonathan.lemon,
	richardcochran, aleksandr.loktionov, milena.olech
  Cc: netdev, linux-kernel, intel-wired-lan, linux-rdma,
	Arkadiusz Kubalewski

Implement new admin command and helper function to handle/obtain CGU
measurements for input pins, initialize PPS dpll capabilities using new
command.
Add callbacks to control dpll device feature:
all-inputs-phase-offset-monitor.
Allow enable/disable of all inputs monitoring for ice PPS dpll device.
If feature is enabled provide users with measured phase offsets and
notifications.

Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
---
 .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  20 ++
 drivers/net/ethernet/intel/ice/ice_common.c   |  26 +++
 drivers/net/ethernet/intel/ice/ice_common.h   |   3 +
 drivers/net/ethernet/intel/ice/ice_dpll.c     | 188 +++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_dpll.h     |   6 +
 drivers/net/ethernet/intel/ice/ice_main.c     |   4 +
 6 files changed, 243 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index bdee499f991a..181bc2c3b4ad 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -2272,6 +2272,22 @@ struct ice_aqc_get_pkg_info_resp {
 	struct ice_aqc_get_pkg_info pkg_info[];
 };
 
+#define ICE_CGU_INPUT_PHASE_OFFSET_BYTES	6
+
+struct ice_cgu_input_measure {
+	u8 phase_offset[ICE_CGU_INPUT_PHASE_OFFSET_BYTES];
+	__le32 freq;
+} __packed __aligned(sizeof(__le16));
+
+#define ICE_AQC_GET_CGU_IN_MEAS_DPLL_IDX_M	ICE_M(0xf, 0)
+
+/* Get CGU input measurements command response data structure (indirect 0x0C59) */
+struct ice_aqc_get_cgu_input_measure {
+	u8 dpll_idx_opt;
+	u8 length;
+	u8 rsvd[6];
+};
+
 #define ICE_AQC_GET_CGU_MAX_PHASE_ADJ	GENMASK(30, 0)
 
 /* Get CGU abilities command response data structure (indirect 0x0C61) */
@@ -2721,6 +2737,7 @@ struct ice_aq_desc {
 		struct ice_aqc_add_get_update_free_vsi vsi_cmd;
 		struct ice_aqc_add_update_free_vsi_resp add_update_free_vsi_res;
 		struct ice_aqc_download_pkg download_pkg;
+		struct ice_aqc_get_cgu_input_measure get_cgu_input_measure;
 		struct ice_aqc_set_cgu_input_config set_cgu_input_config;
 		struct ice_aqc_get_cgu_input_config get_cgu_input_config;
 		struct ice_aqc_set_cgu_output_config set_cgu_output_config;
@@ -2772,6 +2789,8 @@ enum ice_aq_err {
 	ICE_AQ_RC_OK		= 0,  /* Success */
 	ICE_AQ_RC_EPERM		= 1,  /* Operation not permitted */
 	ICE_AQ_RC_ENOENT	= 2,  /* No such element */
+	ICE_AQ_RC_ESRCH		= 3,  /* Bad opcode */
+	ICE_AQ_RC_EAGAIN	= 8,  /* Try again */
 	ICE_AQ_RC_ENOMEM	= 9,  /* Out of memory */
 	ICE_AQ_RC_EBUSY		= 12, /* Device or resource busy */
 	ICE_AQ_RC_EEXIST	= 13, /* Object already exists */
@@ -2927,6 +2946,7 @@ enum ice_adminq_opc {
 	ice_aqc_opc_get_pkg_info_list			= 0x0C43,
 
 	/* 1588/SyncE commands/events */
+	ice_aqc_opc_get_cgu_input_measure		= 0x0C59,
 	ice_aqc_opc_get_cgu_abilities			= 0x0C61,
 	ice_aqc_opc_set_cgu_input_config		= 0x0C62,
 	ice_aqc_opc_get_cgu_input_config		= 0x0C63,
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 59df31c2c83f..f5d50b522e29 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -4966,6 +4966,32 @@ ice_dis_vsi_rdma_qset(struct ice_port_info *pi, u16 count, u32 *qset_teid,
 	return status;
 }
 
+/**
+ * ice_aq_get_cgu_input_pin_measure - get input pin signal measurements
+ * @hw: pointer to the HW struct
+ * @dpll_idx: index of dpll to be measured
+ * @meas: array to be filled with results
+ * @meas_num: max number of results array can hold
+ *
+ * Get CGU measurements (0x0C59) of phase and frequency offsets for input
+ * pins on given dpll.
+ *
+ * Return: 0 on success or negative value on failure.
+ */
+int ice_aq_get_cgu_input_pin_measure(struct ice_hw *hw, u8 dpll_idx,
+				     struct ice_cgu_input_measure *meas,
+				     u16 meas_num)
+{
+	struct ice_aqc_get_cgu_input_measure *cmd;
+	struct ice_aq_desc desc;
+
+	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_cgu_input_measure);
+	cmd = &desc.params.get_cgu_input_measure;
+	cmd->dpll_idx_opt = dpll_idx & ICE_AQC_GET_CGU_IN_MEAS_DPLL_IDX_M;
+
+	return ice_aq_send_cmd(hw, &desc, meas, meas_num * sizeof(*meas), NULL);
+}
+
 /**
  * ice_aq_get_cgu_abilities - get cgu abilities
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
index 9b00aa0ddf10..63a741871555 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.h
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
@@ -229,6 +229,9 @@ void ice_replay_post(struct ice_hw *hw);
 struct ice_q_ctx *
 ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle);
 int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in, u16 flag);
+int ice_aq_get_cgu_input_pin_measure(struct ice_hw *hw, u8 dpll_idx,
+				     struct ice_cgu_input_measure *meas,
+				     u16 meas_num);
 int
 ice_aq_get_cgu_abilities(struct ice_hw *hw,
 			 struct ice_aqc_get_cgu_abilities *abilities);
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 614a813c7772..2986774ab58a 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -11,6 +11,8 @@
 #define ICE_DPLL_RCLK_NUM_PER_PF		1
 #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT	25
 #define ICE_DPLL_PIN_GEN_RCLK_FREQ		1953125
+#define ICE_DPLL_INPUT_REF_NUM			10
+#define ICE_DPLL_PHASE_OFFSET_PERIOD		2
 
 /**
  * enum ice_dpll_pin_type - enumerate ice pin types:
@@ -587,6 +589,63 @@ static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
 	return 0;
 }
 
+/**
+ * ice_dpll_features_set - set dpll's features
+ * @dpll: registered dpll pointer
+ * @dpll_priv: private data pointer passed on dpll registration
+ * @features: mask of features to be set
+ * @extack: error reporting
+ *
+ * Dpll subsystem callback. Enable/disable features of dpll.
+ *
+ * Context: Acquires and releases pf->dplls.lock
+ * Return: 0 - success
+ */
+static int ice_dpll_features_set(const struct dpll_device *dpll,
+				 void *dpll_priv, u32 features,
+				 struct netlink_ext_ack *extack)
+{
+	struct ice_dpll *d = dpll_priv;
+	struct ice_pf *pf = d->pf;
+
+	mutex_lock(&pf->dplls.lock);
+	if (features & DPLL_FEATURES_ALL_INPUTS_PHASE_OFFSET_MONITOR)
+		d->phase_offset_monitor_period = ICE_DPLL_PHASE_OFFSET_PERIOD;
+	else
+		d->phase_offset_monitor_period = 0;
+	mutex_unlock(&pf->dplls.lock);
+
+	return 0;
+}
+
+/**
+ * ice_dpll_features_get - get dpll's features
+ * @dpll: registered dpll pointer
+ * @dpll_priv: private data pointer passed on dpll registration
+ * @features: on success holds currently enabled features of dpll
+ * @extack: error reporting
+ *
+ * Dpll subsystem callback. Provides currently enabled features of dpll.
+ *
+ * Context: Acquires and releases pf->dplls.lock
+ * Return: 0 - success
+ */
+static int ice_dpll_features_get(const struct dpll_device *dpll,
+				 void *dpll_priv, u32 *features,
+				 struct netlink_ext_ack *extack)
+{
+	struct ice_dpll *d = dpll_priv;
+	struct ice_pf *pf = d->pf;
+
+	mutex_lock(&pf->dplls.lock);
+	*features = 0;
+	if (d->phase_offset_monitor_period)
+		*features |= DPLL_FEATURES_ALL_INPUTS_PHASE_OFFSET_MONITOR;
+	mutex_unlock(&pf->dplls.lock);
+
+	return 0;
+}
+
 /**
  * ice_dpll_pin_state_set - set pin's state on dpll
  * @pin: pointer to a pin
@@ -1093,12 +1152,15 @@ ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
 			  const struct dpll_device *dpll, void *dpll_priv,
 			  s64 *phase_offset, struct netlink_ext_ack *extack)
 {
+	struct ice_dpll_pin *p = pin_priv;
 	struct ice_dpll *d = dpll_priv;
 	struct ice_pf *pf = d->pf;
 
 	mutex_lock(&pf->dplls.lock);
 	if (d->active_input == pin)
 		*phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
+	else if (d->phase_offset_monitor_period)
+		*phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
 	else
 		*phase_offset = 0;
 	mutex_unlock(&pf->dplls.lock);
@@ -1457,6 +1519,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
 static const struct dpll_device_ops ice_dpll_ops = {
 	.lock_status_get = ice_dpll_lock_status_get,
 	.mode_get = ice_dpll_mode_get,
+	.features_set = ice_dpll_features_set,
+	.features_get = ice_dpll_features_get,
 };
 
 /**
@@ -1503,6 +1567,110 @@ static void ice_dpll_notify_changes(struct ice_dpll *d)
 	}
 }
 
+/**
+ * ice_dpll_is_pps_phase_monitor - check if dpll capable of phase offset monitor
+ * @pf: pf private structure
+ *
+ * Check if firmware is capable of supporting admin command to provide
+ * phase offset monitoring on all the input pins on PPS dpll.
+ *
+ * Returns:
+ * * true - PPS dpll phase offset monitoring is supported
+ * * false - PPS dpll phase offset monitoring is not supported
+ */
+static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
+{
+	struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
+	int ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
+						   ARRAY_SIZE(meas));
+
+	if (ret && pf->hw.adminq.sq_last_status == ICE_AQ_RC_ESRCH)
+		return false;
+
+	return true;
+}
+
+/**
+ * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes
+ * @pins: array of ice_dpll_pin pointers registered within dpll subsystem
+ * @pin_num: number of pins
+ * @phase_offset_ntf_mask: bitmask of pin indexes to notify
+ *
+ * Iterate over array of pins and call dpll subsystem pin notify if
+ * corresponding pin index within bitmask is set.
+ *
+ * Context: Must be called while pf->dplls.lock is released.
+ */
+static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins,
+				      u8 pin_num,
+				      u32 phase_offset_ntf_mask)
+{
+	int i = 0;
+
+	for (i = 0; i < pin_num; i++)
+		if (phase_offset_ntf_mask & (1 << i))
+			dpll_pin_change_ntf(pins[i].pin);
+}
+
+/**
+ * ice_dpll_pps_update_phase_offsets - update phase offset measurements
+ * @pf: pf private structure
+ * @phase_offset_pins_updated: returns mask of updated input pin indexes
+ *
+ * Read phase offset measurements for PPS dpll device and store values in
+ * input pins array. On success phase_offset_pins_updated - fills bitmask of
+ * updated input pin indexes, pins shall be notified.
+ *
+ * Context: Shall be called with pf->dplls.lock being locked.
+ * Returns:
+ * * 0 - success or no data available
+ * * negative - AQ failure
+ */
+static int ice_dpll_pps_update_phase_offsets(struct ice_pf *pf,
+					     u32 *phase_offset_pins_updated)
+{
+	struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
+	struct ice_dpll_pin *p;
+	s64 phase_offset, tmp;
+	int i, j, ret;
+
+	*phase_offset_pins_updated = 0;
+	ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
+					       ARRAY_SIZE(meas));
+	if (ret && pf->hw.adminq.sq_last_status == ICE_AQ_RC_EAGAIN) {
+		return 0;
+	} else if (ret) {
+		dev_err(ice_pf_to_dev(pf),
+			"failed to get input pin measurements dpll=%d, ret=%d %s\n",
+			DPLL_TYPE_PPS, ret,
+			ice_aq_str(pf->hw.adminq.sq_last_status));
+		return ret;
+	}
+	for (i = 0; i < pf->dplls.num_inputs; i++) {
+		p = &pf->dplls.inputs[i];
+		phase_offset = 0;
+		for (j = 0; j < ICE_CGU_INPUT_PHASE_OFFSET_BYTES; j++) {
+			tmp = meas[i].phase_offset[j];
+#ifdef __LITTLE_ENDIAN
+			phase_offset += tmp << 8 * j;
+#else
+			phase_offset += tmp << 8 *
+				(ICE_CGU_INPUT_PHASE_OFFSET_BYTES - 1 - j);
+#endif
+		}
+		phase_offset = sign_extend64(phase_offset, 47);
+		if (p->phase_offset != phase_offset) {
+			dev_dbg(ice_pf_to_dev(pf),
+				"phase offset changed for pin:%d old:%llx, new:%llx\n",
+				p->idx, p->phase_offset, phase_offset);
+			p->phase_offset = phase_offset;
+			*phase_offset_pins_updated |= (1 << i);
+		}
+	}
+
+	return 0;
+}
+
 /**
  * ice_dpll_update_state - update dpll state
  * @pf: pf private structure
@@ -1589,14 +1757,19 @@ static void ice_dpll_periodic_work(struct kthread_work *work)
 	struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
 	struct ice_dpll *de = &pf->dplls.eec;
 	struct ice_dpll *dp = &pf->dplls.pps;
+	u32 phase_offset_ntf = 0;
 	int ret = 0;
 
 	if (ice_is_reset_in_progress(pf->state))
 		goto resched;
 	mutex_lock(&pf->dplls.lock);
+	d->periodic_counter++;
 	ret = ice_dpll_update_state(pf, de, false);
 	if (!ret)
 		ret = ice_dpll_update_state(pf, dp, false);
+	if (!ret && dp->phase_offset_monitor_period &&
+	    d->periodic_counter % dp->phase_offset_monitor_period == 0)
+		ret = ice_dpll_pps_update_phase_offsets(pf, &phase_offset_ntf);
 	if (ret) {
 		d->cgu_state_acq_err_num++;
 		/* stop rescheduling this worker */
@@ -1611,6 +1784,9 @@ static void ice_dpll_periodic_work(struct kthread_work *work)
 	mutex_unlock(&pf->dplls.lock);
 	ice_dpll_notify_changes(de);
 	ice_dpll_notify_changes(dp);
+	if (phase_offset_ntf)
+		ice_dpll_pins_notify_mask(d->inputs, d->num_inputs,
+					  phase_offset_ntf);
 
 resched:
 	/* Run twice a second or reschedule if update failed */
@@ -1987,6 +2163,7 @@ ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
  * @d: dpll to be initialized
  * @cgu: if cgu is present and controlled by this NIC
  * @type: type of dpll being initialized
+ * @caps: bitmap of capabilities of dpll
  *
  * Allocate dpll instance for this board in dpll subsystem, if cgu is controlled
  * by this NIC, register dpll with the callback ops.
@@ -1997,7 +2174,7 @@ ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
  */
 static int
 ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
-		   enum dpll_type type)
+		   enum dpll_type type, u32 caps)
 {
 	u64 clock_id = pf->dplls.clock_id;
 	int ret;
@@ -2012,7 +2189,8 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
 	d->pf = pf;
 	if (cgu) {
 		ice_dpll_update_state(pf, d, true);
-		ret = dpll_device_register(d->dpll, type, 0, &ice_dpll_ops, d);
+		ret = dpll_device_register(d->dpll, type, caps, &ice_dpll_ops,
+					   d);
 		if (ret) {
 			dpll_device_put(d->dpll);
 			return ret;
@@ -2426,10 +2604,12 @@ void ice_dpll_init(struct ice_pf *pf)
 	err = ice_dpll_init_info(pf, cgu);
 	if (err)
 		goto err_exit;
-	err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC);
+	err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC, 0);
 	if (err)
 		goto deinit_info;
-	err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS);
+	err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS,
+				 !ice_dpll_is_pps_phase_monitor(pf) ? 0 :
+				 DPLL_FEATURES_ALL_INPUTS_PHASE_OFFSET_MONITOR);
 	if (err)
 		goto deinit_eec;
 	err = ice_dpll_init_pins(pf, cgu);
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
index c320f1bf7d6d..290babeef58f 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
@@ -19,6 +19,7 @@
  * @prop: pin properties
  * @freq: current frequency of a pin
  * @phase_adjust: current phase adjust value
+ * @phase_offset: monitored phase offset value
  */
 struct ice_dpll_pin {
 	struct dpll_pin *pin;
@@ -31,6 +32,7 @@ struct ice_dpll_pin {
 	struct dpll_pin_properties prop;
 	u32 freq;
 	s32 phase_adjust;
+	s64 phase_offset;
 	u8 status;
 };
 
@@ -47,6 +49,7 @@ struct ice_dpll_pin {
  * @input_prio: priorities of each input
  * @dpll_state: current dpll sync state
  * @prev_dpll_state: last dpll sync state
+ * @phase_offset_monitor_period: period for phase offset monitor read frequency
  * @active_input: pointer to active input pin
  * @prev_input: pointer to previous active input pin
  */
@@ -64,6 +67,7 @@ struct ice_dpll {
 	enum dpll_lock_status dpll_state;
 	enum dpll_lock_status prev_dpll_state;
 	enum dpll_mode mode;
+	u32 phase_offset_monitor_period;
 	struct dpll_pin *active_input;
 	struct dpll_pin *prev_input;
 };
@@ -80,6 +84,7 @@ struct ice_dpll {
  * @num_inputs: number of input pins available on dpll
  * @num_outputs: number of output pins available on dpll
  * @cgu_state_acq_err_num: number of errors returned during periodic work
+ * @periodic_counter: counter of periodic work executions
  * @base_rclk_idx: idx of first pin used for clock revocery pins
  * @clock_id: clock_id of dplls
  * @input_phase_adj_max: max phase adjust value for an input pins
@@ -97,6 +102,7 @@ struct ice_dplls {
 	u8 num_inputs;
 	u8 num_outputs;
 	int cgu_state_acq_err_num;
+	u32 periodic_counter;
 	u8 base_rclk_idx;
 	u64 clock_id;
 	s32 input_phase_adj_max;
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 049edeb60104..ff1db5cc94eb 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -7914,6 +7914,10 @@ const char *ice_aq_str(enum ice_aq_err aq_err)
 		return "ICE_AQ_RC_EPERM";
 	case ICE_AQ_RC_ENOENT:
 		return "ICE_AQ_RC_ENOENT";
+	case ICE_AQ_RC_ESRCH:
+		return "ICE_AQ_RC_ESRCH";
+	case ICE_AQ_RC_EAGAIN:
+		return "ICE_AQ_RC_EAGAIN";
 	case ICE_AQ_RC_ENOMEM:
 		return "ICE_AQ_RC_ENOMEM";
 	case ICE_AQ_RC_EBUSY:
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH net-next v1 2/4] dpll: pass capabilities on device register
  2025-04-09 15:25 ` [PATCH net-next v1 2/4] dpll: pass capabilities on device register Arkadiusz Kubalewski
@ 2025-04-09 16:34   ` Loktionov, Aleksandr
  0 siblings, 0 replies; 6+ messages in thread
From: Loktionov, Aleksandr @ 2025-04-09 16:34 UTC (permalink / raw)
  To: Kubalewski, Arkadiusz, donald.hunter@gmail.com, kuba@kernel.org,
	davem@davemloft.net, Dumazet, Eric, pabeni@redhat.com,
	horms@kernel.org, vadim.fedorenko@linux.dev, jiri@resnulli.us,
	Nguyen, Anthony L, Kitszel, Przemyslaw, andrew+netdev@lunn.ch,
	saeedm@nvidia.com, leon@kernel.org, tariqt@nvidia.com,
	jonathan.lemon@gmail.com, richardcochran@gmail.com, Olech, Milena
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	intel-wired-lan@lists.osuosl.org, linux-rdma@vger.kernel.org



> -----Original Message-----
> From: Kubalewski, Arkadiusz <arkadiusz.kubalewski@intel.com>
> Sent: Wednesday, April 9, 2025 5:26 PM
> To: donald.hunter@gmail.com; kuba@kernel.org; davem@davemloft.net;
> Dumazet, Eric <edumazet@google.com>; pabeni@redhat.com;
> horms@kernel.org; vadim.fedorenko@linux.dev; jiri@resnulli.us; Nguyen,
> Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; andrew+netdev@lunn.ch;
> saeedm@nvidia.com; leon@kernel.org; tariqt@nvidia.com;
> jonathan.lemon@gmail.com; richardcochran@gmail.com; Loktionov,
> Aleksandr <aleksandr.loktionov@intel.com>; Olech, Milena
> <milena.olech@intel.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; intel-wired-
> lan@lists.osuosl.org; linux-rdma@vger.kernel.org; Kubalewski, Arkadiusz
> <arkadiusz.kubalewski@intel.com>
> Subject: [PATCH net-next v1 2/4] dpll: pass capabilities on device register
> 
> Add new argument on dpll device register, a capabilities bitmask of features
> supported by the dpll device.
> Provide capability value on dpll device dump.
> 
> Reviewed-by: Milena Olech <milena.olech@intel.com>
> Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> ---
>  drivers/dpll/dpll_core.c                       | 5 ++++-
>  drivers/dpll/dpll_core.h                       | 2 ++
>  drivers/dpll/dpll_netlink.c                    | 2 ++
>  drivers/net/ethernet/intel/ice/ice_dpll.c      | 2 +-
>  drivers/net/ethernet/mellanox/mlx5/core/dpll.c | 2 +-
>  drivers/ptp/ptp_ocp.c                          | 2 +-
>  include/linux/dpll.h                           | 3 ++-
>  7 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index
> 20bdc52f63a5..563ac37c83ad 100644
> --- a/drivers/dpll/dpll_core.c
> +++ b/drivers/dpll/dpll_core.c
> @@ -342,6 +342,7 @@ dpll_device_registration_find(struct dpll_device *dpll,
>   * dpll_device_register - register the dpll device in the subsystem
>   * @dpll: pointer to a dpll
>   * @type: type of a dpll
> + * @capabilities: mask of available features supported by dpll
>   * @ops: ops for a dpll device
>   * @priv: pointer to private information of owner
>   *
> @@ -353,7 +354,8 @@ dpll_device_registration_find(struct dpll_device *dpll,
>   * * negative - error value
>   */
>  int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
> -			 const struct dpll_device_ops *ops, void *priv)
> +			 u32 capabilities, const struct dpll_device_ops *ops,
> +			 void *priv)
>  {
>  	struct dpll_device_registration *reg;
>  	bool first_registration = false;
> @@ -382,6 +384,7 @@ int dpll_device_register(struct dpll_device *dpll, enum
> dpll_type type,
>  	reg->ops = ops;
>  	reg->priv = priv;
>  	dpll->type = type;
> +	dpll->capabilities = capabilities;
>  	first_registration = list_empty(&dpll->registration_list);
>  	list_add_tail(&reg->list, &dpll->registration_list);
>  	if (!first_registration) {
> diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h index
> 2b6d8ef1cdf3..70bbafb9b635 100644
> --- a/drivers/dpll/dpll_core.h
> +++ b/drivers/dpll/dpll_core.h
> @@ -21,6 +21,7 @@
>   * @clock_id:		unique identifier (clock_id) of a dpll
>   * @module:		module of creator
>   * @type:		type of a dpll
> + * @capabilities:	capabilities of a dpll
>   * @pin_refs:		stores pins registered within a dpll
>   * @refcount:		refcount
>   * @registration_list:	list of registered ops and priv data of dpll owners
> @@ -31,6 +32,7 @@ struct dpll_device {
>  	u64 clock_id;
>  	struct module *module;
>  	enum dpll_type type;
> +	u32 capabilities;
>  	struct xarray pin_refs;
>  	refcount_t refcount;
>  	struct list_head registration_list;
> diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index
> c130f87147fa..41aed0d29be2 100644
> --- a/drivers/dpll/dpll_netlink.c
> +++ b/drivers/dpll/dpll_netlink.c
> @@ -591,6 +591,8 @@ dpll_device_get_one(struct dpll_device *dpll, struct
> sk_buff *msg,
>  		return ret;
>  	if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type))
>  		return -EMSGSIZE;
> +	if (nla_put_u32(msg, DPLL_A_CAPABILITIES, dpll->capabilities))
> +		return -EMSGSIZE;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
> b/drivers/net/ethernet/intel/ice/ice_dpll.c
> index bce3ad6ca2a6..614a813c7772 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dpll.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
> @@ -2012,7 +2012,7 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll
> *d, bool cgu,
>  	d->pf = pf;
>  	if (cgu) {
>  		ice_dpll_update_state(pf, d, true);
> -		ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d);
> +		ret = dpll_device_register(d->dpll, type, 0, &ice_dpll_ops, d);
>  		if (ret) {
>  			dpll_device_put(d->dpll);
>  			return ret;
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
> b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
> index 1e5522a19483..0e430f93b047 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
> @@ -444,7 +444,7 @@ static int mlx5_dpll_probe(struct auxiliary_device
> *adev,
>  		goto err_free_mdpll;
>  	}
> 
> -	err = dpll_device_register(mdpll->dpll, DPLL_TYPE_EEC,
> +	err = dpll_device_register(mdpll->dpll, DPLL_TYPE_EEC, 0,
>  				   &mlx5_dpll_device_ops, mdpll);
>  	if (err)
>  		goto err_put_dpll_device;
> diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index
> b25635c5c745..87b9890d8ef2 100644
> --- a/drivers/ptp/ptp_ocp.c
> +++ b/drivers/ptp/ptp_ocp.c
> @@ -4745,7 +4745,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct
> pci_device_id *id)
>  		goto out;
>  	}
> 
> -	err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp);
> +	err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, 0, &dpll_ops, bp);
>  	if (err)
>  		goto out;
> 
> diff --git a/include/linux/dpll.h b/include/linux/dpll.h index
> 5e4f9ab1cf75..dde8dee83dc6 100644
> --- a/include/linux/dpll.h
> +++ b/include/linux/dpll.h
> @@ -171,7 +171,8 @@ dpll_device_get(u64 clock_id, u32 dev_driver_id,
> struct module *module);  void dpll_device_put(struct dpll_device *dpll);
> 
>  int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
> -			 const struct dpll_device_ops *ops, void *priv);
> +			 u32 capabilities, const struct dpll_device_ops *ops,
> +			 void *priv);
> 
>  void dpll_device_unregister(struct dpll_device *dpll,
>  			    const struct dpll_device_ops *ops, void *priv);
> --
> 2.38.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-04-09 16:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-09 15:25 [PATCH net-next v1 0/4] dpll: add all inputs phase offset monitor Arkadiusz Kubalewski
2025-04-09 15:25 ` [PATCH net-next v1 1/4] dpll: add features and capabilities to dpll device spec Arkadiusz Kubalewski
2025-04-09 15:25 ` [PATCH net-next v1 2/4] dpll: pass capabilities on device register Arkadiusz Kubalewski
2025-04-09 16:34   ` Loktionov, Aleksandr
2025-04-09 15:25 ` [PATCH net-next v1 3/4] dpll: features_get/set callbacks Arkadiusz Kubalewski
2025-04-09 15:25 ` [PATCH net-next v1 4/4] ice: add phase offset monitor for all PPS dpll inputs Arkadiusz Kubalewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox