From 93e23cc51195e3376caa376c9d4784d13cbf199a Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 12:21:58 +0200 Subject: [PATCH 01/36] dpll: spec: regenerate policy max values Regenreate policies after change to ynl-gen-c.py on main net-next. Signed-off-by: Arkadiusz Kubalewski --- drivers/dpll/dpll_nl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index f5d1245deed9..bd16ae3e0640 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -13,9 +13,9 @@ /* Common nested types */ const struct nla_policy dpll_pin_parent_nl_policy[DPLL_A_PIN_STATE + 1] = { [DPLL_A_ID] = { .type = NLA_U32, }, - [DPLL_A_PIN_DIRECTION] = NLA_POLICY_MAX(NLA_U8, 2), + [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U8, 1, 2), [DPLL_A_PIN_PRIO] = { .type = NLA_U32, }, - [DPLL_A_PIN_STATE] = NLA_POLICY_MAX(NLA_U8, 3), + [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U8, 1, 3), [DPLL_A_PIN_ID] = { .type = NLA_U32, }, }; @@ -23,7 +23,7 @@ const struct nla_policy dpll_pin_parent_nl_policy[DPLL_A_PIN_STATE + 1] = { static const struct nla_policy dpll_device_id_get_nl_policy[DPLL_A_TYPE + 1] = { [DPLL_A_MODULE_NAME] = { .type = NLA_NUL_STRING, }, [DPLL_A_CLOCK_ID] = { .type = NLA_U64, }, - [DPLL_A_TYPE] = NLA_POLICY_MAX(NLA_U8, 2), + [DPLL_A_TYPE] = NLA_POLICY_RANGE(NLA_U8, 1, 2), }; /* DPLL_CMD_DEVICE_GET - do */ @@ -35,7 +35,7 @@ static const struct nla_policy dpll_device_get_nl_policy[DPLL_A_MODULE_NAME + 1] /* DPLL_CMD_DEVICE_SET - do */ static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_MODE + 1] = { [DPLL_A_ID] = { .type = NLA_U32, }, - [DPLL_A_MODE] = NLA_POLICY_MAX(NLA_U8, 4), + [DPLL_A_MODE] = NLA_POLICY_RANGE(NLA_U8, 1, 4), }; /* DPLL_CMD_PIN_ID_GET - do */ @@ -45,7 +45,7 @@ static const struct nla_policy dpll_pin_id_get_nl_policy[DPLL_A_PIN_TYPE + 1] = [DPLL_A_PIN_BOARD_LABEL] = { .type = NLA_NUL_STRING, }, [DPLL_A_PIN_PANEL_LABEL] = { .type = NLA_NUL_STRING, }, [DPLL_A_PIN_PACKAGE_LABEL] = { .type = NLA_NUL_STRING, }, - [DPLL_A_PIN_TYPE] = NLA_POLICY_MAX(NLA_U8, 5), + [DPLL_A_PIN_TYPE] = NLA_POLICY_RANGE(NLA_U8, 1, 5), }; /* DPLL_CMD_PIN_GET - do */ @@ -64,10 +64,10 @@ static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PARENT + 1] = { [DPLL_A_ID] = { .type = NLA_U32, }, [DPLL_A_PIN_ID] = { .type = NLA_U32, }, [DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, }, - [DPLL_A_PIN_DIRECTION] = NLA_POLICY_MAX(NLA_U8, 2), + [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U8, 1, 2), [DPLL_A_PIN_PRIO] = { .type = NLA_U32, }, - [DPLL_A_PIN_STATE] = NLA_POLICY_MAX(NLA_U8, 3), - [DPLL_A_PIN_PARENT] = { .type = NLA_NESTED, }, + [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U8, 1, 3), + [DPLL_A_PIN_PARENT] = NLA_POLICY_NESTED(dpll_pin_parent_nl_policy), }; /* Ops table for dpll */ From 4cc392e4f6d054a0def25825a577995e09ca6013 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 12 Jun 2023 16:41:13 +0200 Subject: [PATCH 02/36] dpll: docs: fix docs build warnings Fix warning during docs build on new dpll.rst Co-developed-by: Bagas Sanjaya Signed-off-by: Bagas Sanjaya Signed-off-by: Arkadiusz Kubalewski --- Documentation/driver-api/dpll.rst | 51 +++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst index 8caa4af022ad..cac765f88cfb 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -63,16 +63,19 @@ for the states the user can request for a dpll device. In manual mode (``DPLL_MODE_MANUAL``) the user can request or receive one of following pin states: + - ``DPLL_PIN_STATE_CONNECTED`` - the pin is used to drive dpll device - ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not used to drive dpll device In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request or receive one of following pin states: + - ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid input for automatic selection algorithm - ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as a valid input for automatic selection algorithm + In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can only receive pin state ``DPLL_PIN_STATE_CONNECTED`` once automatic selection algorithm locks a dpll device with one of the inputs. @@ -85,6 +88,7 @@ Shared pins A single pin object can be attached to multiple dpll devices. Then there are two groups of configuration knobs: + 1) Set on a pin - the configuration affects all dpll devices pin is registered to (i.e. ``DPLL_A_PIN_FREQUENCY``), 2) Set on a pin-dpll tuple - the configuration affects only selected @@ -103,31 +107,32 @@ with. If a pin was registered with multiple parent pins, they behave like a multiple output multiplexer. In this case output of a ``DPLL_CMD_PIN_GET`` would contain multiple pin-parent nested -attributes with current state related to each parent, like: - -``'pin': [{ - {'clock-id': 282574471561216, - 'module-name': 'ice', - 'pin-dpll-caps': 4, - 'pin-id': 13, - 'pin-parent': [{'pin-id': 2, 'pin-state': 'connected'}, - {'pin-id': 3, 'pin-state': 'disconnected'}, - {'id': 0, 'pin-direction': 'input'}, - {'id': 1, 'pin-direction': 'input'}], - 'pin-type': 'synce-eth-port'} -}]`` +attributes with current state related to each parent, like:: + + 'pin': [{ + {'clock-id': 282574471561216, + 'module-name': 'ice', + 'pin-dpll-caps': 4, + 'pin-id': 13, + 'pin-parent': [{'pin-id': 2, 'pin-state': 'connected'}, + {'pin-id': 3, 'pin-state': 'disconnected'}, + {'id': 0, 'pin-direction': 'input'}, + {'id': 1, 'pin-direction': 'input'}], + 'pin-type': 'synce-eth-port'} + }] Only one child pin can provide its signal to the parent MUX-type pin at a time, the selection is done by requesting change of a child pin state on desired parent, with the use of ``DPLL_A_PIN_PARENT`` nested attribute. Example of netlink `set state on parent pin` message format: - ===================== ============================================= + ====================== ============================================= ``DPLL_A_PIN_ID`` child pin id ``DPLL_A_PIN_PARENT`` nested attribute for requesting configuration related to parent pin ``DPLL_A_PIN_ID`` parent pin id ``DPLL_A_PIN_STATE`` requested pin state on parent + ====================== ============================================= Pin priority ============ @@ -149,6 +154,7 @@ device. Example of netlink `set priority on parent pin` message format: related to parent pin ``DPLL_A_ID`` parent dpll id ``DPLL_A_PIN_PRIO`` requested pin prio on parent dpll + ===================== ============================================= Child pin of MUX-type is not capable of automatic input pin selection, in order to configure a input of a MUX-type pin, the user needs to @@ -254,6 +260,7 @@ prefix and suffix according to attribute purpose: ``DPLL_A_PIN_STATE`` attr requested state of pin on the dpll device or on the parent pin + ==================================== ================================= Netlink dump requests ===================== @@ -303,6 +310,7 @@ Values for ``DPLL_A_LOCK_STATUS`` attribute: acquired ``DPLL_LOCK_STATUS_HOLDOVER`` dpll device lost a lock, using its frequency holdover capabilities + ================================== =================================== Values for ``DPLL_A_MODE`` attribute: @@ -316,12 +324,14 @@ Values for ``DPLL_A_MODE`` attribute: ``DPLL_MODE_HOLDOVER`` force holdover mode of dpll ``DPLL_MODE_FREERUN`` dpll device is driven by supplied system clock without holdover capabilities + ======================= ============================================== Values for ``DPLL_A_TYPE`` attribute: ================= =================================================== ``DPLL_TYPE_PPS`` dpll device used to provide pulse-per-second output ``DPLL_TYPE_EEC`` dpll device used to drive ethernet equipment clock + ================= =================================================== Pin level configuration pre-defined enums ========================================= @@ -334,6 +344,7 @@ Values for ``DPLL_A_PIN_STATE`` attribute: ``DPLL_PIN_STATE_DISCONNECTED`` Pin disconnected from a dpll device or from a parent pin ``DPLL_PIN_STATE_SELECTABLE`` Pin enabled for automatic selection + =============================== ====================================== Values for ``DPLL_A_PIN_DIRECTION`` attribute: @@ -342,6 +353,7 @@ Values for ``DPLL_A_PIN_DIRECTION`` attribute: device ``DPLL_PIN_DIRECTION_OUTPUT`` used to output the signal from a dpll device + ============================= ==================================== Values for ``DPLL_A_PIN_TYPE`` attributes: @@ -353,6 +365,7 @@ Values for ``DPLL_A_PIN_TYPE`` attributes: ``DPLL_PIN_TYPE_INT_OSCILLATOR`` Internal Oscillator (i.e. Holdover with Atomic Clock as an input) ``DPLL_PIN_TYPE_GNSS`` GNSS 1PPS input + ================================ ===================================== Values for ``DPLL_A_PIN_DPLL_CAPS`` attributes: @@ -363,6 +376,7 @@ Values for ``DPLL_A_PIN_DPLL_CAPS`` attributes: can change ``DPLL_PIN_CAPS_STATE_CAN_CHANGE`` Bit present if state of pin can change + ====================================== =============================== Notifications ============= @@ -381,6 +395,7 @@ Notifications messages: ``DPLL_CMD_PIN_CREATE_NTF`` dpll pin was created ``DPLL_CMD_PIN_DELETE_NTF`` dpll pin was deleted ``DPLL_CMD_PIN_CHANGE_NTF`` dpll pin has changed + ============================== ===================================== Events format is the same as for the corresponding get command. Format of ``DPLL_CMD_DEVICE_`` events is the same as response of @@ -413,6 +428,7 @@ increases. Also dpll_pin_put() works similarly to dpll_device_put(). A pin can be registered with parent dpll device or parent pin, depending on hardware needs. Each registration requires registerer to provide set of pin callbacks, and private data pointer for calling them: + - dpll_pin_register() - register pin with a dpll device, - dpll_pin_on_pin_register() - register pin with another MUX type pin. @@ -422,6 +438,7 @@ Notifications about registering/deregistering pins are also invoked by the subsystem. Notifications about status changes either of dpll device or a pin are invoked in two ways: + - after successful change was requested on dpll subsystem, the subsystem calls corresponding notification, - requested by device driver with dpll_device_change_ntf() or @@ -431,10 +448,12 @@ The device driver using dpll interface is not required to implement all the callback operation. Neverthelessi, there are few required to be implemented. Required dpll device level callback operations: + - ``.mode_get``, - ``.lock_status_get``. Required pin level callback operations: + - ``.state_get`` (pins registered with dpll device), - ``.state_on_pin_get`` (pins registered with parent pin), - ``.direction_get``. @@ -451,8 +470,8 @@ inputs. In such scenario, dpll device input signal shall be also configurable to drive dpll with signal recovered from the PHY netdevice. This is done by exposing a pin to the netdevice - attaching pin to the -netdevice itself with: -netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); +netdevice itself with +``netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)``. Exposed pin id handle ``DPLL_A_PIN_ID`` is then identifiable by the user as it is attached to rtnetlink respond to get ``RTM_NEWLINK`` command in nested attribute ``IFLA_DPLL_PIN``. From 1b60d8478ca3c2402d54614202c51ddc2ce7f016 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Tue, 13 Jun 2023 13:54:57 +0200 Subject: [PATCH 03/36] dpll: spec: add missing enum descriptions The descriptions are required for proper generation of kdoc. Signed-off-by: Arkadiusz Kubalewski --- Documentation/netlink/specs/dpll.yaml | 3 +++ include/uapi/linux/dpll.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml index f7317003d312..69ce8bae72be 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -164,10 +164,13 @@ definitions: entries: - name: direction-can-change + doc: pin direction can be changed - name: priority-can-change + doc: pin prority can be changed - name: state-can-change + doc: pin state can be changed attribute-sets: - diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index d99d7dc20670..d97d50adde21 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -126,6 +126,9 @@ enum dpll_pin_state { /** * enum dpll_pin_caps - defines possible capabilities of a pin, valid flags on * DPLL_A_PIN_CAPS attribute + * @DPLL_PIN_CAPS_DIRECTION_CAN_CHANGE: pin direction can be changed + * @DPLL_PIN_CAPS_PRIORITY_CAN_CHANGE: pin prority can be changed + * @DPLL_PIN_CAPS_STATE_CAN_CHANGE: pin state can be changed */ enum dpll_pin_caps { DPLL_PIN_CAPS_DIRECTION_CAN_CHANGE = 1, From 0838b5e629b797cdb2b98a4ecfb52772195c3a42 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Tue, 13 Jun 2023 17:37:52 +0200 Subject: [PATCH 04/36] dpll: docs: separate netlink command/attribute list Separate commands and corresponding attributes from each other, previously generated docs consisted of single table contatining all the attributes and commands within one table, this was unreadable. Signed-off-by: Arkadiusz Kubalewski --- Documentation/driver-api/dpll.rst | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst index cac765f88cfb..42737584f232 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -182,11 +182,14 @@ prefix and suffix according to attribute purpose: ==================================== ================================= ``DPLL_CMD_DEVICE_ID_GET`` command to get device ID - ``DPLL_A_MODULE_NAME`` attr module name of registerer + ``DPLL_A_MODULE_NAME`` attr module name of registerer ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier (EUI-64), as defined by the IEEE 1588 standard ``DPLL_A_TYPE`` attr type of dpll device + ==================================== ================================= + + ==================================== ================================= ``DPLL_CMD_DEVICE_GET`` command to get device info or dump list of available devices ``DPLL_A_ID`` attr unique dpll device ID @@ -199,9 +202,15 @@ prefix and suffix according to attribute purpose: ``DPLL_A_LOCK_STATUS`` attr dpll device lock status ``DPLL_A_TEMP`` attr device temperature info ``DPLL_A_TYPE`` attr type of dpll device + ==================================== ================================= + + ==================================== ================================= ``DPLL_CMD_DEVICE_SET`` command to set dpll device config ``DPLL_A_ID`` attr internal dpll device index ``DPLL_A_MODE`` attr selection mode to configure + ==================================== ================================= + + ==================================== ================================= ``DPLL_CMD_PIN_GET`` command to get pin ID ``DPLL_A_MODULE_NAME`` attr module name of registerer ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier @@ -214,6 +223,9 @@ prefix and suffix according to attribute purpose: ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided by registerer ``DPLL_A_PIN_TYPE`` attr type of a pin + ==================================== ================================= + + ==================================== ================================= ``DPLL_CMD_PIN_GET`` command to get pin info or dump list of available pins ``DPLL_A_PIN_ID`` attr unique a pin ID @@ -245,6 +257,9 @@ prefix and suffix according to attribute purpose: device or on the parent pin ``DPLL_A_PIN_DPLL_CAPS`` attr bitmask of pin-dpll capabilities + ==================================== ================================= + + ==================================== ================================= ``DPLL_CMD_PIN_SET`` command to set pins configuration ``DPLL_A_PIN_ID`` attr unique a pin ID ``DPLL_A_PIN_DIRECTION`` attr requested direction of a pin From bd03467e500cc142dc63444ccd335f17cf4cf555 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Tue, 13 Jun 2023 17:41:22 +0200 Subject: [PATCH 05/36] dpll: docs: replace enum description with uapi header Use uapi header to list enum values and their description, instead of using redundant explanation of their existence. Signed-off-by: Arkadiusz Kubalewski --- Documentation/driver-api/dpll.rst | 85 ++----------------------------- 1 file changed, 3 insertions(+), 82 deletions(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst index 42737584f232..e494527b2379 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -309,89 +309,10 @@ In general, it is possible to configure multiple parameters at once, but internally each parameter change will be invoked separately, where order of configuration is not guaranteed by any means. -Device level configuration pre-defined enums -================================================= +Configuration pre-defined enums +=============================== -Values for ``DPLL_A_LOCK_STATUS`` attribute: - - ================================== =================================== - ``DPLL_LOCK_STATUS_UNLOCKED`` dpll device is in freerun, not - locked to any input pin - ``DPLL_LOCK_STATUS_LOCKED`` dpll device is locked to the input - but no holdover capability yet - acquired - ``DPLL_LOCK_STATUS_LOCKED_HO_ACQ`` dpll device is locked to the input - pin with holdover capability - acquired - ``DPLL_LOCK_STATUS_HOLDOVER`` dpll device lost a lock, using its - frequency holdover capabilities - ================================== =================================== - -Values for ``DPLL_A_MODE`` attribute: - - ======================= ============================================== - ``DPLL_MODE_MANUAL`` input pin is manually selected by setting pin - state to ``DPLL_PIN_STATE_CONNECTED`` on a - dpll device - ``DPLL_MODE_AUTOMATIC`` input pin is auto selected according to - configured pin priorities and input signal - validity - ``DPLL_MODE_HOLDOVER`` force holdover mode of dpll - ``DPLL_MODE_FREERUN`` dpll device is driven by supplied system clock - without holdover capabilities - ======================= ============================================== - -Values for ``DPLL_A_TYPE`` attribute: - - ================= =================================================== - ``DPLL_TYPE_PPS`` dpll device used to provide pulse-per-second output - ``DPLL_TYPE_EEC`` dpll device used to drive ethernet equipment clock - ================= =================================================== - -Pin level configuration pre-defined enums -========================================= - -Values for ``DPLL_A_PIN_STATE`` attribute: - - =============================== ====================================== - ``DPLL_PIN_STATE_CONNECTED`` Pin used as active input for a dpll - device or for a parent pin - ``DPLL_PIN_STATE_DISCONNECTED`` Pin disconnected from a dpll device or - from a parent pin - ``DPLL_PIN_STATE_SELECTABLE`` Pin enabled for automatic selection - =============================== ====================================== - -Values for ``DPLL_A_PIN_DIRECTION`` attribute: - - ============================= ==================================== - ``DPLL_PIN_DIRECTION_INPUT`` used to provide its signal to a dpll - device - ``DPLL_PIN_DIRECTION_OUTPUT`` used to output the signal from a dpll - device - ============================= ==================================== - -Values for ``DPLL_A_PIN_TYPE`` attributes: - - ================================ ===================================== - ``DPLL_PIN_TYPE_MUX`` MUX type pin, connected pins shall - have their own types - ``DPLL_PIN_TYPE_EXT`` External pin - ``DPLL_PIN_TYPE_SYNCE_ETH_PORT`` SyncE on Ethernet port - ``DPLL_PIN_TYPE_INT_OSCILLATOR`` Internal Oscillator (i.e. Holdover - with Atomic Clock as an input) - ``DPLL_PIN_TYPE_GNSS`` GNSS 1PPS input - ================================ ===================================== - -Values for ``DPLL_A_PIN_DPLL_CAPS`` attributes: - - ====================================== =============================== - ``DPLL_PIN_CAPS_DIRECTION_CAN_CHANGE`` Bit present if direction of - pin can change - ``DPLL_PIN_CAPS_PRIORITY_CAN_CHANGE`` Bit present if priority of pin - can change - ``DPLL_PIN_CAPS_STATE_CAN_CHANGE`` Bit present if state of pin can - change - ====================================== =============================== +.. kernel-doc:: include/uapi/linux/dpll.h Notifications ============= From 4d11b668567808f7ab10cd6e1342c7997c6e6c2d Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Wed, 14 Jun 2023 00:49:04 +0200 Subject: [PATCH 06/36] dpll: docs: add DPLL chapter Add brief explanation what is a DPLL. Signed-off-by: Arkadiusz Kubalewski --- Documentation/driver-api/dpll.rst | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst index e494527b2379..1bcc7effc3cc 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -4,10 +4,25 @@ The Linux kernel dpll subsystem =============================== +DPLL +==== + +PLL - Phase Locked Loop is an electronic circuit which syntonizes clock +signal of a device with an external clock signal. Effectively enabling +device to run on the same clock signal beat as provided on a PLL input. + +DPLL - Digital Phase Locked Loop is am integrated circuit which in +addition to plain PLL behavior incorporates a digital phase detector +and may have digital divider in the loop. As a result, the frequency on +DPLL's input and output may be configurable. + +Subsystem +========= + The main purpose of dpll subsystem is to provide general interface to configure devices that use any kind of Digital PLL and could use -different sources of signal to synchronize to as well as different -types of outputs. +different sources of input signal to synchronize to, as well as +different types of outputs. The main interface is NETLINK_GENERIC based protocol with an event monitoring multicast group defined. From 6d06a2cb9cf9f9f5a7b010938f1ce18e48582fd6 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 13:55:03 +0200 Subject: [PATCH 07/36] dpll: spec: split pin-parent nest split the nest into separated nests: - pin-parent-device - for configuration of pin-device tuple, - pin-parent-pin - for configuration od pin-pin tuple. Signed-off-by: Arkadiusz Kubalewski --- Documentation/netlink/specs/dpll.yaml | 29 ++++++++++++++++++--------- drivers/dpll/dpll_nl.c | 14 +++++++------ drivers/dpll/dpll_nl.h | 3 ++- include/uapi/linux/dpll.h | 3 ++- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml index 69ce8bae72be..e1283fc15e91 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -252,12 +252,17 @@ attribute-sets: name: pin-dpll-caps type: u32 - - name: pin-parent + name: pin-parent-device type: nest multi-attr: true - nested-attributes: pin-parent + nested-attributes: pin-parent-device + - + name: pin-parent-pin + type: nest + multi-attr: true + nested-attributes: pin-parent-pin - - name: pin-parent + name: pin-parent-device subset-of: dpll attributes: - @@ -272,10 +277,16 @@ attribute-sets: - name: pin-state type: u8 + - + name: pin-parent-pin + subset-of: dpll + attributes: + - + name: pin-state + type: u8 - name: pin-id type: u32 - - name: pin-frequency-range subset-of: dpll @@ -388,7 +399,7 @@ operations: - pin-type reply: attributes: - - id + - pin-id - name: pin-get @@ -407,7 +418,6 @@ operations: post: dpll-pin-post-doit request: attributes: - - id - pin-id reply: &pin-attrs attributes: @@ -418,8 +428,9 @@ operations: - pin-type - pin-frequency - pin-frequency-supported - - pin-parent - pin-dpll-caps + - pin-parent-device + - pin-parent-pin dump: pre: dpll-lock-dumpit @@ -440,13 +451,13 @@ operations: post: dpll-pin-post-doit request: attributes: - - id - pin-id - pin-frequency - pin-direction - pin-prio - pin-state - - pin-parent + - pin-parent-device + - pin-parent-pin - name: pin-create-ntf doc: Notification about pin appearing diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index bd16ae3e0640..aa40a4879ae1 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -11,11 +11,14 @@ #include /* Common nested types */ -const struct nla_policy dpll_pin_parent_nl_policy[DPLL_A_PIN_STATE + 1] = { +const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_STATE + 1] = { [DPLL_A_ID] = { .type = NLA_U32, }, [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U8, 1, 2), [DPLL_A_PIN_PRIO] = { .type = NLA_U32, }, [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U8, 1, 3), +}; +const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1] = { + [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U8, 1, 3), [DPLL_A_PIN_ID] = { .type = NLA_U32, }, }; @@ -50,7 +53,6 @@ static const struct nla_policy dpll_pin_id_get_nl_policy[DPLL_A_PIN_TYPE + 1] = /* DPLL_CMD_PIN_GET - do */ static const struct nla_policy dpll_pin_get_do_nl_policy[DPLL_A_PIN_ID + 1] = { - [DPLL_A_ID] = { .type = NLA_U32, }, [DPLL_A_PIN_ID] = { .type = NLA_U32, }, }; @@ -60,14 +62,14 @@ static const struct nla_policy dpll_pin_get_dump_nl_policy[DPLL_A_ID + 1] = { }; /* DPLL_CMD_PIN_SET - do */ -static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PARENT + 1] = { - [DPLL_A_ID] = { .type = NLA_U32, }, +static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PARENT_PIN + 1] = { [DPLL_A_PIN_ID] = { .type = NLA_U32, }, [DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, }, [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U8, 1, 2), [DPLL_A_PIN_PRIO] = { .type = NLA_U32, }, [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U8, 1, 3), - [DPLL_A_PIN_PARENT] = NLA_POLICY_NESTED(dpll_pin_parent_nl_policy), + [DPLL_A_PIN_PARENT_DEVICE] = NLA_POLICY_NESTED(dpll_pin_parent_device_nl_policy), + [DPLL_A_PIN_PARENT_PIN] = NLA_POLICY_NESTED(dpll_pin_parent_pin_nl_policy), }; /* Ops table for dpll */ @@ -139,7 +141,7 @@ static const struct genl_split_ops dpll_nl_ops[] = { .doit = dpll_nl_pin_set_doit, .post_doit = dpll_pin_post_doit, .policy = dpll_pin_set_nl_policy, - .maxattr = DPLL_A_PIN_PARENT, + .maxattr = DPLL_A_PIN_PARENT_PIN, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, }; diff --git a/drivers/dpll/dpll_nl.h b/drivers/dpll/dpll_nl.h index 54d493778888..1f67aaed4742 100644 --- a/drivers/dpll/dpll_nl.h +++ b/drivers/dpll/dpll_nl.h @@ -12,7 +12,8 @@ #include /* Common nested types */ -extern const struct nla_policy dpll_pin_parent_nl_policy[DPLL_A_PIN_STATE + 1]; +extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_STATE + 1]; +extern const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1]; int dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb, struct genl_info *info); diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index d97d50adde21..72867857ac07 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -158,7 +158,8 @@ enum dpll_a { DPLL_A_PIN_PRIO, DPLL_A_PIN_STATE, DPLL_A_PIN_DPLL_CAPS, - DPLL_A_PIN_PARENT, + DPLL_A_PIN_PARENT_DEVICE, + DPLL_A_PIN_PARENT_PIN, __DPLL_A_MAX, DPLL_A_MAX = (__DPLL_A_MAX - 1) From 6ecfc42a4ba67984c29e24caa1b7fb3120147489 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 14:22:43 +0200 Subject: [PATCH 08/36] dpll: core: netlink: split pin-parent nest split the nest into separated nests: - pin-parent-device - for configuration of pin-device tuple, - pin-parent-pin - for configuration od pin-pin tuple. Signed-off-by: Arkadiusz Kubalewski --- drivers/dpll/dpll_netlink.c | 99 ++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 40 deletions(-) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index e6efc17aaf26..893e7ef1342b 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -211,7 +211,7 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin, ppin, parent_priv, &state, extack); if (ret) return -EFAULT; - nest = nla_nest_start(msg, DPLL_A_PIN_PARENT); + nest = nla_nest_start(msg, DPLL_A_PIN_PARENT_PIN); if (!nest) return -EMSGSIZE; ret = dpll_msg_add_pin_handle(msg, ppin); @@ -241,7 +241,7 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin, int ret; xa_for_each(&pin->dpll_refs, index, ref) { - attr = nla_nest_start(msg, DPLL_A_PIN_PARENT); + attr = nla_nest_start(msg, DPLL_A_PIN_PARENT_DEVICE); if (!attr) return -EMSGSIZE; ret = dpll_msg_add_dev_handle(msg, ref->dpll); @@ -523,55 +523,45 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll, } static int -dpll_pin_parent_set(struct dpll_pin *pin, struct nlattr *parent_nest, - struct netlink_ext_ack *extack) +dpll_pin_parent_device_set(struct dpll_pin *pin, struct nlattr *parent_nest, + struct netlink_ext_ack *extack) { struct nlattr *tb[DPLL_A_MAX + 1]; enum dpll_pin_direction direction; - u32 ppin_idx, pdpll_idx, prio; enum dpll_pin_state state; struct dpll_pin_ref *ref; struct dpll_device *dpll; + u32 pdpll_idx, prio; int ret; nla_parse_nested(tb, DPLL_A_MAX, parent_nest, NULL, extack); - if ((tb[DPLL_A_ID] && tb[DPLL_A_PIN_ID]) || - !(tb[DPLL_A_ID] || tb[DPLL_A_PIN_ID])) { - NL_SET_ERR_MSG(extack, "one parent id expected"); + if (!tb[DPLL_A_ID]) { + NL_SET_ERR_MSG(extack, "device parent id expected"); return -EINVAL; } - if (tb[DPLL_A_ID]) { - pdpll_idx = nla_get_u32(tb[DPLL_A_ID]); - dpll = xa_load(&dpll_device_xa, pdpll_idx); - if (!dpll) - return -EINVAL; - ref = xa_load(&pin->dpll_refs, dpll->device_idx); - if (!ref) - return -EINVAL; - if (tb[DPLL_A_PIN_STATE]) { - state = nla_get_u8(tb[DPLL_A_PIN_STATE]); - ret = dpll_pin_state_set(dpll, pin, state, extack); - if (ret) - return ret; - } - if (tb[DPLL_A_PIN_PRIO]) { - prio = nla_get_u8(tb[DPLL_A_PIN_PRIO]); - ret = dpll_pin_prio_set(dpll, pin, prio, extack); - if (ret) - return ret; - } - if (tb[DPLL_A_PIN_DIRECTION]) { - direction = nla_get_u8(tb[DPLL_A_PIN_DIRECTION]); - ret = dpll_pin_direction_set(pin, dpll, direction, - extack); - if (ret) - return ret; - } - } else if (tb[DPLL_A_PIN_ID]) { - ppin_idx = nla_get_u32(tb[DPLL_A_PIN_ID]); + pdpll_idx = nla_get_u32(tb[DPLL_A_ID]); + dpll = xa_load(&dpll_device_xa, pdpll_idx); + if (!dpll) + return -EINVAL; + ref = xa_load(&pin->dpll_refs, dpll->device_idx); + if (!ref) + return -EINVAL; + if (tb[DPLL_A_PIN_STATE]) { state = nla_get_u8(tb[DPLL_A_PIN_STATE]); - ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack); + ret = dpll_pin_state_set(dpll, pin, state, extack); + if (ret) + return ret; + } + if (tb[DPLL_A_PIN_PRIO]) { + prio = nla_get_u8(tb[DPLL_A_PIN_PRIO]); + ret = dpll_pin_prio_set(dpll, pin, prio, extack); + if (ret) + return ret; + } + if (tb[DPLL_A_PIN_DIRECTION]) { + direction = nla_get_u8(tb[DPLL_A_PIN_DIRECTION]); + ret = dpll_pin_direction_set(pin, dpll, direction, extack); if (ret) return ret; } @@ -579,6 +569,30 @@ dpll_pin_parent_set(struct dpll_pin *pin, struct nlattr *parent_nest, return 0; } +static int +dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest, + struct netlink_ext_ack *extack) +{ + struct nlattr *tb[DPLL_A_MAX + 1]; + enum dpll_pin_state state; + u32 ppin_idx; + int ret; + + nla_parse_nested(tb, DPLL_A_MAX, parent_nest, + NULL, extack); + if (!tb[DPLL_A_PIN_ID]) { + NL_SET_ERR_MSG(extack, "parent pin id expected"); + return -EINVAL; + } + ppin_idx = nla_get_u32(tb[DPLL_A_PIN_ID]); + state = nla_get_u8(tb[DPLL_A_PIN_STATE]); + ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack); + if (ret) + return ret; + + return 0; +} + static int dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info) { @@ -593,8 +607,13 @@ dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info) if (ret) return ret; break; - case DPLL_A_PIN_PARENT: - ret = dpll_pin_parent_set(pin, a, info->extack); + case DPLL_A_PIN_PARENT_DEVICE: + ret = dpll_pin_parent_device_set(pin, a, info->extack); + if (ret) + return ret; + break; + case DPLL_A_PIN_PARENT_PIN: + ret = dpll_pin_parent_pin_set(pin, a, info->extack); if (ret) return ret; break; From fd936c010f24219e259661e67eb65c9fe63c0c7a Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 14:25:25 +0200 Subject: [PATCH 09/36] dpll: docs: fix EOPNOTSUPP typo Fix typo ENOTSUPP -> EOPNOTSUPP. Signed-off-by: Arkadiusz Kubalewski --- Documentation/driver-api/dpll.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst index 1bcc7effc3cc..6e88990b3bc6 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -410,7 +410,7 @@ Required pin level callback operations: - ``.direction_get``. Every other operation handler is checked for existence and -``-ENOTSUPP`` is returned in case of absence of specific handler. +``-EOPNOTSUPP`` is returned in case of absence of specific handler. SyncE enablement ================ From 1de17be5a4db64cda30c134a46d98f49e5b346f5 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 14:43:27 +0200 Subject: [PATCH 10/36] dpll: spec: fix typos s/working-modes/working modes/ s/differentiate/differentiates/ s/valid input, auto selected by dpll/input pin auto selected by dpll/ Signed-off-by: Arkadiusz Kubalewski --- Documentation/netlink/specs/dpll.yaml | 4 ++-- include/uapi/linux/dpll.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml index e1283fc15e91..72054da45440 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -9,7 +9,7 @@ definitions: type: enum name: mode doc: | - working-modes a dpll can support, differentiate if and how dpll selects + working modes a dpll can support, differentiates if and how dpll selects one of its inputs to syntonize with it, valid values for DPLL_A_MODE attribute entries: @@ -19,7 +19,7 @@ definitions: value: 1 - name: automatic - doc: highest prio, valid input, auto selected by dpll + doc: highest prio input pin auto selected by dpll - name: holdover doc: dpll forced into holdover mode diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index 72867857ac07..527c8ca6d2bf 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -10,11 +10,11 @@ #define DPLL_FAMILY_VERSION 1 /** - * enum dpll_mode - working-modes a dpll can support, differentiate if and how + * enum dpll_mode - working modes a dpll can support, differentiates if and how * dpll selects one of its inputs to syntonize with it, valid values for * DPLL_A_MODE attribute * @DPLL_MODE_MANUAL: input can be only selected by sending a request to dpll - * @DPLL_MODE_AUTOMATIC: highest prio, valid input, auto selected by dpll + * @DPLL_MODE_AUTOMATIC: highest prio input pin auto selected by dpll * @DPLL_MODE_HOLDOVER: dpll forced into holdover mode * @DPLL_MODE_FREERUN: dpll driven on system clk */ From 1de616bee227d1ee206ec49ca99082c3e4c8a695 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 15:23:50 +0200 Subject: [PATCH 11/36] dpll: spec: remove FREERUN and HOLDOVER modes Modes are not yet used by any of the drivers, remove them. Signed-off-by: Arkadiusz Kubalewski --- Documentation/netlink/specs/dpll.yaml | 18 +++++------------- drivers/dpll/dpll_nl.c | 2 +- include/uapi/linux/dpll.h | 15 +++++---------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml index 72054da45440..af6258c3d8ec 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -20,12 +20,6 @@ definitions: - name: automatic doc: highest prio input pin auto selected by dpll - - - name: holdover - doc: dpll forced into holdover mode - - - name: freerun - doc: dpll driven on system clk render-max: true - type: enum @@ -37,8 +31,7 @@ definitions: - name: unlocked doc: | - dpll was not yet locked to any valid input (or is in mode: - DPLL_MODE_FREERUN) + dpll was not yet locked to any valid input value: 1 - name: locked @@ -52,11 +45,10 @@ definitions: name: holdover doc: | dpll is in holdover state - lost a valid lock or was forced - by selecting DPLL_MODE_HOLDOVER mode (latter possible only - when dpll lock-state was already DPLL_LOCK_STATUS_LOCKED, - if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED, the - dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED - even if DPLL_MODE_HOLDOVER was requested) + by disconnecting all the pins (latter possible only + when dpll lock-state was already DPLL_LOCK_STATUS_LOCKED_HO_ACQ, + if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the + dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED) render-max: true - type: const diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index aa40a4879ae1..3b5ed39971b4 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -38,7 +38,7 @@ static const struct nla_policy dpll_device_get_nl_policy[DPLL_A_MODULE_NAME + 1] /* DPLL_CMD_DEVICE_SET - do */ static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_MODE + 1] = { [DPLL_A_ID] = { .type = NLA_U32, }, - [DPLL_A_MODE] = NLA_POLICY_RANGE(NLA_U8, 1, 4), + [DPLL_A_MODE] = NLA_POLICY_RANGE(NLA_U8, 1, 2), }; /* DPLL_CMD_PIN_ID_GET - do */ diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index 527c8ca6d2bf..fd09965aed00 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -15,14 +15,10 @@ * DPLL_A_MODE attribute * @DPLL_MODE_MANUAL: input can be only selected by sending a request to dpll * @DPLL_MODE_AUTOMATIC: highest prio input pin auto selected by dpll - * @DPLL_MODE_HOLDOVER: dpll forced into holdover mode - * @DPLL_MODE_FREERUN: dpll driven on system clk */ enum dpll_mode { DPLL_MODE_MANUAL = 1, DPLL_MODE_AUTOMATIC, - DPLL_MODE_HOLDOVER, - DPLL_MODE_FREERUN, __DPLL_MODE_MAX, DPLL_MODE_MAX = (__DPLL_MODE_MAX - 1) @@ -31,16 +27,15 @@ enum dpll_mode { /** * enum dpll_lock_status - provides information of dpll device lock status, * valid values for DPLL_A_LOCK_STATUS attribute - * @DPLL_LOCK_STATUS_UNLOCKED: dpll was not yet locked to any valid input (or - * is in mode: DPLL_MODE_FREERUN) + * @DPLL_LOCK_STATUS_UNLOCKED: dpll was not yet locked to any valid input * @DPLL_LOCK_STATUS_LOCKED: dpll is locked to a valid signal, but no holdover * available * @DPLL_LOCK_STATUS_LOCKED_HO_ACQ: dpll is locked and holdover acquired * @DPLL_LOCK_STATUS_HOLDOVER: dpll is in holdover state - lost a valid lock or - * was forced by selecting DPLL_MODE_HOLDOVER mode (latter possible only when - * dpll lock-state was already DPLL_LOCK_STATUS_LOCKED, if dpll lock-state - * was not DPLL_LOCK_STATUS_LOCKED, the dpll's lock-state shall remain - * DPLL_LOCK_STATUS_UNLOCKED even if DPLL_MODE_HOLDOVER was requested) + * was forced by disconnecting all the pins (latter possible only when dpll + * lock-state was already DPLL_LOCK_STATUS_LOCKED_HO_ACQ, if dpll lock-state + * was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the dpll's lock-state shall remain + * DPLL_LOCK_STATUS_UNLOCKED) */ enum dpll_lock_status { DPLL_LOCK_STATUS_UNLOCKED = 1, From f71b5a01152809845557a7e0c1000455136129fc Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 15 Jun 2023 17:29:03 +0200 Subject: [PATCH 12/36] netdev: fix expose DPLL pin handle for netdevice net_device->dpll_pin is only valid if IS_ENABLED(CONFIG_DPLL) fix the code in net/core/rtnetlink.c to respect that. To be merged with "netdev: expose DPLL pin handle for netdevice", as requested on review. Signed-off-by: Jiri Pirko Signed-off-by: Arkadiusz Kubalewski --- drivers/dpll/dpll_netlink.c | 4 +++- include/linux/netdevice.h | 10 ++++++++++ net/core/rtnetlink.c | 11 ++++------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 893e7ef1342b..8f1de9da7795 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -303,12 +303,14 @@ dpll_cmd_pin_fill_details(struct sk_buff *msg, struct dpll_pin *pin, size_t dpll_msg_pin_handle_size(struct dpll_pin *pin) { - return nla_total_size(4); /* DPLL_A_PIN_ID */ + return pin ? nla_total_size(4) : 0; /* DPLL_A_PIN_ID */ } EXPORT_SYMBOL_GPL(dpll_msg_pin_handle_size); int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin) { + if (!pin) + return 0; if (nla_put_u32(msg, DPLL_A_PIN_ID, pin->id)) return -EMSGSIZE; return 0; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f17a1fab8358..99bfc427ffee 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3971,6 +3971,16 @@ int dev_get_port_parent_id(struct net_device *dev, bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b); void netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); void netdev_dpll_pin_clear(struct net_device *dev); + +static inline struct dpll_pin *netdev_dpll_pin(const struct net_device *dev) +{ +#if IS_ENABLED(CONFIG_DPLL) + return dev->dpll_pin; +#else + return NULL; +#endif +} + struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev, bool *again); struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq, int *ret); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index c03599e74110..48ce14306f28 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1059,8 +1059,7 @@ static size_t rtnl_dpll_pin_size(const struct net_device *dev) { size_t size = nla_total_size(0); /* nest IFLA_DPLL_PIN */ - if (dev->dpll_pin) - size += dpll_msg_pin_handle_size(dev->dpll_pin); + size += dpll_msg_pin_handle_size(netdev_dpll_pin(dev)); return size; } @@ -1796,11 +1795,9 @@ static int rtnl_fill_dpll_pin(struct sk_buff *skb, if (!dpll_pin_nest) return -EMSGSIZE; - if (dev->dpll_pin) { - ret = dpll_msg_add_pin_handle(skb, dev->dpll_pin); - if (ret < 0) - goto nest_cancel; - } + ret = dpll_msg_add_pin_handle(skb, netdev_dpll_pin(dev)); + if (ret < 0) + goto nest_cancel; nla_nest_end(skb, dpll_pin_nest); return 0; From bf93ee4eef19fc1605da34b4016ab340e42d47a5 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 18:33:16 +0200 Subject: [PATCH 13/36] ice-fw: rename MAX_NETLIST_SIZE -> ICE_MAX_NETLIST_SIZE Add prefix to a defined const value. Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_common.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index a9e52e37be40..f2536fc494c3 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -7,6 +7,7 @@ #include "ice_flow.h" #define ICE_PF_RESET_WAIT_COUNT 300 +#define ICE_MAX_NETLIST_SIZE 10 static const char * const ice_link_mode_str_low[] = { [0] = "100BASE_TX", @@ -464,8 +465,6 @@ ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd, return 0; } -#define MAX_NETLIST_SIZE 10 - /** * ice_find_netlist_node * @hw: pointer to the hw struct @@ -486,7 +485,7 @@ ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number, u16 rec_node_handle; u8 idx; - for (idx = 0; idx < MAX_NETLIST_SIZE; idx++) { + for (idx = 0; idx < ICE_MAX_NETLIST_SIZE; idx++) { int status; memset(&cmd, 0, sizeof(cmd)); From dbf577ac23d7d2dc16eae43e5a04506f1800bb54 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 18:59:31 +0200 Subject: [PATCH 14/36] ice-fw: Simplify function: s64 convert_s48_to_s64(s64 signed_48) fix "ice: add admin commands to access cgu configuration" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_common.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index f2536fc494c3..c306e4ac9f1b 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -5158,14 +5158,10 @@ ice_aq_get_output_pin_cfg(struct ice_hw *hw, u8 output_idx, u8 *flags, * * Return: signed 64 bit representation of signed 48 bit value. */ -static inline -s64 convert_s48_to_s64(s64 signed_48) +static s64 convert_s48_to_s64(s64 signed_48) { - const s64 MASK_SIGN_BITS = GENMASK_ULL(63, 48); - const s64 SIGN_BIT_47 = BIT_ULL(47); - - return ((signed_48 & SIGN_BIT_47) ? (s64)(MASK_SIGN_BITS | signed_48) - : signed_48); + return signed_48 & BIT_ULL(47) ? + GENMASK_ULL(63, 48) | signed_48 : signed_48; } /** From 3c5a796647715dbd7bdf9949c8ab5f296c98454f Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 19:01:29 +0200 Subject: [PATCH 15/36] ice-fw: do not assign 0 to field that is already 0 fix "ice: add admin commands to access cgu configuration" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index 39b692945f73..3f5d0d827637 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -3281,7 +3281,6 @@ int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx) ctx = ICE_AQC_LINK_TOPO_NODE_TYPE_PHY << ICE_AQC_LINK_TOPO_NODE_TYPE_S; ctx |= ICE_AQC_LINK_TOPO_NODE_CTX_PORT << ICE_AQC_LINK_TOPO_NODE_CTX_S; cmd.addr.topo_params.node_type_ctx = ctx; - cmd.addr.topo_params.index = 0; status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number, &node_handle); From a3469551d2574282139066889d0f9e7fb501da52 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Thu, 15 Jun 2023 23:44:17 +0200 Subject: [PATCH 16/36] ice: drop pointless 0 assignement fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 22a69197188a..21fc278fbdba 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -16,7 +16,6 @@ */ static const enum dpll_lock_status ice_dpll_status[__DPLL_LOCK_STATUS_MAX] = { - [ICE_CGU_STATE_INVALID] = 0, [ICE_CGU_STATE_FREERUN] = DPLL_LOCK_STATUS_UNLOCKED, [ICE_CGU_STATE_LOCKED] = DPLL_LOCK_STATUS_LOCKED, [ICE_CGU_STATE_LOCKED_HO_ACQ] = DPLL_LOCK_STATUS_LOCKED_HO_ACQ, @@ -27,7 +26,7 @@ ice_dpll_status[__DPLL_LOCK_STATUS_MAX] = { * ice_dpll_pin_type - enumerate ice pin types */ enum ice_dpll_pin_type { - ICE_DPLL_PIN_INVALID = 0, + ICE_DPLL_PIN_INVALID, ICE_DPLL_PIN_TYPE_INPUT, ICE_DPLL_PIN_TYPE_OUTPUT, ICE_DPLL_PIN_TYPE_RCLK_INPUT, From 476345336e686005dc1328ed5cd8c32c824da1bd Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 00:06:24 +0200 Subject: [PATCH 17/36] ice: ice_dpll_init(..) returns void instead of int ice: fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 6 +++--- drivers/net/ethernet/intel/ice/ice_dpll.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 21fc278fbdba..e992fdd43004 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1963,7 +1963,7 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu) * * 0 - success * * negative - init failure reason */ -int ice_dpll_init(struct ice_pf *pf) +void ice_dpll_init(struct ice_pf *pf) { bool cgu_present = ice_is_feature_supported(pf, ICE_F_CGU); struct ice_dplls *d = &pf->dplls; @@ -1994,7 +1994,7 @@ int ice_dpll_init(struct ice_pf *pf) mutex_unlock(&d->lock); dev_info(ice_pf_to_dev(pf), "DPLLs init successful\n"); - return err; + return; deinit_pins: ice_dpll_deinit_pins(pf, cgu_present); @@ -2010,5 +2010,5 @@ int ice_dpll_init(struct ice_pf *pf) mutex_destroy(&d->lock); dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:\n"); - return err; + return; } diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h index 287892825deb..385bb7a0f198 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.h +++ b/drivers/net/ethernet/intel/ice/ice_dpll.h @@ -95,7 +95,7 @@ struct ice_dplls { u64 clock_id; }; -int ice_dpll_init(struct ice_pf *pf); +void ice_dpll_init(struct ice_pf *pf); void ice_dpll_deinit(struct ice_pf *pf); From 13420c9b53a751933a8227b01b1f1b140afa664d Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 00:09:09 +0200 Subject: [PATCH 18/36] ice: fix context description of the functions fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index e992fdd43004..947adb53e75d 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1753,7 +1753,7 @@ void ice_dpll_deinit(struct ice_pf *pf) * Init information for directly connected pins, cache them in pf's pins * structures. * - * Context: Function initializes and holds pf->dplls.lock mutex. + * Context: Called under pf->dplls.lock. * Return: * * 0 - success * * negative - init failure reason @@ -1870,6 +1870,7 @@ ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type) * * Acquire (from HW) and set basic dpll information (on pf->dplls struct). * + * Context: Called under pf->dplls.lock * Return: * * 0 - success * * negative - init failure reason @@ -1959,9 +1960,7 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu) * subsystem. Allow userpsace to obtain state of DPLL and handling of DPLL * configuration requests. * - * Return: - * * 0 - success - * * negative - init failure reason + * Context: Function initializes and holds pf->dplls.lock mutex. */ void ice_dpll_init(struct ice_pf *pf) { From 1d92aef779ea9bfbb793ab47baf2eba7cd7c3143 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 00:09:50 +0200 Subject: [PATCH 19/36] ice: fix ice_dpll_init(..) traces fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 947adb53e75d..af2f5ab33ab8 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1991,7 +1991,7 @@ void ice_dpll_init(struct ice_pf *pf) goto deinit_pins; } mutex_unlock(&d->lock); - dev_info(ice_pf_to_dev(pf), "DPLLs init successful\n"); + dev_dbg(ice_pf_to_dev(pf), "DPLLs init successful\n"); return; @@ -2007,7 +2007,7 @@ void ice_dpll_init(struct ice_pf *pf) clear_bit(ICE_FLAG_DPLL, pf->flags); mutex_unlock(&d->lock); mutex_destroy(&d->lock); - dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:\n"); + dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err); return; } From f6c5487331f380c1e0c8e134f8088bfbe63ee751 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 00:44:01 +0200 Subject: [PATCH 20/36] ice: fix use package_label instead pf board_label for rclk pin fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index af2f5ab33ab8..7af3565fc139 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1829,7 +1829,7 @@ static int ice_dpll_init_rclk_pin(struct ice_pf *pf) struct ice_dpll_pin *pin = &pf->dplls.rclk; struct device *dev = ice_pf_to_dev(pf); - pin->prop.board_label = dev_name(dev); + pin->prop.package_label = dev_name(dev); pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT; pin->prop.capabilities |= DPLL_PIN_CAPS_STATE_CAN_CHANGE; pin->pf = pf; From 9bf9250f0a36e75b18c22c35a4ede09a01129db4 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 00:46:56 +0200 Subject: [PATCH 21/36] ice: be consistent on cgu presence naming fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 7af3565fc139..ec77a2682e64 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1964,28 +1964,26 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu) */ void ice_dpll_init(struct ice_pf *pf) { - bool cgu_present = ice_is_feature_supported(pf, ICE_F_CGU); + bool cgu = ice_is_feature_supported(pf, ICE_F_CGU); struct ice_dplls *d = &pf->dplls; int err = 0; mutex_init(&d->lock); mutex_lock(&d->lock); - err = ice_dpll_init_info(pf, cgu_present); + err = ice_dpll_init_info(pf, cgu); if (err) goto err_exit; - err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu_present, - DPLL_TYPE_EEC); + err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC); if (err) goto deinit_info; - err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu_present, - DPLL_TYPE_PPS); + err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS); if (err) goto deinit_eec; - err = ice_dpll_init_pins(pf, cgu_present); + err = ice_dpll_init_pins(pf, cgu); if (err) goto deinit_pps; set_bit(ICE_FLAG_DPLL, pf->flags); - if (cgu_present) { + if (cgu) { err = ice_dpll_init_worker(pf); if (err) goto deinit_pins; @@ -1996,11 +1994,11 @@ void ice_dpll_init(struct ice_pf *pf) return; deinit_pins: - ice_dpll_deinit_pins(pf, cgu_present); + ice_dpll_deinit_pins(pf, cgu); deinit_pps: - ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu_present); + ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu); deinit_eec: - ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu_present); + ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu); deinit_info: ice_dpll_deinit_info(pf); err_exit: From 8348d3f78ff6cc3336b2938503bc62d129c43ce0 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 00:58:47 +0200 Subject: [PATCH 22/36] ice: remove indent in ice_dpll_deinit(..) fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index ec77a2682e64..2791d81abb16 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1731,18 +1731,19 @@ void ice_dpll_deinit(struct ice_pf *pf) { bool cgu = ice_is_feature_supported(pf, ICE_F_CGU); - if (test_bit(ICE_FLAG_DPLL, pf->flags)) { - mutex_lock(&pf->dplls.lock); - ice_dpll_deinit_pins(pf, cgu); - ice_dpll_deinit_info(pf); - ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu); - ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu); - if (cgu) - ice_dpll_deinit_worker(pf); - clear_bit(ICE_FLAG_DPLL, pf->flags); - mutex_unlock(&pf->dplls.lock); - mutex_destroy(&pf->dplls.lock); - } + if (!test_bit(ICE_FLAG_DPLL, pf->flags)) + return; + + mutex_lock(&pf->dplls.lock); + ice_dpll_deinit_pins(pf, cgu); + ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu); + ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu); + ice_dpll_deinit_info(pf); + if (cgu) + ice_dpll_deinit_worker(pf); + clear_bit(ICE_FLAG_DPLL, pf->flags); + mutex_unlock(&pf->dplls.lock); + mutex_destroy(&pf->dplls.lock); } /** From 0a1cb876fd8adbbec93507f876a2ed0849f80ec1 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 11:32:24 +0200 Subject: [PATCH 23/36] ice: remove unused struct field lock_err_num fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 4 +--- drivers/net/ethernet/intel/ice/ice_dpll.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 2791d81abb16..0aeefd52a70c 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1583,10 +1583,8 @@ static void ice_dpll_periodic_work(struct kthread_work *work) if (!test_bit(ICE_FLAG_DPLL, pf->flags)) return; ret = ice_dpll_cb_lock(pf); - if (ret) { - d->lock_err_num++; + if (ret) goto resched; - } ret = ice_dpll_update_state(pf, de, false); if (!ret) ret = ice_dpll_update_state(pf, dp, false); diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h index 385bb7a0f198..e331eaef61b5 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.h +++ b/drivers/net/ethernet/intel/ice/ice_dpll.h @@ -90,7 +90,6 @@ struct ice_dplls { u32 num_inputs; u32 num_outputs; int cgu_state_acq_err_num; - int lock_err_num; u8 base_rclk_idx; u64 clock_id; }; From 8d479a45228b6d60b8810a298f7d03eda0a78394 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 11:37:52 +0200 Subject: [PATCH 24/36] ice: fix kworker resched behavior fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 0aeefd52a70c..1a770fbc92fb 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1580,11 +1580,11 @@ static void ice_dpll_periodic_work(struct kthread_work *work) struct ice_dpll *dp = &pf->dplls.pps; int ret = 0; - if (!test_bit(ICE_FLAG_DPLL, pf->flags)) - return; ret = ice_dpll_cb_lock(pf); - if (ret) + if (ret == -EBUSY) goto resched; + else if (ret) + return; ret = ice_dpll_update_state(pf, de, false); if (!ret) ret = ice_dpll_update_state(pf, dp, false); From bbc5bbc2d3c1f675970df52d08f6e5a3d5a9f29a Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 14:21:31 +0200 Subject: [PATCH 25/36] ice: remove debug log from ice_dpll_deinit_worker(..) fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 1a770fbc92fb..ff7fe2ab4077 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1708,11 +1708,8 @@ static void ice_dpll_deinit_worker(struct ice_pf *pf) struct ice_dplls *d = &pf->dplls; kthread_cancel_delayed_work_sync(&d->work); - if (!IS_ERR_OR_NULL(d->kworker)) { + if (!IS_ERR_OR_NULL(d->kworker)) kthread_destroy_worker(d->kworker); - d->kworker = NULL; - dev_dbg(ice_pf_to_dev(pf), "DPLLs worker removed\n"); - } } /** From cd7499102edfb52a9a578abf094c3f8029c67270 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Jun 2023 15:44:29 +0200 Subject: [PATCH 26/36] ice: reorder ice internal functions keep all init/deinit pairs together fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 772 +++++++++++----------- 1 file changed, 386 insertions(+), 386 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index ff7fe2ab4077..bdbd04b68e59 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1073,79 +1073,142 @@ static const struct dpll_device_ops ice_dpll_ops = { }; /** - * ice_dpll_deinit_info - release memory allocated for pins info + * ice_generate_clock_id - generates unique clock_id for registering dpll. * @pf: board private structure * - * Release memory allocated for pins by ice_dpll_init_info function. + * Generates unique (per board) clock_id for allocation and search of dpll + * devices in Linux dpll subsystem. * - * Context: Called under pf->dplls.lock + * Return: generated clock id for the board */ -static void ice_dpll_deinit_info(struct ice_pf *pf) +static u64 ice_generate_clock_id(struct ice_pf *pf) { - kfree(pf->dplls.inputs); - pf->dplls.inputs = NULL; - kfree(pf->dplls.outputs); - pf->dplls.outputs = NULL; - kfree(pf->dplls.eec.input_prio); - pf->dplls.eec.input_prio = NULL; - kfree(pf->dplls.pps.input_prio); - pf->dplls.pps.input_prio = NULL; + return pci_get_dsn(pf->pdev); } /** - * ice_dpll_deinit_rclk_pin - release rclk pin resources - * @pf: board private structure - * - * Deregister rclk pin from parent pins and release resources in dpll subsystem. + * ice_dpll_notify_changes - notify dpll subsystem about changes + * @d: pointer do dpll * - * Context: Called under pf->dplls.lock + * Once change detected appropriate event is submitted to the dpll subsystem. */ -static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf) +static void ice_dpll_notify_changes(struct ice_dpll *d) { - struct ice_dpll_pin *rclk = &pf->dplls.rclk; - struct ice_vsi *vsi = ice_get_main_vsi(pf); - struct dpll_pin *parent; - int i; - - for (i = 0; i < rclk->num_parents; i++) { - parent = pf->dplls.inputs[rclk->parent_idx[i]].pin; - if (!parent) - continue; - if (!IS_ERR_OR_NULL(rclk->pin)) - dpll_pin_on_pin_unregister(parent, rclk->pin, - &ice_dpll_rclk_ops, rclk); + if (d->prev_dpll_state != d->dpll_state) { + d->prev_dpll_state = d->dpll_state; + dpll_device_change_ntf(d->dpll); + } + if (d->prev_input != d->active_input) { + if (d->prev_input) + dpll_pin_change_ntf(d->prev_input); + d->prev_input = d->active_input; + if (d->active_input) + dpll_pin_change_ntf(d->active_input); } - if (WARN_ON_ONCE(!vsi || !vsi->netdev)) - return; - netdev_dpll_pin_clear(vsi->netdev); - dpll_pin_put(rclk->pin); - rclk->pin = NULL; } /** - * ice_dpll_unregister_pins - unregister pins from a dpll - * @dpll: dpll device pointer - * @pins: pointer to pins array - * @ops: callback ops registered with the pins - * @count: number of pins + * ice_dpll_update_state - update dpll state + * @pf: pf private structure + * @d: pointer to queried dpll device * - * Unregister pins of a given array of pins from given dpll device registered in - * dpll subsystem. + * Poll current state of dpll from hw and update ice_dpll struct. * * Context: Called under pf->dplls.lock + * Return: + * * 0 - success + * * negative - AQ failure */ -static void -ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, - const struct dpll_pin_ops *ops, int count) +static int +ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init) { struct ice_dpll_pin *p; - int i; + int ret; - for (i = 0; i < count; i++) { - p = &pins[i]; - if (p && !IS_ERR_OR_NULL(p->pin)) - dpll_pin_unregister(dpll, p->pin, ops, p); + ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state, + &d->input_idx, &d->ref_state, &d->eec_mode, + &d->phase_offset, &d->dpll_state); + + dev_dbg(ice_pf_to_dev(pf), + "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d\n", + d->dpll_idx, d->prev_input_idx, d->input_idx, + d->dpll_state, d->prev_dpll_state); + if (ret) { + dev_err(ice_pf_to_dev(pf), + "update dpll=%d state failed, ret=%d %s\n", + d->dpll_idx, ret, + ice_aq_str(pf->hw.adminq.sq_last_status)); + return ret; + } + if (init) { + if (d->dpll_state == ICE_CGU_STATE_LOCKED && + d->dpll_state == ICE_CGU_STATE_LOCKED_HO_ACQ) + d->active_input = pf->dplls.inputs[d->input_idx].pin; + p = &pf->dplls.inputs[d->input_idx]; + return ice_dpll_pin_state_update(pf, p, + ICE_DPLL_PIN_TYPE_INPUT); + } + if (d->dpll_state == ICE_CGU_STATE_HOLDOVER || + d->dpll_state == ICE_CGU_STATE_FREERUN) { + d->active_input = NULL; + p = &pf->dplls.inputs[d->input_idx]; + d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID; + d->input_idx = ICE_DPLL_PIN_IDX_INVALID; + ret = ice_dpll_pin_state_update(pf, p, + ICE_DPLL_PIN_TYPE_INPUT); + } else if (d->input_idx != d->prev_input_idx) { + p = &pf->dplls.inputs[d->prev_input_idx]; + ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT); + p = &pf->dplls.inputs[d->input_idx]; + d->active_input = p->pin; + ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT); + d->prev_input_idx = d->input_idx; } + + return ret; +} + +/** + * ice_dpll_periodic_work - DPLLs periodic worker + * @work: pointer to kthread_work structure + * + * DPLLs periodic worker is responsible for polling state of dpll. + * Context: Holds pf->dplls.lock + */ +static void ice_dpll_periodic_work(struct kthread_work *work) +{ + struct ice_dplls *d = container_of(work, struct ice_dplls, 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; + int ret = 0; + + ret = ice_dpll_cb_lock(pf); + if (ret == -EBUSY) + goto resched; + else if (ret) + return; + ret = ice_dpll_update_state(pf, de, false); + if (!ret) + ret = ice_dpll_update_state(pf, dp, false); + if (ret) { + d->cgu_state_acq_err_num++; + /* stop rescheduling this worker */ + if (d->cgu_state_acq_err_num > + ICE_CGU_STATE_ACQ_ERR_THRESHOLD) { + dev_err(ice_pf_to_dev(pf), + "EEC/PPS DPLLs periodic work disabled\n"); + return; + } + } + ice_dpll_cb_unlock(pf); + ice_dpll_notify_changes(de); + ice_dpll_notify_changes(dp); +resched: + /* Run twice a second or reschedule if update failed */ + kthread_queue_delayed_work(d->kworker, &d->work, + ret ? msecs_to_jiffies(10) : + msecs_to_jiffies(500)); } /** @@ -1211,52 +1274,40 @@ ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins, } /** - * ice_dpll_register_pins - register pins with a dpll - * @dpll: dpll pointer to register pins with + * ice_dpll_unregister_pins - unregister pins from a dpll + * @dpll: dpll device pointer * @pins: pointer to pins array * @ops: callback ops registered with the pins * @count: number of pins - * @cgu: if cgu is present and controlled by this NIC * - * Register pins of a given array with given dpll in dpll subsystem. + * Unregister pins of a given array of pins from given dpll device registered in + * dpll subsystem. * * Context: Called under pf->dplls.lock - * Return: - * * 0 - success - * * negative - registration failure reason */ -static int -ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, - const struct dpll_pin_ops *ops, int count) +static void +ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, + const struct dpll_pin_ops *ops, int count) { - int ret, i; + struct ice_dpll_pin *p; + int i; for (i = 0; i < count; i++) { - ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]); - if (ret) - goto unregister_pins; + p = &pins[i]; + if (p && !IS_ERR_OR_NULL(p->pin)) + dpll_pin_unregister(dpll, p->pin, ops, p); } - - return 0; - -unregister_pins: - ice_dpll_unregister_pins(dpll, pins, ops, i); - return ret; } /** - * ice_dpll_init_direct_pins - initialize direct pins + * ice_dpll_register_pins - register pins with a dpll * @dpll: dpll pointer to register pins with - * @cgu: if cgu is present and controlled by this NIC * @pins: pointer to pins array - * @start_idx: on which index shall allocation start in dpll subsystem - * @count: number of pins * @ops: callback ops registered with the pins - * @first: dpll device pointer - * @second: dpll device pointer + * @count: number of pins + * @cgu: if cgu is present and controlled by this NIC * - * Allocate directly connected pins of a given array in dpll subsystem. - * If cgu is owned register allocated pins with given dplls. + * Register pins of a given array with given dpll in dpll subsystem. * * Context: Called under pf->dplls.lock * Return: @@ -1264,31 +1315,21 @@ ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, * * negative - registration failure reason */ static int -ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu, - struct ice_dpll_pin *pins, int start_idx, int count, - const struct dpll_pin_ops *ops, - struct dpll_device *first, struct dpll_device *second) +ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, + const struct dpll_pin_ops *ops, int count) { - int ret; + int ret, i; - ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id); - if (ret) - return ret; - if (cgu) { - ret = ice_dpll_register_pins(first, pins, ops, count); - if (ret) - goto release_pins; - ret = ice_dpll_register_pins(second, pins, ops, count); + for (i = 0; i < count; i++) { + ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]); if (ret) - goto unregister_first; + goto unregister_pins; } return 0; -unregister_first: - ice_dpll_unregister_pins(first, pins, ops, count); -release_pins: - ice_dpll_release_pins(pins, count); +unregister_pins: + ice_dpll_unregister_pins(dpll, pins, ops, i); return ret; } @@ -1319,17 +1360,18 @@ ice_dpll_deinit_direct_pins(bool cgu, struct ice_dpll_pin *pins, int count, } /** - * ice_dpll_init_rclk_pins - initialize recovered clock pin + * ice_dpll_init_direct_pins - initialize direct pins * @dpll: dpll pointer to register pins with * @cgu: if cgu is present and controlled by this NIC * @pins: pointer to pins array * @start_idx: on which index shall allocation start in dpll subsystem * @count: number of pins * @ops: callback ops registered with the pins + * @first: dpll device pointer + * @second: dpll device pointer * - * Allocate resource for recovered clock pin in dpll subsystem. Register the - * pin with the parents it has in the info. Register pin with the pf's main vsi - * netdev. + * Allocate directly connected pins of a given array in dpll subsystem. + * If cgu is owned register allocated pins with given dplls. * * Context: Called under pf->dplls.lock * Return: @@ -1337,305 +1379,119 @@ ice_dpll_deinit_direct_pins(bool cgu, struct ice_dpll_pin *pins, int count, * * negative - registration failure reason */ static int -ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin, - int start_idx, const struct dpll_pin_ops *ops) -{ - struct ice_vsi *vsi = ice_get_main_vsi(pf); - struct dpll_pin *parent; - int ret, i; - - ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, - pf->dplls.clock_id); - if (ret) - return ret; - for (i = 0; i < pf->dplls.rclk.num_parents; i++) { - parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[i]].pin; - if (!parent) { - ret = -ENODEV; - goto unregister_pins; - } - ret = dpll_pin_on_pin_register(parent, pf->dplls.rclk.pin, - ops, &pf->dplls.rclk); - if (ret) - goto unregister_pins; - } - if (WARN_ON((!vsi || !vsi->netdev))) - return -EINVAL; - netdev_dpll_pin_set(vsi->netdev, pf->dplls.rclk.pin); - - return 0; - -unregister_pins: - while (i) { - parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[--i]].pin; - dpll_pin_on_pin_unregister(parent, pf->dplls.rclk.pin, - &ice_dpll_rclk_ops, &pf->dplls.rclk); - } - ice_dpll_release_pins(pin, ICE_DPLL_RCLK_NUM_PER_PF); - return ret; -} - -/** - * ice_dpll_init_pins - init pins and register pins with a dplls - * @pf: board private structure - * @cgu: if cgu is present and controlled by this NIC - * - * Initialize directly connected pf's pins within pf's dplls in a Linux dpll - * subsystem. - * - * Context: Called under pf->dplls.lock - * Return: - * * 0 - success - * * negative - initialization failure reason - */ -static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu) +ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu, + struct ice_dpll_pin *pins, int start_idx, int count, + const struct dpll_pin_ops *ops, + struct dpll_device *first, struct dpll_device *second) { - u32 rclk_idx; int ret; - ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0, - pf->dplls.num_inputs, - &ice_dpll_input_ops, - pf->dplls.eec.dpll, pf->dplls.pps.dpll); + ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id); if (ret) return ret; if (cgu) { - ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs, - pf->dplls.num_inputs, - pf->dplls.num_outputs, - &ice_dpll_output_ops, - pf->dplls.eec.dpll, - pf->dplls.pps.dpll); + ret = ice_dpll_register_pins(first, pins, ops, count); if (ret) - goto deinit_inputs; + goto release_pins; + ret = ice_dpll_register_pins(second, pins, ops, count); + if (ret) + goto unregister_first; } - rclk_idx = pf->dplls.num_inputs + pf->dplls.num_outputs + pf->hw.pf_id; - ret = ice_dpll_init_rclk_pins(pf, &pf->dplls.rclk, rclk_idx, - &ice_dpll_rclk_ops); - if (ret) - goto deinit_outputs; return 0; -deinit_outputs: - ice_dpll_deinit_direct_pins(cgu, pf->dplls.outputs, - pf->dplls.num_outputs, - &ice_dpll_output_ops, pf->dplls.pps.dpll, - pf->dplls.eec.dpll); -deinit_inputs: - ice_dpll_deinit_direct_pins(cgu, pf->dplls.inputs, pf->dplls.num_inputs, - &ice_dpll_input_ops, pf->dplls.pps.dpll, - pf->dplls.eec.dpll); - return ret; -} -/** - * ice_generate_clock_id - generates unique clock_id for registering dpll. - * @pf: board private structure - * - * Generates unique (per board) clock_id for allocation and search of dpll - * devices in Linux dpll subsystem. - * - * Return: generated clock id for the board - */ -static u64 ice_generate_clock_id(struct ice_pf *pf) -{ - return pci_get_dsn(pf->pdev); +unregister_first: + ice_dpll_unregister_pins(first, pins, ops, count); +release_pins: + ice_dpll_release_pins(pins, count); + return ret; } /** - * ice_dpll_init_dpll - initialize dpll device in dpll subsystem + * ice_dpll_deinit_rclk_pin - release rclk pin resources * @pf: board private structure - * @d: dpll to be initialized - * @cgu: if cgu is present and controlled by this NIC - * @type: type of dpll being initialized - * - * Allocate dpll instance for this board in dpll subsystem, if cgu is controlled - * by this NIC, register dpll with the callback ops. * - * Context: Called under pf->dplls.lock - * Return: - * * 0 - success - * * negative - initialization failure reason - */ -static int -ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu, - enum dpll_type type) -{ - u64 clock_id = pf->dplls.clock_id; - int ret; - - d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE); - if (IS_ERR(d->dpll)) { - ret = PTR_ERR(d->dpll); - dev_err(ice_pf_to_dev(pf), - "dpll_device_get failed (%p) err=%d\n", d, ret); - return ret; - } - d->pf = pf; - if (cgu) { - ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d); - if (ret) { - dpll_device_put(d->dpll); - return ret; - } - } - - return 0; -} - -/** - * ice_dpll_update_state - update dpll state - * @pf: pf private structure - * @d: pointer to queried dpll device - * - * Poll current state of dpll from hw and update ice_dpll struct. + * Deregister rclk pin from parent pins and release resources in dpll subsystem. * * Context: Called under pf->dplls.lock - * Return: - * * 0 - success - * * negative - AQ failure */ -static int -ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init) -{ - struct ice_dpll_pin *p; - int ret; - - ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state, - &d->input_idx, &d->ref_state, &d->eec_mode, - &d->phase_offset, &d->dpll_state); - - dev_dbg(ice_pf_to_dev(pf), - "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d\n", - d->dpll_idx, d->prev_input_idx, d->input_idx, - d->dpll_state, d->prev_dpll_state); - if (ret) { - dev_err(ice_pf_to_dev(pf), - "update dpll=%d state failed, ret=%d %s\n", - d->dpll_idx, ret, - ice_aq_str(pf->hw.adminq.sq_last_status)); - return ret; - } - if (init) { - if (d->dpll_state == ICE_CGU_STATE_LOCKED && - d->dpll_state == ICE_CGU_STATE_LOCKED_HO_ACQ) - d->active_input = pf->dplls.inputs[d->input_idx].pin; - p = &pf->dplls.inputs[d->input_idx]; - return ice_dpll_pin_state_update(pf, p, - ICE_DPLL_PIN_TYPE_INPUT); - } - if (d->dpll_state == ICE_CGU_STATE_HOLDOVER || - d->dpll_state == ICE_CGU_STATE_FREERUN) { - d->active_input = NULL; - p = &pf->dplls.inputs[d->input_idx]; - d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID; - d->input_idx = ICE_DPLL_PIN_IDX_INVALID; - ret = ice_dpll_pin_state_update(pf, p, - ICE_DPLL_PIN_TYPE_INPUT); - } else if (d->input_idx != d->prev_input_idx) { - p = &pf->dplls.inputs[d->prev_input_idx]; - ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT); - p = &pf->dplls.inputs[d->input_idx]; - d->active_input = p->pin; - ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT); - d->prev_input_idx = d->input_idx; - } - - return ret; -} - -/** - * ice_dpll_notify_changes - notify dpll subsystem about changes - * @d: pointer do dpll - * - * Once change detected appropriate event is submitted to the dpll subsystem. - */ -static void ice_dpll_notify_changes(struct ice_dpll *d) -{ - if (d->prev_dpll_state != d->dpll_state) { - d->prev_dpll_state = d->dpll_state; - dpll_device_change_ntf(d->dpll); - } - if (d->prev_input != d->active_input) { - if (d->prev_input) - dpll_pin_change_ntf(d->prev_input); - d->prev_input = d->active_input; - if (d->active_input) - dpll_pin_change_ntf(d->active_input); - } -} - -/** - * ice_dpll_periodic_work - DPLLs periodic worker - * @work: pointer to kthread_work structure - * - * DPLLs periodic worker is responsible for polling state of dpll. - * Context: Holds pf->dplls.lock - */ -static void ice_dpll_periodic_work(struct kthread_work *work) +static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf) { - struct ice_dplls *d = container_of(work, struct ice_dplls, 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; - int ret = 0; + struct ice_dpll_pin *rclk = &pf->dplls.rclk; + struct ice_vsi *vsi = ice_get_main_vsi(pf); + struct dpll_pin *parent; + int i; - ret = ice_dpll_cb_lock(pf); - if (ret == -EBUSY) - goto resched; - else if (ret) - return; - ret = ice_dpll_update_state(pf, de, false); - if (!ret) - ret = ice_dpll_update_state(pf, dp, false); - if (ret) { - d->cgu_state_acq_err_num++; - /* stop rescheduling this worker */ - if (d->cgu_state_acq_err_num > - ICE_CGU_STATE_ACQ_ERR_THRESHOLD) { - dev_err(ice_pf_to_dev(pf), - "EEC/PPS DPLLs periodic work disabled\n"); - return; - } + for (i = 0; i < rclk->num_parents; i++) { + parent = pf->dplls.inputs[rclk->parent_idx[i]].pin; + if (!parent) + continue; + if (!IS_ERR_OR_NULL(rclk->pin)) + dpll_pin_on_pin_unregister(parent, rclk->pin, + &ice_dpll_rclk_ops, rclk); } - ice_dpll_cb_unlock(pf); - ice_dpll_notify_changes(de); - ice_dpll_notify_changes(dp); -resched: - /* Run twice a second or reschedule if update failed */ - kthread_queue_delayed_work(d->kworker, &d->work, - ret ? msecs_to_jiffies(10) : - msecs_to_jiffies(500)); + if (WARN_ON_ONCE(!vsi || !vsi->netdev)) + return; + netdev_dpll_pin_clear(vsi->netdev); + dpll_pin_put(rclk->pin); + rclk->pin = NULL; } /** - * ice_dpll_init_worker - Initialize DPLLs periodic worker - * @pf: board private structure + * ice_dpll_init_rclk_pins - initialize recovered clock pin + * @dpll: dpll pointer to register pins with + * @cgu: if cgu is present and controlled by this NIC + * @pins: pointer to pins array + * @start_idx: on which index shall allocation start in dpll subsystem + * @count: number of pins + * @ops: callback ops registered with the pins * - * Create and start DPLLs periodic worker. + * Allocate resource for recovered clock pin in dpll subsystem. Register the + * pin with the parents it has in the info. Register pin with the pf's main vsi + * netdev. * * Context: Called under pf->dplls.lock * Return: * * 0 - success - * * negative - create worker failure + * * negative - registration failure reason */ -static int ice_dpll_init_worker(struct ice_pf *pf) +static int +ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin, + int start_idx, const struct dpll_pin_ops *ops) { - struct ice_dplls *d = &pf->dplls; - struct kthread_worker *kworker; + struct ice_vsi *vsi = ice_get_main_vsi(pf); + struct dpll_pin *parent; + int ret, i; - ice_dpll_update_state(pf, &d->eec, true); - ice_dpll_update_state(pf, &d->pps, true); - kthread_init_delayed_work(&d->work, ice_dpll_periodic_work); - kworker = kthread_create_worker(0, "ice-dplls-%s", - dev_name(ice_pf_to_dev(pf))); - if (IS_ERR(kworker)) - return PTR_ERR(kworker); - d->kworker = kworker; - d->cgu_state_acq_err_num = 0; - kthread_queue_delayed_work(d->kworker, &d->work, 0); + ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, + pf->dplls.clock_id); + if (ret) + return ret; + for (i = 0; i < pf->dplls.rclk.num_parents; i++) { + parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[i]].pin; + if (!parent) { + ret = -ENODEV; + goto unregister_pins; + } + ret = dpll_pin_on_pin_register(parent, pf->dplls.rclk.pin, + ops, &pf->dplls.rclk); + if (ret) + goto unregister_pins; + } + if (WARN_ON((!vsi || !vsi->netdev))) + return -EINVAL; + netdev_dpll_pin_set(vsi->netdev, pf->dplls.rclk.pin); return 0; + +unregister_pins: + while (i) { + parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[--i]].pin; + dpll_pin_on_pin_unregister(parent, pf->dplls.rclk.pin, + &ice_dpll_rclk_ops, &pf->dplls.rclk); + } + ice_dpll_release_pins(pin, ICE_DPLL_RCLK_NUM_PER_PF); + return ret; } /** @@ -1675,6 +1531,59 @@ static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu) } } +/** + * ice_dpll_init_pins - init pins and register pins with a dplls + * @pf: board private structure + * @cgu: if cgu is present and controlled by this NIC + * + * Initialize directly connected pf's pins within pf's dplls in a Linux dpll + * subsystem. + * + * Context: Called under pf->dplls.lock + * Return: + * * 0 - success + * * negative - initialization failure reason + */ +static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu) +{ + u32 rclk_idx; + int ret; + + ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0, + pf->dplls.num_inputs, + &ice_dpll_input_ops, + pf->dplls.eec.dpll, pf->dplls.pps.dpll); + if (ret) + return ret; + if (cgu) { + ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs, + pf->dplls.num_inputs, + pf->dplls.num_outputs, + &ice_dpll_output_ops, + pf->dplls.eec.dpll, + pf->dplls.pps.dpll); + if (ret) + goto deinit_inputs; + } + rclk_idx = pf->dplls.num_inputs + pf->dplls.num_outputs + pf->hw.pf_id; + ret = ice_dpll_init_rclk_pins(pf, &pf->dplls.rclk, rclk_idx, + &ice_dpll_rclk_ops); + if (ret) + goto deinit_outputs; + + return 0; +deinit_outputs: + ice_dpll_deinit_direct_pins(cgu, pf->dplls.outputs, + pf->dplls.num_outputs, + &ice_dpll_output_ops, pf->dplls.pps.dpll, + pf->dplls.eec.dpll); +deinit_inputs: + ice_dpll_deinit_direct_pins(cgu, pf->dplls.inputs, pf->dplls.num_inputs, + &ice_dpll_input_ops, pf->dplls.pps.dpll, + pf->dplls.eec.dpll); + return ret; +} + /** * ice_dpll_deinit_dpll - deinitialize dpll device * @pf: board private structure @@ -1695,6 +1604,47 @@ ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu) } } +/** + * ice_dpll_init_dpll - initialize dpll device in dpll subsystem + * @pf: board private structure + * @d: dpll to be initialized + * @cgu: if cgu is present and controlled by this NIC + * @type: type of dpll being initialized + * + * Allocate dpll instance for this board in dpll subsystem, if cgu is controlled + * by this NIC, register dpll with the callback ops. + * + * Context: Called under pf->dplls.lock + * Return: + * * 0 - success + * * negative - initialization failure reason + */ +static int +ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu, + enum dpll_type type) +{ + u64 clock_id = pf->dplls.clock_id; + int ret; + + d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE); + if (IS_ERR(d->dpll)) { + ret = PTR_ERR(d->dpll); + dev_err(ice_pf_to_dev(pf), + "dpll_device_get failed (%p) err=%d\n", d, ret); + return ret; + } + d->pf = pf; + if (cgu) { + ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d); + if (ret) { + dpll_device_put(d->dpll); + return ret; + } + } + + return 0; +} + /** * ice_dpll_deinit_worker - deinitialize dpll kworker * @pf: board private structure @@ -1713,32 +1663,33 @@ static void ice_dpll_deinit_worker(struct ice_pf *pf) } /** - * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem - * the dpll device. + * ice_dpll_init_worker - Initialize DPLLs periodic worker * @pf: board private structure * - * Handles the cleanup work required after dpll initialization,freeing resources - * and unregistering the dpll, pin and all resources used for handling them. + * Create and start DPLLs periodic worker. * - * Context: Function holds pf->dplls.lock mutex. + * Context: Called under pf->dplls.lock + * Return: + * * 0 - success + * * negative - create worker failure */ -void ice_dpll_deinit(struct ice_pf *pf) +static int ice_dpll_init_worker(struct ice_pf *pf) { - bool cgu = ice_is_feature_supported(pf, ICE_F_CGU); + struct ice_dplls *d = &pf->dplls; + struct kthread_worker *kworker; - if (!test_bit(ICE_FLAG_DPLL, pf->flags)) - return; + ice_dpll_update_state(pf, &d->eec, true); + ice_dpll_update_state(pf, &d->pps, true); + kthread_init_delayed_work(&d->work, ice_dpll_periodic_work); + kworker = kthread_create_worker(0, "ice-dplls-%s", + dev_name(ice_pf_to_dev(pf))); + if (IS_ERR(kworker)) + return PTR_ERR(kworker); + d->kworker = kworker; + d->cgu_state_acq_err_num = 0; + kthread_queue_delayed_work(d->kworker, &d->work, 0); - mutex_lock(&pf->dplls.lock); - ice_dpll_deinit_pins(pf, cgu); - ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu); - ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu); - ice_dpll_deinit_info(pf); - if (cgu) - ice_dpll_deinit_worker(pf); - clear_bit(ICE_FLAG_DPLL, pf->flags); - mutex_unlock(&pf->dplls.lock); - mutex_destroy(&pf->dplls.lock); + return 0; } /** @@ -1810,7 +1761,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, } /** - * ice_dpll_init_rclk_pin - initializes rclk pin information + * ice_dpll_init_info_rclk_pin - initializes rclk pin information * @pf: board private structure * @pin_type: type of pins being initialized * @@ -1820,7 +1771,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, * * 0 - success * * negative - init failure reason */ -static int ice_dpll_init_rclk_pin(struct ice_pf *pf) +static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf) { struct ice_dpll_pin *pin = &pf->dplls.rclk; struct device *dev = ice_pf_to_dev(pf); @@ -1853,12 +1804,32 @@ ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type) case ICE_DPLL_PIN_TYPE_OUTPUT: return ice_dpll_init_info_direct_pins(pf, pin_type); case ICE_DPLL_PIN_TYPE_RCLK_INPUT: - return ice_dpll_init_rclk_pin(pf); + return ice_dpll_init_info_rclk_pin(pf); default: return -EINVAL; } } +/** + * ice_dpll_deinit_info - release memory allocated for pins info + * @pf: board private structure + * + * Release memory allocated for pins by ice_dpll_init_info function. + * + * Context: Called under pf->dplls.lock + */ +static void ice_dpll_deinit_info(struct ice_pf *pf) +{ + kfree(pf->dplls.inputs); + pf->dplls.inputs = NULL; + kfree(pf->dplls.outputs); + pf->dplls.outputs = NULL; + kfree(pf->dplls.eec.input_prio); + pf->dplls.eec.input_prio = NULL; + kfree(pf->dplls.pps.input_prio); + pf->dplls.pps.input_prio = NULL; +} + /** * ice_dpll_init_info - prepare pf's dpll information structure * @pf: board private structure @@ -1948,6 +1919,35 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu) return ret; } +/** + * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem + * the dpll device. + * @pf: board private structure + * + * Handles the cleanup work required after dpll initialization,freeing resources + * and unregistering the dpll, pin and all resources used for handling them. + * + * Context: Function holds pf->dplls.lock mutex. + */ +void ice_dpll_deinit(struct ice_pf *pf) +{ + bool cgu = ice_is_feature_supported(pf, ICE_F_CGU); + + if (!test_bit(ICE_FLAG_DPLL, pf->flags)) + return; + + mutex_lock(&pf->dplls.lock); + ice_dpll_deinit_pins(pf, cgu); + ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu); + ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu); + ice_dpll_deinit_info(pf); + if (cgu) + ice_dpll_deinit_worker(pf); + clear_bit(ICE_FLAG_DPLL, pf->flags); + mutex_unlock(&pf->dplls.lock); + mutex_destroy(&pf->dplls.lock); +} + /** * ice_dpll_init - initialize support for dpll subsystem * @pf: board private structure From 591982c7989ac76005aa1c01ff3f115de26ea2a2 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Sat, 17 Jun 2023 14:29:59 +0200 Subject: [PATCH 27/36] dpll: netlink: fix pin-id-get/device-id-get behavior If pin was given a different pin label then the one searched by the user it wrongly returned the match, despite there was not a match. Exaple use case: pin had only a board-label assigned, a user requested search of a pin with the label, logic returned a match in two cases: - when pin actually had board-label match - when a pin had no board-label but a different label present (either package-label or panel-label), even if there was no match Do not return a match for a label if that label is not present on the pin being checked. Signed-off-by: Arkadiusz Kubalewski --- drivers/dpll/dpll_netlink.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 8f1de9da7795..049dd50a9e33 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -653,13 +653,15 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr, !nla_strcmp(mod_name_attr, module_name(pin->module)) : true; type_match = type ? prop->type == type : true; - board_match = board_label && prop->board_label ? - !nla_strcmp(board_label, prop->board_label) : true; - panel_match = panel_label && prop->panel_label ? - !nla_strcmp(panel_label, prop->panel_label) : true; - package_match = package_label && prop->package_label ? - !nla_strcmp(package_label, - prop->package_label) : true; + board_match = board_label ? (prop->board_label ? + !nla_strcmp(board_label, prop->board_label) : false) : + true; + panel_match = panel_label ? (prop->panel_label ? + !nla_strcmp(panel_label, prop->panel_label) : false) : + true; + package_match = package_label ? (prop->package_label ? + !nla_strcmp(package_label, prop->package_label) : + false) : true; if (cid_match && mod_match && type_match && board_match && panel_match && package_match) { if (pin_match) @@ -698,22 +700,22 @@ dpll_pin_find_from_nlattr(struct genl_info *info, struct sk_buff *skb) if (type) return -EINVAL; type = nla_get_u8(attr); - break; + break; case DPLL_A_PIN_BOARD_LABEL: if (board_label_attr) return -EINVAL; board_label_attr = attr; - break; + break; case DPLL_A_PIN_PANEL_LABEL: if (panel_label_attr) return -EINVAL; panel_label_attr = attr; - break; + break; case DPLL_A_PIN_PACKAGE_LABEL: if (package_label_attr) return -EINVAL; package_label_attr = attr; - break; + break; default: break; } @@ -828,9 +830,9 @@ dpll_device_find(u64 clock_id, struct nlattr *mod_name_attr, xa_for_each_marked(&dpll_device_xa, i, dpll, DPLL_REGISTERED) { cid_match = clock_id ? dpll->clock_id == clock_id : true; - mod_match = mod_name_attr && module_name(dpll->module) ? + mod_match = mod_name_attr ? (module_name(dpll->module) ? !nla_strcmp(mod_name_attr, - module_name(dpll->module)) : true; + module_name(dpll->module)) : false) : true; type_match = type ? dpll->type == type : true; if (cid_match && mod_match && type_match) { if (dpll_match) From 858bcf49e4a23da0cb6594a36ea796dde8df9e96 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Sun, 18 Jun 2023 19:19:27 +0200 Subject: [PATCH 28/36] ice: release resources directly on error path In case of failed dpll_pin_get(..) or dpll_pin_register(..), call release resources functions directly in a loop (error path), instead of calling helper functions. fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index bdbd04b68e59..e808311a0b4d 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1269,7 +1269,8 @@ ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins, return 0; release_pins: - ice_dpll_release_pins(pins, i); + while (--i >= 0) + dpll_pin_put(pins[i].pin); return ret; } @@ -1329,7 +1330,8 @@ ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, return 0; unregister_pins: - ice_dpll_unregister_pins(dpll, pins, ops, i); + while (--i >= 0) + dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]); return ret; } From 8e60d700f5a635915bfff74009e8e29861b61cfd Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Sun, 18 Jun 2023 23:49:54 +0200 Subject: [PATCH 29/36] ice: remove redundant NULL checks when releasing resources fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 36 +++++++---------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index e808311a0b4d..1e4cf2136548 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1223,16 +1223,10 @@ static void ice_dpll_periodic_work(struct kthread_work *work) */ static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count) { - struct ice_dpll_pin *p; int i; - for (i = 0; i < count; i++) { - p = &pins[i]; - if (p && !IS_ERR_OR_NULL(p->pin)) { - dpll_pin_put(p->pin); - p->pin = NULL; - } - } + for (i = 0; i < count; i++) + dpll_pin_put(pins[i].pin); } /** @@ -1290,14 +1284,10 @@ static void ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, const struct dpll_pin_ops *ops, int count) { - struct ice_dpll_pin *p; int i; - for (i = 0; i < count; i++) { - p = &pins[i]; - if (p && !IS_ERR_OR_NULL(p->pin)) - dpll_pin_unregister(dpll, p->pin, ops, p); - } + for (i = 0; i < count; i++) + dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]); } /** @@ -1428,9 +1418,8 @@ static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf) parent = pf->dplls.inputs[rclk->parent_idx[i]].pin; if (!parent) continue; - if (!IS_ERR_OR_NULL(rclk->pin)) - dpll_pin_on_pin_unregister(parent, rclk->pin, - &ice_dpll_rclk_ops, rclk); + dpll_pin_on_pin_unregister(parent, rclk->pin, + &ice_dpll_rclk_ops, rclk); } if (WARN_ON_ONCE(!vsi || !vsi->netdev)) return; @@ -1598,12 +1587,10 @@ static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu) static void ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu) { - if (!IS_ERR(d->dpll)) { - if (cgu) - dpll_device_unregister(d->dpll, &ice_dpll_ops, d); - dpll_device_put(d->dpll); - dev_dbg(ice_pf_to_dev(pf), "(%p) dpll removed\n", d); - } + if (cgu) + dpll_device_unregister(d->dpll, &ice_dpll_ops, d); + dpll_device_put(d->dpll); + dev_dbg(ice_pf_to_dev(pf), "(%p) dpll removed\n", d); } /** @@ -1660,8 +1647,7 @@ static void ice_dpll_deinit_worker(struct ice_pf *pf) struct ice_dplls *d = &pf->dplls; kthread_cancel_delayed_work_sync(&d->work); - if (!IS_ERR_OR_NULL(d->kworker)) - kthread_destroy_worker(d->kworker); + kthread_destroy_worker(d->kworker); } /** From 079ba7b41dc968335d2985d509c409f1e04d255a Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 00:10:58 +0200 Subject: [PATCH 30/36] ice: do not assign NULL to pointers after releasing resources fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 1e4cf2136548..18618737f138 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1425,7 +1425,6 @@ static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf) return; netdev_dpll_pin_clear(vsi->netdev); dpll_pin_put(rclk->pin); - rclk->pin = NULL; } /** @@ -1809,13 +1808,9 @@ ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type) static void ice_dpll_deinit_info(struct ice_pf *pf) { kfree(pf->dplls.inputs); - pf->dplls.inputs = NULL; kfree(pf->dplls.outputs); - pf->dplls.outputs = NULL; kfree(pf->dplls.eec.input_prio); - pf->dplls.eec.input_prio = NULL; kfree(pf->dplls.pps.input_prio); - pf->dplls.pps.input_prio = NULL; } /** From 996db2d0a48cb562d7dcdbe1703caeb74ccab1ae Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 00:20:06 +0200 Subject: [PATCH 31/36] ice: simplify variable assignement fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 18618737f138..7258f01acf92 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -670,7 +670,7 @@ ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv, enum dpll_pin_state state, struct netlink_ext_ack *extack) { - bool enable = state == DPLL_PIN_STATE_CONNECTED ? true : false; + bool enable = state == DPLL_PIN_STATE_CONNECTED; return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable, extack, ICE_DPLL_PIN_TYPE_OUTPUT); @@ -698,7 +698,7 @@ ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv, enum dpll_pin_state state, struct netlink_ext_ack *extack) { - bool enable = state == DPLL_PIN_STATE_SELECTABLE ? true : false; + bool enable = state == DPLL_PIN_STATE_SELECTABLE; return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable, extack, ICE_DPLL_PIN_TYPE_INPUT); @@ -964,8 +964,8 @@ ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv, enum dpll_pin_state state, struct netlink_ext_ack *extack) { - bool enable = state == DPLL_PIN_STATE_CONNECTED ? true : false; struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv; + bool enable = state == DPLL_PIN_STATE_CONNECTED; struct ice_pf *pf = p->pf; int ret = -EINVAL; u32 hw_idx; From c22ae9dbde5fd4751c6bf600dfd627e0f46a8c1b Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 00:51:03 +0200 Subject: [PATCH 32/36] ice: fix 'int ret;' declarations across the ice_dpll.c fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 52 ++++++++++++++--------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 7258f01acf92..59a8ee056ea9 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -97,7 +97,7 @@ static int ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin, enum ice_dpll_pin_type pin_type, const u32 freq) { - int ret = -EINVAL; + int ret; u8 flags; switch (pin_type) { @@ -112,7 +112,7 @@ ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin, 0, freq, 0); break; default: - break; + return -EINVAL; } if (ret) { dev_err(ice_pf_to_dev(pf), @@ -152,7 +152,7 @@ ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv, { struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; - int ret = -EINVAL; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -240,7 +240,7 @@ ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv, { struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; - int ret = -EINVAL; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -318,8 +318,8 @@ static int ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin, enum ice_dpll_pin_type pin_type) { - int ret = -EINVAL; u8 flags = 0; + int ret; switch (pin_type) { case ICE_DPLL_PIN_TYPE_INPUT: @@ -335,7 +335,7 @@ ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin, ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, 0, 0, 0); break; default: - break; + return -EINVAL; } if (ret) dev_err(ice_pf_to_dev((struct ice_pf *)(hw->back)), @@ -363,8 +363,8 @@ static int ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin, enum ice_dpll_pin_type pin_type) { - int ret = -EINVAL; u8 flags = 0; + int ret; switch (pin_type) { case ICE_DPLL_PIN_TYPE_INPUT: @@ -378,7 +378,7 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin, ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, 0, 0, 0); break; default: - break; + return -EINVAL; } if (ret) dev_err(ice_pf_to_dev((struct ice_pf *)(hw->back)), @@ -408,13 +408,15 @@ int ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, enum ice_dpll_pin_type pin_type) { - int ret = -EINVAL; + int ret; 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], &pin->freq, NULL); + if (ret) + goto err; if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) { if (pin->pin) { pin->state[pf->dplls.eec.dpll_idx] = @@ -442,6 +444,8 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, ret = ice_aq_get_output_pin_cfg(&pf->hw, pin->idx, &pin->flags[0], NULL, &pin->freq, NULL); + if (ret) + goto err; if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) pin->state[0] = DPLL_PIN_STATE_CONNECTED; else @@ -457,7 +461,7 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, &pin->flags[parent], &pin->freq); if (ret) - return ret; + goto err; if (ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN & pin->flags[parent]) pin->state[parent] = DPLL_PIN_STATE_CONNECTED; @@ -467,9 +471,15 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, } break; default: - break; + return -EINVAL; } + return 0; +err: + dev_err(ice_pf_to_dev(pf), + "err:%d %s failed to update %s pin:%u\n", + ret, ice_aq_str(pf->hw.adminq.sq_last_status), + pin_type_name[pin_type], pin->idx); return ret; } @@ -544,7 +554,7 @@ static int ice_dpll_lock_status_get(const struct dpll_device *dpll, void *priv, { struct ice_dpll *d = priv; struct ice_pf *pf = d->pf; - int ret = -EINVAL; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -628,7 +638,7 @@ ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv, { struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; - int ret = -EINVAL; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -731,7 +741,7 @@ ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv, struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; struct ice_dpll *d; - int ret = -EINVAL; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -833,7 +843,7 @@ ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv, struct ice_dpll_pin *p = pin_priv; struct ice_dpll *d = dpll_priv; struct ice_pf *pf = d->pf; - int ret = -EINVAL; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -870,7 +880,7 @@ ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv, struct ice_dpll_pin *p = pin_priv; struct ice_dpll *d = dpll_priv; struct ice_pf *pf = d->pf; - int ret = -EINVAL; + int ret; if (prio > ICE_DPLL_PRIO_MAX) { NL_SET_ERR_MSG_FMT(extack, "prio out of supported range 0-%d", @@ -967,8 +977,8 @@ ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv, struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv; bool enable = state == DPLL_PIN_STATE_CONNECTED; struct ice_pf *pf = p->pf; - int ret = -EINVAL; u32 hw_idx; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -1017,8 +1027,8 @@ ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv, { struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv; struct ice_pf *pf = p->pf; - int ret = -EFAULT; u32 hw_idx; + int ret; ret = ice_dpll_cb_lock(pf); if (ret) @@ -1181,7 +1191,7 @@ 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; - int ret = 0; + int ret; ret = ice_dpll_cb_lock(pf); if (ret == -EBUSY) @@ -1697,9 +1707,9 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, enum ice_dpll_pin_type pin_type) { struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps; - int num_pins, i, ret = -EINVAL; struct ice_hw *hw = &pf->hw; struct ice_dpll_pin *pins; + int num_pins, i, ret; u8 freq_supp_num; bool input; @@ -1715,7 +1725,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, input = false; break; default: - return ret; + return -EINVAL; } for (i = 0; i < num_pins; i++) { From 85f8d749729385f76188c8a625a044e8fcb1d66a Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 00:56:04 +0200 Subject: [PATCH 33/36] ice: remove leftover ice_dpll_find(..) fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 27 ++--------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 59a8ee056ea9..25bc95cf66d4 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -483,26 +483,6 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, return ret; } -/** - * ice_find_dpll - find ice_dpll on a pf - * @pf: private board structure - * @dpll: kernel's dpll_device pointer to be searched - * - * Context: Called under pf->dplls.lock - * Return: - * * pointer if ice_dpll with given device dpll pointer is found - * * NULL if not found - */ -static struct ice_dpll -*ice_find_dpll(struct ice_pf *pf, const struct dpll_device *dpll) -{ - if (!pf || !dpll) - return NULL; - - return dpll == pf->dplls.eec.dpll ? &pf->dplls.eec : - dpll == pf->dplls.pps.dpll ? &pf->dplls.pps : NULL; -} - /** * ice_dpll_hw_input_prio_set - set input priority value in hardware * @pf: board private structure @@ -733,22 +713,19 @@ ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv, */ static int ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv, - const struct dpll_device *dpll, void *dpll_priv, + const struct dpll_device *dpll, void *dpll_priv, enum dpll_pin_state *state, struct netlink_ext_ack *extack, enum ice_dpll_pin_type pin_type) { struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; - struct ice_dpll *d; + struct ice_dpll *d = dpll_priv; int ret; ret = ice_dpll_cb_lock(pf); if (ret) return ret; - d = ice_find_dpll(pf, dpll); - if (!d) - goto unlock; ret = ice_dpll_pin_state_update(pf, p, pin_type); if (ret) goto unlock; From f7249c9b725c2af7c62da0a1e7a10fbfb5cfbbc8 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 01:01:12 +0200 Subject: [PATCH 34/36] ice: get pf pointer from dpll_priv without type cast fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 25bc95cf66d4..e7b784df5b5a 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -150,8 +150,9 @@ ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv, struct netlink_ext_ack *extack, enum ice_dpll_pin_type pin_type) { - struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; + struct ice_dpll *d = dpll_priv; + struct ice_pf *pf = d->pf; int ret; ret = ice_dpll_cb_lock(pf); @@ -238,8 +239,9 @@ ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv, u64 *frequency, struct netlink_ext_ack *extack, enum ice_dpll_pin_type pin_type) { - struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; + struct ice_dpll *d = dpll_priv; + struct ice_pf *pf = d->pf; int ret; ret = ice_dpll_cb_lock(pf); @@ -616,8 +618,9 @@ ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv, bool enable, struct netlink_ext_ack *extack, enum ice_dpll_pin_type pin_type) { - struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; + struct ice_dpll *d = dpll_priv; + struct ice_pf *pf = d->pf; int ret; ret = ice_dpll_cb_lock(pf); @@ -718,9 +721,9 @@ ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv, struct netlink_ext_ack *extack, enum ice_dpll_pin_type pin_type) { - struct ice_pf *pf = ((struct ice_dpll *)dpll_priv)->pf; struct ice_dpll_pin *p = pin_priv; struct ice_dpll *d = dpll_priv; + struct ice_pf *pf = d->pf; int ret; ret = ice_dpll_cb_lock(pf); From 2fee3e92876f492ab637a112a945bdebd41f838d Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 14:44:49 +0200 Subject: [PATCH 35/36] ice: improve error reporting Use netlink to report errors. Remove dev_dbg traces as they are no longer useful. fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 166 +++++++++++----------- 1 file changed, 86 insertions(+), 80 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index e7b784df5b5a..10132e19f88d 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -53,7 +53,7 @@ static const char * const pin_type_name[] = { * 0 - if lock acquired * negative - lock not acquired or dpll was deinitialized */ -static int ice_dpll_cb_lock(struct ice_pf *pf) +static int ice_dpll_cb_lock(struct ice_pf *pf, struct netlink_ext_ack *extack) { int i; @@ -61,9 +61,15 @@ static int ice_dpll_cb_lock(struct ice_pf *pf) if (mutex_trylock(&pf->dplls.lock)) return 0; usleep_range(100, 150); - if (!test_bit(ICE_FLAG_DPLL, pf->flags)) + if (!test_bit(ICE_FLAG_DPLL, pf->flags)) { + if (extack) + NL_SET_ERR_MSG(extack, + "ice dpll was deinitialized"); return -EFAULT; + } } + if (extack) + NL_SET_ERR_MSG(extack, "was not able to acquire mutex"); return -EBUSY; } @@ -95,7 +101,8 @@ static void ice_dpll_cb_unlock(struct ice_pf *pf) */ static int ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin, - enum ice_dpll_pin_type pin_type, const u32 freq) + enum ice_dpll_pin_type pin_type, const u32 freq, + struct netlink_ext_ack *extack) { int ret; u8 flags; @@ -115,10 +122,11 @@ ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin, return -EINVAL; } if (ret) { - dev_err(ice_pf_to_dev(pf), - "err:%d %s failed to set pin freq:%u on pin:%u\n", - ret, ice_aq_str(pf->hw.adminq.sq_last_status), - freq, pin->idx); + NL_SET_ERR_MSG_FMT(extack, + "err:%d %s failed to set pin freq:%u on pin:%u\n", + ret, + ice_aq_str(pf->hw.adminq.sq_last_status), + freq, pin->idx); return ret; } pin->freq = freq; @@ -155,13 +163,11 @@ ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv, struct ice_pf *pf = d->pf; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; - ret = ice_dpll_pin_freq_set(pf, p, pin_type, frequency); + ret = ice_dpll_pin_freq_set(pf, p, pin_type, frequency, extack); ice_dpll_cb_unlock(pf); - if (ret) - NL_SET_ERR_MSG(extack, "frequency was not set"); return ret; } @@ -244,7 +250,7 @@ ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv, struct ice_pf *pf = d->pf; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; *frequency = p->freq; @@ -318,7 +324,8 @@ ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv, */ static int ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin, - enum ice_dpll_pin_type pin_type) + enum ice_dpll_pin_type pin_type, + struct netlink_ext_ack *extack) { u8 flags = 0; int ret; @@ -340,10 +347,10 @@ ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin, return -EINVAL; } if (ret) - dev_err(ice_pf_to_dev((struct ice_pf *)(hw->back)), - "err:%d %s failed to enable %s pin:%u\n", - ret, ice_aq_str(hw->adminq.sq_last_status), - pin_type_name[pin_type], pin->idx); + NL_SET_ERR_MSG_FMT(extack, + "err:%d %s failed to enable %s pin:%u\n", + ret, ice_aq_str(hw->adminq.sq_last_status), + pin_type_name[pin_type], pin->idx); return ret; } @@ -363,7 +370,8 @@ ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin, */ static int ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin, - enum ice_dpll_pin_type pin_type) + enum ice_dpll_pin_type pin_type, + struct netlink_ext_ack *extack) { u8 flags = 0; int ret; @@ -383,10 +391,10 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin, return -EINVAL; } if (ret) - dev_err(ice_pf_to_dev((struct ice_pf *)(hw->back)), - "err:%d %s failed to disable %s pin:%u\n", - ret, ice_aq_str(hw->adminq.sq_last_status), - pin_type_name[pin_type], pin->idx); + NL_SET_ERR_MSG_FMT(extack, + "err:%d %s failed to disable %s pin:%u\n", + ret, ice_aq_str(hw->adminq.sq_last_status), + pin_type_name[pin_type], pin->idx); return ret; } @@ -408,7 +416,8 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin, */ int ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, - enum ice_dpll_pin_type pin_type) + enum ice_dpll_pin_type pin_type, + struct netlink_ext_ack *extack) { int ret; @@ -478,10 +487,18 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, return 0; err: - dev_err(ice_pf_to_dev(pf), - "err:%d %s failed to update %s pin:%u\n", - ret, ice_aq_str(pf->hw.adminq.sq_last_status), - pin_type_name[pin_type], pin->idx); + if (extack) + NL_SET_ERR_MSG_FMT(extack, + "err:%d %s failed to update %s pin:%u\n", + ret, + ice_aq_str(pf->hw.adminq.sq_last_status), + pin_type_name[pin_type], pin->idx); + else + dev_err_ratelimited(ice_pf_to_dev(pf), + "err:%d %s failed to update %s pin:%u\n", + ret, + ice_aq_str(pf->hw.adminq.sq_last_status), + pin_type_name[pin_type], pin->idx); return ret; } @@ -501,17 +518,19 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, */ static int ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll, - struct ice_dpll_pin *pin, const u32 prio) + struct ice_dpll_pin *pin, const u32 prio, + struct netlink_ext_ack *extack) { int ret; ret = ice_aq_set_cgu_ref_prio(&pf->hw, dpll->dpll_idx, pin->idx, (u8)prio); if (ret) - dev_err(ice_pf_to_dev(pf), - "err:%d %s failed to set pin prio:%u on pin:%u\n", - ret, ice_aq_str(pf->hw.adminq.sq_last_status), - prio, pin->idx); + NL_SET_ERR_MSG_FMT(extack, + "err:%d %s failed to set pin prio:%u on pin:%u\n", + ret, + ice_aq_str(pf->hw.adminq.sq_last_status), + prio, pin->idx); else dpll->input_prio[pin->idx] = prio; @@ -530,21 +549,20 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll, * * 0 - success * * negative - failure */ -static int ice_dpll_lock_status_get(const struct dpll_device *dpll, void *priv, - enum dpll_lock_status *status, - struct netlink_ext_ack *extack) +static int +ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, + enum dpll_lock_status *status, + struct netlink_ext_ack *extack) { - struct ice_dpll *d = priv; + struct ice_dpll *d = dpll_priv; struct ice_pf *pf = d->pf; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; *status = ice_dpll_status[d->dpll_state]; ice_dpll_cb_unlock(pf); - dev_dbg(ice_pf_to_dev(pf), "%s: dpll:%p, pf:%p, ret:%d\n", __func__, - dpll, pf, ret); return ret; } @@ -623,20 +641,16 @@ ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv, struct ice_pf *pf = d->pf; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; if (enable) - ret = ice_dpll_pin_enable(&pf->hw, p, pin_type); + ret = ice_dpll_pin_enable(&pf->hw, p, pin_type, extack); else - ret = ice_dpll_pin_disable(&pf->hw, p, pin_type); + ret = ice_dpll_pin_disable(&pf->hw, p, pin_type, extack); if (!ret) - ret = ice_dpll_pin_state_update(pf, p, pin_type); + ret = ice_dpll_pin_state_update(pf, p, pin_type, extack); ice_dpll_cb_unlock(pf); - if (ret) - dev_err(ice_pf_to_dev(pf), - "%s: dpll:%p, pin:%p, p:%p pf:%p enable:%d ret:%d\n", - __func__, dpll, pin, p, pf, enable, ret); return ret; } @@ -726,10 +740,10 @@ ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv, struct ice_pf *pf = d->pf; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; - ret = ice_dpll_pin_state_update(pf, p, pin_type); + ret = ice_dpll_pin_state_update(pf, p, pin_type, extack); if (ret) goto unlock; if (pin_type == ICE_DPLL_PIN_TYPE_INPUT) @@ -739,10 +753,6 @@ ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv, ret = 0; unlock: ice_dpll_cb_unlock(pf); - if (ret) - dev_err(ice_pf_to_dev(pf), - "%s: dpll:%p, pin:%p, pf:%p state: %d ret:%d\n", - __func__, dpll, pin, pf, *state, ret); return ret; } @@ -825,13 +835,11 @@ ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv, struct ice_pf *pf = d->pf; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; *prio = d->input_prio[p->idx]; ice_dpll_cb_unlock(pf); - dev_dbg(ice_pf_to_dev(pf), "%s: dpll:%p, pin:%p, pf:%p ret:%d\n", - __func__, dpll, pin, pf, ret); return 0; } @@ -868,15 +876,11 @@ ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv, return ret; } - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; - ret = ice_dpll_hw_input_prio_set(pf, d, p, prio); - if (ret) - NL_SET_ERR_MSG_FMT(extack, "unable to set prio: %u", prio); + ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack); ice_dpll_cb_unlock(pf); - dev_dbg(ice_pf_to_dev(pf), "%s: dpll:%p, pin:%p, pf:%p ret:%d\n", - __func__, dpll, pin, pf, ret); return ret; } @@ -960,7 +964,7 @@ ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv, u32 hw_idx; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; hw_idx = parent->idx - pf->dplls.base_rclk_idx; @@ -969,16 +973,22 @@ ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv, if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) || (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) { + NL_SET_ERR_MSG_FMT(extack, + "pin:%u state:%u on parent:%u already set", + p->idx, state, parent->idx); ret = -EINVAL; goto unlock; } ret = ice_aq_set_phy_rec_clk_out(&pf->hw, hw_idx, enable, &p->freq); + if (ret) + NL_SET_ERR_MSG_FMT(extack, + "err:%d %s failed to set pin state:%u for pin:%u on parent:%u\n", + ret, + ice_aq_str(pf->hw.adminq.sq_last_status), + state, p->idx, parent->idx); unlock: ice_dpll_cb_unlock(pf); - dev_dbg(ice_pf_to_dev(pf), - "%s: parent:%p, pin:%p, pf:%p hw_idx:%u enable:%d ret:%d\n", - __func__, parent_pin, pin, pf, hw_idx, enable, ret); return ret; } @@ -1010,14 +1020,15 @@ ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv, u32 hw_idx; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, extack); if (ret) return ret; hw_idx = parent->idx - pf->dplls.base_rclk_idx; if (hw_idx >= pf->dplls.num_inputs) goto unlock; - ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT); + ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT, + extack); if (ret) goto unlock; @@ -1025,9 +1036,6 @@ ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv, ret = 0; unlock: ice_dpll_cb_unlock(pf); - dev_dbg(ice_pf_to_dev(pf), - "%s: parent:%p, pin:%p, pf:%p hw_idx:%u state:%u ret:%d\n", - __func__, parent_pin, pin, pf, hw_idx, *state, ret); return ret; } @@ -1136,7 +1144,7 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init) d->active_input = pf->dplls.inputs[d->input_idx].pin; p = &pf->dplls.inputs[d->input_idx]; return ice_dpll_pin_state_update(pf, p, - ICE_DPLL_PIN_TYPE_INPUT); + ICE_DPLL_PIN_TYPE_INPUT, NULL); } if (d->dpll_state == ICE_CGU_STATE_HOLDOVER || d->dpll_state == ICE_CGU_STATE_FREERUN) { @@ -1145,13 +1153,13 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init) d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID; d->input_idx = ICE_DPLL_PIN_IDX_INVALID; ret = ice_dpll_pin_state_update(pf, p, - ICE_DPLL_PIN_TYPE_INPUT); + ICE_DPLL_PIN_TYPE_INPUT, NULL); } else if (d->input_idx != d->prev_input_idx) { p = &pf->dplls.inputs[d->prev_input_idx]; - ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT); + ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT, NULL); p = &pf->dplls.inputs[d->input_idx]; d->active_input = p->pin; - ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT); + ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT, NULL); d->prev_input_idx = d->input_idx; } @@ -1173,7 +1181,7 @@ static void ice_dpll_periodic_work(struct kthread_work *work) struct ice_dpll *dp = &pf->dplls.pps; int ret; - ret = ice_dpll_cb_lock(pf); + ret = ice_dpll_cb_lock(pf, NULL); if (ret == -EBUSY) goto resched; else if (ret) @@ -1579,7 +1587,6 @@ ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu) if (cgu) dpll_device_unregister(d->dpll, &ice_dpll_ops, d); dpll_device_put(d->dpll); - dev_dbg(ice_pf_to_dev(pf), "(%p) dpll removed\n", d); } /** @@ -1725,7 +1732,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, DPLL_PIN_CAPS_PRIORITY_CAN_CHANGE; } pins[i].prop.capabilities |= DPLL_PIN_CAPS_STATE_CAN_CHANGE; - ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type); + ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL); if (ret) return ret; pins[i].prop.freq_supported = @@ -1759,7 +1766,7 @@ static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf) pin->pf = pf; return ice_dpll_pin_state_update(pf, pin, - ICE_DPLL_PIN_TYPE_RCLK_INPUT); + ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL); } /** @@ -1958,7 +1965,6 @@ void ice_dpll_init(struct ice_pf *pf) goto deinit_pins; } mutex_unlock(&d->lock); - dev_dbg(ice_pf_to_dev(pf), "DPLLs init successful\n"); return; From de30b8da914af605be0832c0b9497a38844aaf45 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Mon, 19 Jun 2023 14:53:18 +0200 Subject: [PATCH 36/36] ice: fix documentation fix "ice: implement dpll interface to control" Signed-off-by: Arkadiusz Kubalewski --- drivers/net/ethernet/intel/ice/ice_dpll.c | 55 ++++++++++++----------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 10132e19f88d..c0a14d6d6ada 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -11,11 +11,7 @@ #define ICE_DPLL_PIN_IDX_INVALID 0xff #define ICE_DPLL_RCLK_NUM_PER_PF 1 -/** - * dpll_lock_status - map ice cgu states into dpll's subsystem lock status - */ -static const enum dpll_lock_status -ice_dpll_status[__DPLL_LOCK_STATUS_MAX] = { +static const enum dpll_lock_status ice_dpll_status[] = { [ICE_CGU_STATE_FREERUN] = DPLL_LOCK_STATUS_UNLOCKED, [ICE_CGU_STATE_LOCKED] = DPLL_LOCK_STATUS_LOCKED, [ICE_CGU_STATE_LOCKED_HO_ACQ] = DPLL_LOCK_STATUS_LOCKED_HO_ACQ, @@ -23,7 +19,11 @@ ice_dpll_status[__DPLL_LOCK_STATUS_MAX] = { }; /** - * ice_dpll_pin_type - enumerate ice pin types + * enum ice_dpll_pin_type - enumerate ice pin types: + * @ICE_DPLL_PIN_INVALID: invalid pin type + * @ICE_DPLL_PIN_TYPE_INPUT: input pin + * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin + * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin */ enum ice_dpll_pin_type { ICE_DPLL_PIN_INVALID, @@ -32,9 +32,6 @@ enum ice_dpll_pin_type { ICE_DPLL_PIN_TYPE_RCLK_INPUT, }; -/** - * pin_type_name - string names of ice pin types - */ static const char * const pin_type_name[] = { [ICE_DPLL_PIN_TYPE_INPUT] = "input", [ICE_DPLL_PIN_TYPE_OUTPUT] = "output", @@ -44,6 +41,7 @@ static const char * const pin_type_name[] = { /** * ice_dpll_cb_lock - lock dplls mutex in callback context * @pf: private board structure + * @extack: error reporting * * Lock the mutex from the callback operations invoked by dpll subsystem. * Prevent dead lock caused by `rmmod ice` when dpll callbacks are under stress @@ -91,6 +89,7 @@ static void ice_dpll_cb_unlock(struct ice_pf *pf) * @pin: pointer to a pin * @pin_type: type of pin being configured * @freq: frequency to be set + * @extack: error reporting * * Set requested frequency on a pin. * @@ -314,6 +313,7 @@ ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv, * @hw: board private hw structure * @pin: pointer to a pin * @pin_type: type of pin being enabled + * @extack: error reporting * * Enable a pin on both dplls. Store current state in pin->flags. * @@ -360,6 +360,7 @@ ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin, * @hw: board private hw structure * @pin: pointer to a pin * @pin_type: type of pin being disabled + * @extack: error reporting * * Disable a pin on both dplls. Store current state in pin->flags. * @@ -401,9 +402,10 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin, /** * ice_dpll_pin_state_update - update pin's state - * @hw: private board struct + * @pf: private board struct * @pin: structure with pin attributes to be updated * @pin_type: type of pin being updated + * @extack: error reporting * * Determine pin current state and frequency, then update struct * holding the pin info. For input pin states are separated for each @@ -508,6 +510,7 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, * @dpll: ice dpll pointer * @pin: ice pin pointer * @prio: priority value being set on a dpll + * @extack: error reporting * * Internal wrapper for setting the priority in the hardware. * @@ -540,7 +543,9 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll, /** * ice_dpll_lock_status_get - get dpll lock status callback * @dpll: registered dpll pointer + * @dpll_priv: private data pointer passed on dpll registration * @status: on success holds dpll's lock status + * @extack: error reporting * * Dpll subsystem callback, provides dpll's lock status. * @@ -570,7 +575,7 @@ ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, /** * ice_dpll_mode_get - get dpll's working mode * @dpll: registered dpll pointer - * @priv: private data pointer passed on dpll registration + * @dpll_priv: private data pointer passed on dpll registration * @mode: on success holds current working mode of dpll * @extack: error reporting * @@ -580,7 +585,7 @@ ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, * * 0 - success * * negative - failure */ -static int ice_dpll_mode_get(const struct dpll_device *dpll, void *priv, +static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv, enum dpll_mode *mode, struct netlink_ext_ack *extack) { @@ -590,9 +595,9 @@ static int ice_dpll_mode_get(const struct dpll_device *dpll, void *priv, } /** - * ice_dpll_mode_get - check if dpll's working mode is supported + * ice_dpll_mode_supported - check if dpll's working mode is supported * @dpll: registered dpll pointer - * @priv: private data pointer passed on dpll registration + * @dpll_priv: private data pointer passed on dpll registration * @mode: mode to be checked for support * @extack: error reporting * @@ -603,7 +608,8 @@ static int ice_dpll_mode_get(const struct dpll_device *dpll, void *priv, * * true - mode is supported * * false - mode is not supported */ -static bool ice_dpll_mode_supported(const struct dpll_device *dpll, void *priv, +static bool ice_dpll_mode_supported(const struct dpll_device *dpll, + void *dpll_priv, enum dpll_mode mode, struct netlink_ext_ack *extack) { @@ -619,7 +625,7 @@ static bool ice_dpll_mode_supported(const struct dpll_device *dpll, void *priv, * @pin_priv: private data pointer passed on pin registration * @dpll: registered dpll pointer * @dpll_priv: private data pointer passed on dpll registration - * @state: state of pin to be set + * @enable: if pin shalll be enabled * @extack: error reporting * @pin_type: type of a pin * @@ -937,10 +943,10 @@ ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv, /** * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin - * @dpll: registered dpll pointer * @pin: pointer to a pin * @pin_priv: private data pointer passed on pin registration * @parent_pin: pin parent pointer + * @parent_pin_priv: parent private data pointer passed on pin registration * @state: state to be set on pin * @extack: error reporting * @@ -998,6 +1004,7 @@ ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv, * @pin: pointer to a pin * @pin_priv: private data pointer passed on pin registration * @parent_pin: pin parent pointer + * @parent_pin_priv: pin parent priv data pointer passed on pin registration * @state: on success holds pin state on parent pin * @extack: error reporting * @@ -1109,6 +1116,7 @@ static void ice_dpll_notify_changes(struct ice_dpll *d) * ice_dpll_update_state - update dpll state * @pf: pf private structure * @d: pointer to queried dpll device + * @init: if function called on initialization of ice dpll * * Poll current state of dpll from hw and update ice_dpll struct. * @@ -1211,7 +1219,6 @@ static void ice_dpll_periodic_work(struct kthread_work *work) /** * ice_dpll_release_pins - release pins resources from dpll subsystem - * @pf: board private structure * @pins: pointer to pins array * @count: number of pins * @@ -1294,7 +1301,6 @@ ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins, * @pins: pointer to pins array * @ops: callback ops registered with the pins * @count: number of pins - * @cgu: if cgu is present and controlled by this NIC * * Register pins of a given array with given dpll in dpll subsystem. * @@ -1351,7 +1357,7 @@ ice_dpll_deinit_direct_pins(bool cgu, struct ice_dpll_pin *pins, int count, /** * ice_dpll_init_direct_pins - initialize direct pins - * @dpll: dpll pointer to register pins with + * @pf: board private structure * @cgu: if cgu is present and controlled by this NIC * @pins: pointer to pins array * @start_idx: on which index shall allocation start in dpll subsystem @@ -1427,11 +1433,9 @@ static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf) /** * ice_dpll_init_rclk_pins - initialize recovered clock pin - * @dpll: dpll pointer to register pins with - * @cgu: if cgu is present and controlled by this NIC - * @pins: pointer to pins array + * @pf: board private structure + * @pin: pin to register * @start_idx: on which index shall allocation start in dpll subsystem - * @count: number of pins * @ops: callback ops registered with the pins * * Allocate resource for recovered clock pin in dpll subsystem. Register the @@ -1575,6 +1579,8 @@ static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu) /** * ice_dpll_deinit_dpll - deinitialize dpll device * @pf: board private structure + * @d: pointer to ice_dpll + * @cgu: if cgu is present and controlled by this NIC * * If cgu is owned unregister the dpll from dpll subsystem. * Release resources of dpll device from dpll subsystem. @@ -1747,7 +1753,6 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, /** * ice_dpll_init_info_rclk_pin - initializes rclk pin information * @pf: board private structure - * @pin_type: type of pins being initialized * * Init information for rclk pin, cache them in pf->dplls.rclk. *