dpll: expose fractional frequency offset value to user
authorJiri Pirko <jiri@nvidia.com>
Wed, 3 Jan 2024 13:28:36 +0000 (14:28 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 5 Jan 2024 15:58:19 +0000 (07:58 -0800)
Add a new netlink attribute to expose fractional frequency offset value
for a pin. Add an op to get the value from the driver.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Acked-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Link: https://lore.kernel.org/r/20240103132838.1501801-2-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/netlink/specs/dpll.yaml
drivers/dpll/dpll_netlink.c
include/linux/dpll.h
include/uapi/linux/dpll.h

index cf8abe1c0550fc5dca46e35d329379e68f412402..b14aed18065f43ce24e9217eefd455814c953efc 100644 (file)
@@ -296,6 +296,16 @@ attribute-sets:
       -
         name: phase-offset
         type: s64
+      -
+        name: fractional-frequency-offset
+        type: sint
+        doc: |
+          The FFO (Fractional Frequency Offset) between the RX and TX
+          symbol rate on the media associated with the pin:
+          (rx_frequency-tx_frequency)/rx_frequency
+          Value is in PPM (parts per million).
+          This may be implemented for example for pin of type
+          PIN_TYPE_SYNCE_ETH_PORT.
   -
     name: pin-parent-device
     subset-of: pin
@@ -460,6 +470,7 @@ operations:
             - phase-adjust-min
             - phase-adjust-max
             - phase-adjust
+            - fractional-frequency-offset
 
       dump:
         pre: dpll-lock-dumpit
index 21c627e9401a2bac8376f3b1956465f17efd90e1..3370dbddb86bdeb6b627fdf741357eeb15ee3676 100644 (file)
@@ -263,6 +263,27 @@ dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
        return 0;
 }
 
+static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
+                           struct dpll_pin_ref *ref,
+                           struct netlink_ext_ack *extack)
+{
+       const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
+       struct dpll_device *dpll = ref->dpll;
+       s64 ffo;
+       int ret;
+
+       if (!ops->ffo_get)
+               return 0;
+       ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
+                          dpll, dpll_priv(dpll), &ffo, extack);
+       if (ret) {
+               if (ret == -ENODATA)
+                       return 0;
+               return ret;
+       }
+       return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, ffo);
+}
+
 static int
 dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
                      struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
@@ -440,6 +461,9 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
                        prop->phase_range.max))
                return -EMSGSIZE;
        ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
+       if (ret)
+               return ret;
+       ret = dpll_msg_add_ffo(msg, pin, ref, extack);
        if (ret)
                return ret;
        if (xa_empty(&pin->parent_refs))
index b1a5f9ca8ee5d39725188fd6bc1863d89402d0df..9cf896ea1d4122f3bc7094e46a5af81b999937dc 100644 (file)
@@ -77,6 +77,9 @@ struct dpll_pin_ops {
                                const struct dpll_device *dpll, void *dpll_priv,
                                const s32 phase_adjust,
                                struct netlink_ext_ack *extack);
+       int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
+                      const struct dpll_device *dpll, void *dpll_priv,
+                      s64 *ffo, struct netlink_ext_ack *extack);
 };
 
 struct dpll_pin_frequency {
index 715a491d2727958db8ba8557d137cc4e0d0d8f5c..b4e947f9bfbcdb411273cd41d8dffec9f1c3a1dd 100644 (file)
@@ -179,6 +179,7 @@ enum dpll_a_pin {
        DPLL_A_PIN_PHASE_ADJUST_MAX,
        DPLL_A_PIN_PHASE_ADJUST,
        DPLL_A_PIN_PHASE_OFFSET,
+       DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
 
        __DPLL_A_PIN_MAX,
        DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)