* [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features
@ 2024-07-04 8:11 Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 1/7] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state Kory Maincent
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:11 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent, Sai Krishna
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
This patch series adds new c33 features to the PSE API.
- Expand the PSE PI informations status with power, class and failure
reason
- Add the possibility to get and set the PSE PIs power limit
Changes in v6:
- Rebase on top of net-next
- Link to v5: https://lore.kernel.org/r/20240628-feature_poe_power_cap-v5-0-5e1375d3817a@bootlin.com
Changes in v5:
- Fix few nitpick.
- Link to v4: https://lore.kernel.org/r/20240625-feature_poe_power_cap-v4-0-b0813aad57d5@bootlin.com
Changes in v4:
- Made few update in PSE extended state an substate.
- Add support for c33 pse power limit ranges.
- Few changes in the specs and the documentation.
- Link to v3: https://lore.kernel.org/r/20240614-feature_poe_power_cap-v3-0-a26784e78311@bootlin.com
Changes in v3:
- Use u32 instead of u8 size for c33 pse extended state and substate.
- Reformat the state and substate enumeration to follow Oleksij proposal which
is more IEEE 802.3 standard compliant
- Sent the first patch standalone in net.
- Link to v2: https://lore.kernel.org/r/20240607-feature_poe_power_cap-v2-0-c03c2deb83ab@bootlin.com
Changes in v2:
- Use uA and uV instead of mA and mV to have more precision in the power
calculation. Need to use 64bit variables for the calculation.
- Modify the pd-92x0behavior in case of setting the current out of the
available ranges. Report an error now.
- Link to v1: https://lore.kernel.org/r/20240529-feature_poe_power_cap-v1-0-0c4b1d5953b8@bootlin.com
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Kory Maincent (7):
net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state
netlink: specs: Expand the PSE netlink command with C33 new features
net: pse-pd: pd692x0: Expand ethtool status message
net: pse-pd: Add new power limit get and set c33 features
net: ethtool: Add new power limit get and set features
netlink: specs: Expand the PSE netlink command with C33 pw-limit attributes
net: pse-pd: pd692x0: Enhance with new current limit and voltage read callbacks
Documentation/netlink/specs/ethtool.yaml | 58 +++++
Documentation/networking/ethtool-netlink.rst | 87 +++++++-
drivers/net/pse-pd/pd692x0.c | 317 ++++++++++++++++++++++++++-
drivers/net/pse-pd/pse_core.c | 172 ++++++++++++++-
include/linux/ethtool.h | 20 ++
include/linux/pse-pd/pse.h | 51 +++++
include/uapi/linux/ethtool.h | 191 ++++++++++++++++
include/uapi/linux/ethtool_netlink.h | 12 +
net/ethtool/pse-pd.c | 119 +++++++++-
9 files changed, 997 insertions(+), 30 deletions(-)
---
base-commit: 2b117c82eb31424d12326707ba9085dd31fb193b
change-id: 20240425-feature_poe_power_cap-18e90ba7294b
Best regards,
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v6 1/7] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
@ 2024-07-04 8:11 ` Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 2/7] netlink: specs: Expand the PSE netlink command with C33 new features Kory Maincent
` (7 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:11 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
This update expands the status information provided by ethtool for PSE c33.
It includes details such as the detected class, current power delivered,
and extended state information.
Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v2:
- Move on PSE string error messages to ETHTOOL_LINK_EXT_STATE and
ETHTOOL_LINK_EXT_SUBSTATE with fixed enumeration in aim to unify
interface diagnostic.
Change in v3:
- Add ethtool netlink documentation and kdoc.
- Move on to u32 for state and substate.
- Update C33 pse extended state and substate following Oleksij proposal.
Change in v4:
- Made few changes in the c33 pse extended state and substate enumerations.
- Update pse_reply to send extended substate only if extended state is present.
---
Documentation/networking/ethtool-netlink.rst | 37 ++++++
include/linux/ethtool.h | 15 +++
include/linux/pse-pd/pse.h | 8 ++
include/uapi/linux/ethtool.h | 191 +++++++++++++++++++++++++++
include/uapi/linux/ethtool_netlink.h | 4 +
net/ethtool/pse-pd.c | 32 ++++-
6 files changed, 286 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index bfe2eda8580d..0656ad4be000 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -1740,6 +1740,13 @@ Kernel response contents:
PSE functions.
``ETHTOOL_A_C33_PSE_PW_D_STATUS`` u32 power detection status of the
PoE PSE.
+ ``ETHTOOL_A_C33_PSE_PW_CLASS`` u32 power class of the PoE PSE.
+ ``ETHTOOL_A_C33_PSE_ACTUAL_PW`` u32 actual power drawn on the
+ PoE PSE.
+ ``ETHTOOL_A_C33_PSE_EXT_STATE`` u32 power extended state of the
+ PoE PSE.
+ ``ETHTOOL_A_C33_PSE_EXT_SUBSTATE`` u32 power extended substatus of
+ the PoE PSE.
====================================== ====== =============================
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
@@ -1772,6 +1779,36 @@ The same goes for ``ETHTOOL_A_C33_PSE_ADMIN_PW_D_STATUS`` implementing
.. kernel-doc:: include/uapi/linux/ethtool.h
:identifiers: ethtool_c33_pse_pw_d_status
+When set, the optional ``ETHTOOL_A_C33_PSE_PW_CLASS`` attribute identifies
+the power class of the C33 PSE. It depends on the class negotiated between
+the PSE and the PD. This option is corresponding to ``IEEE 802.3-2022``
+30.9.1.1.8 aPSEPowerClassification.
+
+When set, the optional ``ETHTOOL_A_C33_PSE_ACTUAL_PW`` attribute identifies
+This option is corresponding to ``IEEE 802.3-2022`` 30.9.1.1.23 aPSEActualPower.
+Actual power is reported in mW.
+
+When set, the optional ``ETHTOOL_A_C33_PSE_EXT_STATE`` attribute identifies
+the extended error state of the C33 PSE. Possible values are:
+
+.. kernel-doc:: include/uapi/linux/ethtool.h
+ :identifiers: ethtool_c33_pse_ext_state
+
+When set, the optional ``ETHTOOL_A_C33_PSE_EXT_SUBSTATE`` attribute identifies
+the extended error state of the C33 PSE. Possible values are:
+Possible values are:
+
+.. kernel-doc:: include/uapi/linux/ethtool.h
+ :identifiers: ethtool_c33_pse_ext_substate_class_num_events
+ ethtool_c33_pse_ext_substate_error_condition
+ ethtool_c33_pse_ext_substate_mr_pse_enable
+ ethtool_c33_pse_ext_substate_option_detect_ted
+ ethtool_c33_pse_ext_substate_option_vport_lim
+ ethtool_c33_pse_ext_substate_ovld_detected
+ ethtool_c33_pse_ext_substate_pd_dll_power_type
+ ethtool_c33_pse_ext_substate_power_not_available
+ ethtool_c33_pse_ext_substate_short_detected
+
PSE_SET
=======
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index f74bb0cf8ed1..4d1fc0679d5d 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -1271,4 +1271,19 @@ struct ethtool_forced_speed_map {
void
ethtool_forced_speed_maps_init(struct ethtool_forced_speed_map *maps, u32 size);
+
+/* C33 PSE extended state and substate. */
+struct ethtool_c33_pse_ext_state_info {
+ enum ethtool_c33_pse_ext_state c33_pse_ext_state;
+ union {
+ enum ethtool_c33_pse_ext_substate_error_condition error_condition;
+ enum ethtool_c33_pse_ext_substate_mr_pse_enable mr_pse_enable;
+ enum ethtool_c33_pse_ext_substate_option_detect_ted option_detect_ted;
+ enum ethtool_c33_pse_ext_substate_option_vport_lim option_vport_lim;
+ enum ethtool_c33_pse_ext_substate_ovld_detected ovld_detected;
+ enum ethtool_c33_pse_ext_substate_power_not_available power_not_available;
+ enum ethtool_c33_pse_ext_substate_short_detected short_detected;
+ u32 __c33_pse_ext_substate;
+ };
+};
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 6eec24ffa866..38b9308e5e7a 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -36,12 +36,20 @@ struct pse_control_config {
* functions. IEEE 802.3-2022 30.9.1.1.2 aPSEAdminState
* @c33_pw_status: power detection status of the PSE.
* IEEE 802.3-2022 30.9.1.1.5 aPSEPowerDetectionStatus:
+ * @c33_pw_class: detected class of a powered PD
+ * IEEE 802.3-2022 30.9.1.1.8 aPSEPowerClassification
+ * @c33_actual_pw: power currently delivered by the PSE in mW
+ * IEEE 802.3-2022 30.9.1.1.23 aPSEActualPower
+ * @c33_ext_state_info: extended state information of the PSE
*/
struct pse_control_status {
enum ethtool_podl_pse_admin_state podl_admin_state;
enum ethtool_podl_pse_pw_d_status podl_pw_status;
enum ethtool_c33_pse_admin_state c33_admin_state;
enum ethtool_c33_pse_pw_d_status c33_pw_status;
+ u32 c33_pw_class;
+ u32 c33_actual_pw;
+ struct ethtool_c33_pse_ext_state_info c33_ext_state_info;
};
/**
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index e011384c915c..230110b97029 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -752,6 +752,197 @@ enum ethtool_module_power_mode {
ETHTOOL_MODULE_POWER_MODE_HIGH,
};
+/**
+ * enum ethtool_c33_pse_ext_state - groups of PSE extended states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION: Group of error_condition states
+ * @ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID: Group of mr_mps_valid states
+ * @ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE: Group of mr_pse_enable states
+ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED: Group of option_detect_ted
+ * states
+ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM: Group of option_vport_lim states
+ * @ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED: Group of ovld_detected states
+ * @ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE: Group of pd_dll_power_type
+ * states
+ * @ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE: Group of power_not_available
+ * states
+ * @ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED: Group of short_detected states
+ */
+enum ethtool_c33_pse_ext_state {
+ ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION = 1,
+ ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
+ ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
+ ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED,
+ ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE,
+ ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_mr_mps_valid - mr_mps_valid states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD: Underload
+ * state
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN: Port is not
+ * connected
+ *
+ * The PSE monitors either the DC or AC Maintain Power Signature
+ * (MPS, see 33.2.9.1). This variable indicates the presence or absence of
+ * a valid MPS.
+ */
+enum ethtool_c33_pse_ext_substate_mr_mps_valid {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_error_condition - error_condition states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT: Non-existing
+ * port number
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT: Undefined port
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT: Internal
+ * hardware fault
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON:
+ * Communication error after force on
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS: Unknown
+ * port status
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF: Host
+ * crash turn off
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN:
+ * Host crash force shutdown
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE: Configuration
+ * change
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP: Over
+ * temperature detected
+ *
+ * error_condition is a variable indicating the status of
+ * implementation-specific fault conditions or optionally other system faults
+ * that prevent the PSE from meeting the specifications in Table 33–11 and that
+ * require the PSE not to source power. These error conditions are different
+ * from those monitored by the state diagrams in Figure 33–10.
+ */
+enum ethtool_c33_pse_ext_substate_error_condition {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_mr_pse_enable - mr_pse_enable states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE: Disable
+ * pin active
+ *
+ * mr_pse_enable is control variable that selects PSE operation and test
+ * functions.
+ */
+enum ethtool_c33_pse_ext_substate_mr_pse_enable {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE = 1,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_option_detect_ted - option_detect_ted
+ * states functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS: Detection
+ * in process
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR:
+ * Connection check error
+ *
+ * option_detect_ted is a variable indicating if detection can be performed
+ * by the PSE during the ted_timer interval.
+ */
+enum ethtool_c33_pse_ext_substate_option_detect_ted {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_option_vport_lim - option_vport_lim states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE: Main supply
+ * voltage is high
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE: Main supply
+ * voltage is low
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION: Voltage
+ * injection into the port
+ *
+ * option_vport_lim is an optional variable indicates if VPSE is out of the
+ * operating range during normal operating state.
+ */
+enum ethtool_c33_pse_ext_substate_option_vport_lim {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_ovld_detected - ovld_detected states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD: Overload state
+ *
+ * ovld_detected is a variable indicating if the PSE output current has been
+ * in an overload condition (see 33.2.7.6) for at least TCUT of a one-second
+ * sliding time.
+ */
+enum ethtool_c33_pse_ext_substate_ovld_detected {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD = 1,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_power_not_available - power_not_available
+ * states functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED: Power
+ * budget exceeded for the controller
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET:
+ * Configured port power limit exceeded controller power budget
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT:
+ * Power request from PD exceeds port limit
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT: Power
+ * denied due to Hardware power limit
+ *
+ * power_not_available is a variable that is asserted in an
+ * implementation-dependent manner when the PSE is no longer capable of
+ * sourcing sufficient power to support the attached PD. Sufficient power
+ * is defined by classification; see 33.2.6.
+ */
+enum ethtool_c33_pse_ext_substate_power_not_available {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_short_detected - short_detected states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION: Short
+ * condition was detected
+ *
+ * short_detected is a variable indicating if the PSE output current has been
+ * in a short circuit condition for TLIM within a sliding window (see 33.2.7.7).
+ */
+enum ethtool_c33_pse_ext_substate_short_detected {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION = 1,
+};
+
/**
* enum ethtool_pse_types - Types of PSE controller.
* @ETHTOOL_PSE_UNKNOWN: Type of PSE controller is unknown
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 840dabdc9d88..b8895da001bc 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -939,6 +939,10 @@ enum {
ETHTOOL_A_C33_PSE_ADMIN_STATE, /* u32 */
ETHTOOL_A_C33_PSE_ADMIN_CONTROL, /* u32 */
ETHTOOL_A_C33_PSE_PW_D_STATUS, /* u32 */
+ ETHTOOL_A_C33_PSE_PW_CLASS, /* u32 */
+ ETHTOOL_A_C33_PSE_ACTUAL_PW, /* u32 */
+ ETHTOOL_A_C33_PSE_EXT_STATE, /* u32 */
+ ETHTOOL_A_C33_PSE_EXT_SUBSTATE, /* u32 */
/* add new constants above here */
__ETHTOOL_A_PSE_CNT,
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 2c981d443f27..d2a1c14d789f 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -86,7 +86,16 @@ static int pse_reply_size(const struct ethnl_req_info *req_base,
len += nla_total_size(sizeof(u32)); /* _C33_PSE_ADMIN_STATE */
if (st->c33_pw_status > 0)
len += nla_total_size(sizeof(u32)); /* _C33_PSE_PW_D_STATUS */
-
+ if (st->c33_pw_class > 0)
+ len += nla_total_size(sizeof(u32)); /* _C33_PSE_PW_CLASS */
+ if (st->c33_actual_pw > 0)
+ len += nla_total_size(sizeof(u32)); /* _C33_PSE_ACTUAL_PW */
+ if (st->c33_ext_state_info.c33_pse_ext_state > 0) {
+ len += nla_total_size(sizeof(u32)); /* _C33_PSE_EXT_STATE */
+ if (st->c33_ext_state_info.__c33_pse_ext_substate > 0)
+ /* _C33_PSE_EXT_SUBSTATE */
+ len += nla_total_size(sizeof(u32));
+ }
return len;
}
@@ -117,6 +126,27 @@ static int pse_fill_reply(struct sk_buff *skb,
st->c33_pw_status))
return -EMSGSIZE;
+ if (st->c33_pw_class > 0 &&
+ nla_put_u32(skb, ETHTOOL_A_C33_PSE_PW_CLASS,
+ st->c33_pw_class))
+ return -EMSGSIZE;
+
+ if (st->c33_actual_pw > 0 &&
+ nla_put_u32(skb, ETHTOOL_A_C33_PSE_ACTUAL_PW,
+ st->c33_actual_pw))
+ return -EMSGSIZE;
+
+ if (st->c33_ext_state_info.c33_pse_ext_state > 0) {
+ if (nla_put_u32(skb, ETHTOOL_A_C33_PSE_EXT_STATE,
+ st->c33_ext_state_info.c33_pse_ext_state))
+ return -EMSGSIZE;
+
+ if (st->c33_ext_state_info.__c33_pse_ext_substate > 0 &&
+ nla_put_u32(skb, ETHTOOL_A_C33_PSE_EXT_SUBSTATE,
+ st->c33_ext_state_info.__c33_pse_ext_substate))
+ return -EMSGSIZE;
+ }
+
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v6 2/7] netlink: specs: Expand the PSE netlink command with C33 new features
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 1/7] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state Kory Maincent
@ 2024-07-04 8:11 ` Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 3/7] net: pse-pd: pd692x0: Expand ethtool status message Kory Maincent
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:11 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
Expand the c33 PSE attributes with PSE class, extended state information
and power consumption.
./ynl/cli.py --spec netlink/specs/ethtool.yaml --no-schema --do pse-get
--json '{"header":{"dev-name":"eth0"}}'
{'c33-pse-actual-pw': 1700,
'c33-pse-admin-state': 3,
'c33-pse-pw-class': 4,
'c33-pse-pw-d-status': 4,
'header': {'dev-index': 4, 'dev-name': 'eth0'}}
./ynl/cli.py --spec netlink/specs/ethtool.yaml --no-schema --do pse-get
--json '{"header":{"dev-name":"eth0"}}'
{'c33-pse-admin-state': 3,
'c33-pse-ext-state': 'mr-mps-valid',
'c33-pse-ext-substate': 2,
'c33-pse-pw-d-status': 2,
'header': {'dev-index': 4, 'dev-name': 'eth0'}}
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v3:
- Update c33-pse-ext-state and c33-pse-ext-substate to u32
- Add enum for listing c33-pse-ext-state
Change in v4:
- Add name-prefix.
- Use hyphen-case instead of snwke_case.
- Use yaml list format.
- Updated substate list.
---
Documentation/netlink/specs/ethtool.yaml | 36 ++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 949e2722505d..3c7744acc6c7 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -24,6 +24,21 @@ definitions:
name: module-fw-flash-status
type: enum
entries: [ started, in_progress, completed, error ]
+ -
+ name: c33-pse-ext-state
+ enum-name:
+ type: enum
+ name-prefix: ethtool-c33-pse-ext-state-
+ entries:
+ - none
+ - error-condition
+ - mr-mps-valid
+ - mr-pse-enable
+ - option-detect-ted
+ - option-vport-lim
+ - ovld-detected
+ - power-not-available
+ - short-detected
attribute-sets:
-
@@ -955,6 +970,23 @@ attribute-sets:
name: c33-pse-pw-d-status
type: u32
name-prefix: ethtool-a-
+ -
+ name: c33-pse-pw-class
+ type: u32
+ name-prefix: ethtool-a-
+ -
+ name: c33-pse-actual-pw
+ type: u32
+ name-prefix: ethtool-a-
+ -
+ name: c33-pse-ext-state
+ type: u32
+ name-prefix: ethtool-a-
+ enum: c33-pse-ext-state
+ -
+ name: c33-pse-ext-substate
+ type: u32
+ name-prefix: ethtool-a-
-
name: rss
attributes:
@@ -1672,6 +1704,10 @@ operations:
- c33-pse-admin-state
- c33-pse-admin-control
- c33-pse-pw-d-status
+ - c33-pse-pw-class
+ - c33-pse-actual-pw
+ - c33-pse-ext-state
+ - c33-pse-ext-substate
dump: *pse-get-op
-
name: pse-set
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v6 3/7] net: pse-pd: pd692x0: Expand ethtool status message
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 1/7] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 2/7] netlink: specs: Expand the PSE netlink command with C33 new features Kory Maincent
@ 2024-07-04 8:11 ` Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 4/7] net: pse-pd: Add new power limit get and set c33 features Kory Maincent
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:11 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
This update expands pd692x0_ethtool_get_status() callback with newly
introduced details such as the detected class, current power delivered,
and extended state information.
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v2:
- Move in from string status message to c33_pse_ext_state_info.
Change in v3:
- Update extended state and substate list.
Change in v4:
- Update extended state and substate list.
---
drivers/net/pse-pd/pd692x0.c | 101 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index 820358b71f0f..cce1b7ce044b 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -73,6 +73,7 @@ enum {
PD692X0_MSG_SET_PORT_PARAM,
PD692X0_MSG_GET_PORT_STATUS,
PD692X0_MSG_DOWNLOAD_CMD,
+ PD692X0_MSG_GET_PORT_CLASS,
/* add new message above here */
PD692X0_MSG_CNT
@@ -149,6 +150,12 @@ static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
.data = {0x16, 0x16, 0x99, 0x4e,
0x4e, 0x4e, 0x4e, 0x4e},
},
+ [PD692X0_MSG_GET_PORT_CLASS] = {
+ .key = PD692X0_KEY_REQ,
+ .sub = {0x05, 0xc4},
+ .data = {0x4e, 0x4e, 0x4e, 0x4e,
+ 0x4e, 0x4e, 0x4e, 0x4e},
+ },
};
static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
@@ -435,6 +442,84 @@ static int pd692x0_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
}
}
+struct pd692x0_pse_ext_state_mapping {
+ u32 status_code;
+ enum ethtool_c33_pse_ext_state pse_ext_state;
+ u32 pse_ext_substate;
+};
+
+static const struct pd692x0_pse_ext_state_mapping
+pd692x0_pse_ext_state_map[] = {
+ {0x06, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE},
+ {0x07, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE},
+ {0x08, ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE},
+ {0x0C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT},
+ {0x11, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT},
+ {0x12, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT},
+ {0x1B, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS},
+ {0x1C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
+ {0x1E, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD},
+ {0x1F, ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD},
+ {0x20, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED},
+ {0x21, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT},
+ {0x22, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE},
+ {0x24, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION},
+ {0x25, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
+ {0x34, ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION},
+ {0x35, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP},
+ {0x36, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP},
+ {0x37, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
+ {0x3C, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET},
+ {0x3D, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT},
+ {0x41, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT},
+ {0x43, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
+ {0xA7, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR},
+ {0xA8, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN},
+ { /* sentinel */ }
+};
+
+static void
+pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info,
+ u32 status_code)
+{
+ const struct pd692x0_pse_ext_state_mapping *ext_state_map;
+
+ ext_state_map = pd692x0_pse_ext_state_map;
+ while (ext_state_map->status_code) {
+ if (ext_state_map->status_code == status_code) {
+ c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state;
+ c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate;
+ return;
+ }
+ ext_state_map++;
+ }
+}
+
static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
unsigned long id,
struct netlink_ext_ack *extack,
@@ -442,6 +527,7 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
{
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
struct pd692x0_msg msg, buf = {0};
+ u32 class;
int ret;
ret = pd692x0_fw_unavailable(priv);
@@ -471,6 +557,21 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
priv->admin_state[id] = status->c33_admin_state;
+ pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]);
+
+ status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100;
+
+ memset(&buf, 0, sizeof(buf));
+ msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
+ msg.sub[2] = id;
+ ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
+ if (ret < 0)
+ return ret;
+
+ class = buf.data[3] >> 4;
+ if (class <= 8)
+ status->c33_pw_class = class;
+
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v6 4/7] net: pse-pd: Add new power limit get and set c33 features
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
` (2 preceding siblings ...)
2024-07-04 8:11 ` [PATCH net-next v6 3/7] net: pse-pd: pd692x0: Expand ethtool status message Kory Maincent
@ 2024-07-04 8:11 ` Kory Maincent
2024-07-04 8:12 ` [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features Kory Maincent
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:11 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent, Sai Krishna
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
This patch add a way to get and set the power limit of a PSE PI.
For that it uses regulator API callbacks wrapper like get_voltage() and
get/set_current_limit() as power is simply V * I.
We used mW unit as defined by the IEEE 802.3-2022 standards.
set_current_limit() uses the voltage return by get_voltage() and the
desired power limit to calculate the current limit. get_voltage() callback
is then mandatory to set the power limit.
get_current_limit() callback is by default looking at a driver callback
and fallback to extracting the current limit from _pse_ethtool_get_status()
if the driver does not set its callback. We prefer let the user the choice
because ethtool_get_status return much more information than the current
limit.
expand pse status with c33_pw_limit_ranges to return the ranges available
to configure the power limit.
Reviewed-by: Sai Krishna <saikrishnag@marvell.com>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v2:
- Use uA and uV instead of mA and mV to have more precision in the power
calculation. Need to use 64bit variables for the calculation.
Change in v4:
- Rename the power limit value to c33_avail_pw_limit.
- Add support for c33_pw_limit_ranges
Change in v5:
- Update an error message and a return value.
---
drivers/net/pse-pd/pse_core.c | 172 +++++++++++++++++++++++++++++++++++++++---
include/linux/pse-pd/pse.h | 43 +++++++++++
2 files changed, 204 insertions(+), 11 deletions(-)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 795ab264eaf2..16f364b3473b 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -265,10 +265,113 @@ static int pse_pi_disable(struct regulator_dev *rdev)
return ret;
}
+static int _pse_pi_get_voltage(struct regulator_dev *rdev)
+{
+ struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
+ const struct pse_controller_ops *ops;
+ int id;
+
+ ops = pcdev->ops;
+ if (!ops->pi_get_voltage)
+ return -EOPNOTSUPP;
+
+ id = rdev_get_id(rdev);
+ return ops->pi_get_voltage(pcdev, id);
+}
+
+static int pse_pi_get_voltage(struct regulator_dev *rdev)
+{
+ struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
+ int ret;
+
+ mutex_lock(&pcdev->lock);
+ ret = _pse_pi_get_voltage(rdev);
+ mutex_unlock(&pcdev->lock);
+
+ return ret;
+}
+
+static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
+ int id,
+ struct netlink_ext_ack *extack,
+ struct pse_control_status *status);
+
+static int pse_pi_get_current_limit(struct regulator_dev *rdev)
+{
+ struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
+ const struct pse_controller_ops *ops;
+ struct netlink_ext_ack extack = {};
+ struct pse_control_status st = {};
+ int id, uV, ret;
+ s64 tmp_64;
+
+ ops = pcdev->ops;
+ id = rdev_get_id(rdev);
+ mutex_lock(&pcdev->lock);
+ if (ops->pi_get_current_limit) {
+ ret = ops->pi_get_current_limit(pcdev, id);
+ goto out;
+ }
+
+ /* If pi_get_current_limit() callback not populated get voltage
+ * from pi_get_voltage() and power limit from ethtool_get_status()
+ * to calculate current limit.
+ */
+ ret = _pse_pi_get_voltage(rdev);
+ if (!ret) {
+ dev_err(pcdev->dev, "Voltage null\n");
+ ret = -ERANGE;
+ goto out;
+ }
+ if (ret < 0)
+ goto out;
+ uV = ret;
+
+ ret = _pse_ethtool_get_status(pcdev, id, &extack, &st);
+ if (ret)
+ goto out;
+
+ if (!st.c33_avail_pw_limit) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ tmp_64 = st.c33_avail_pw_limit;
+ tmp_64 *= 1000000000ull;
+ /* uA = mW * 1000000000 / uV */
+ ret = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
+
+out:
+ mutex_unlock(&pcdev->lock);
+ return ret;
+}
+
+static int pse_pi_set_current_limit(struct regulator_dev *rdev, int min_uA,
+ int max_uA)
+{
+ struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
+ const struct pse_controller_ops *ops;
+ int id, ret;
+
+ ops = pcdev->ops;
+ if (!ops->pi_set_current_limit)
+ return -EOPNOTSUPP;
+
+ id = rdev_get_id(rdev);
+ mutex_lock(&pcdev->lock);
+ ret = ops->pi_set_current_limit(pcdev, id, max_uA);
+ mutex_unlock(&pcdev->lock);
+
+ return ret;
+}
+
static const struct regulator_ops pse_pi_ops = {
.is_enabled = pse_pi_is_enabled,
.enable = pse_pi_enable,
.disable = pse_pi_disable,
+ .get_voltage = pse_pi_get_voltage,
+ .get_current_limit = pse_pi_get_current_limit,
+ .set_current_limit = pse_pi_set_current_limit,
};
static int
@@ -298,7 +401,9 @@ devm_pse_pi_regulator_register(struct pse_controller_dev *pcdev,
rdesc->ops = &pse_pi_ops;
rdesc->owner = pcdev->owner;
- rinit_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+ rinit_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_CURRENT;
+ rinit_data->constraints.max_uA = MAX_PI_CURRENT;
rinit_data->supply_regulator = "vpwr";
rconfig.dev = pcdev->dev;
@@ -626,6 +731,23 @@ struct pse_control *of_pse_control_get(struct device_node *node)
}
EXPORT_SYMBOL_GPL(of_pse_control_get);
+static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
+ int id,
+ struct netlink_ext_ack *extack,
+ struct pse_control_status *status)
+{
+ const struct pse_controller_ops *ops;
+
+ ops = pcdev->ops;
+ if (!ops->ethtool_get_status) {
+ NL_SET_ERR_MSG(extack,
+ "PSE driver does not support status report");
+ return -EOPNOTSUPP;
+ }
+
+ return ops->ethtool_get_status(pcdev, id, extack, status);
+}
+
/**
* pse_ethtool_get_status - get status of PSE control
* @psec: PSE control pointer
@@ -638,19 +760,10 @@ int pse_ethtool_get_status(struct pse_control *psec,
struct netlink_ext_ack *extack,
struct pse_control_status *status)
{
- const struct pse_controller_ops *ops;
int err;
- ops = psec->pcdev->ops;
-
- if (!ops->ethtool_get_status) {
- NL_SET_ERR_MSG(extack,
- "PSE driver does not support status report");
- return -EOPNOTSUPP;
- }
-
mutex_lock(&psec->pcdev->lock);
- err = ops->ethtool_get_status(psec->pcdev, psec->id, extack, status);
+ err = _pse_ethtool_get_status(psec->pcdev, psec->id, extack, status);
mutex_unlock(&psec->pcdev->lock);
return err;
@@ -732,6 +845,43 @@ int pse_ethtool_set_config(struct pse_control *psec,
}
EXPORT_SYMBOL_GPL(pse_ethtool_set_config);
+/**
+ * pse_ethtool_set_pw_limit - set PSE control power limit
+ * @psec: PSE control pointer
+ * @extack: extack for reporting useful error messages
+ * @pw_limit: power limit value in mW
+ *
+ * Return: 0 on success and failure value on error
+ */
+int pse_ethtool_set_pw_limit(struct pse_control *psec,
+ struct netlink_ext_ack *extack,
+ const unsigned int pw_limit)
+{
+ int uV, uA, ret;
+ s64 tmp_64;
+
+ ret = regulator_get_voltage(psec->ps);
+ if (!ret) {
+ NL_SET_ERR_MSG(extack,
+ "Can't calculate the current, PSE voltage read is 0");
+ return -ERANGE;
+ }
+ if (ret < 0) {
+ NL_SET_ERR_MSG(extack,
+ "Error reading PSE voltage");
+ return ret;
+ }
+ uV = ret;
+
+ tmp_64 = pw_limit;
+ tmp_64 *= 1000000000ull;
+ /* uA = mW * 1000000000 / uV */
+ uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
+
+ return regulator_set_current_limit(psec->ps, 0, uA);
+}
+EXPORT_SYMBOL_GPL(pse_ethtool_set_pw_limit);
+
bool pse_has_podl(struct pse_control *psec)
{
return psec->pcdev->types & ETHTOOL_PSE_PODL;
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 38b9308e5e7a..591a53e082e6 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -9,6 +9,9 @@
#include <linux/list.h>
#include <uapi/linux/ethtool.h>
+/* Maximum current in uA according to IEEE 802.3-2022 Table 145-1 */
+#define MAX_PI_CURRENT 1920000
+
struct phy_device;
struct pse_controller_dev;
@@ -41,6 +44,12 @@ struct pse_control_config {
* @c33_actual_pw: power currently delivered by the PSE in mW
* IEEE 802.3-2022 30.9.1.1.23 aPSEActualPower
* @c33_ext_state_info: extended state information of the PSE
+ * @c33_avail_pw_limit: available power limit of the PSE in mW
+ * IEEE 802.3-2022 145.2.5.4 pse_avail_pwr
+ * @c33_pw_limit_ranges: supported power limit configuration range. The driver
+ * is in charge of the memory allocation.
+ * @c33_pw_limit_nb_ranges: number of supported power limit configuration
+ * ranges
*/
struct pse_control_status {
enum ethtool_podl_pse_admin_state podl_admin_state;
@@ -50,6 +59,9 @@ struct pse_control_status {
u32 c33_pw_class;
u32 c33_actual_pw;
struct ethtool_c33_pse_ext_state_info c33_ext_state_info;
+ u32 c33_avail_pw_limit;
+ struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
+ u32 c33_pw_limit_nb_ranges;
};
/**
@@ -61,6 +73,14 @@ struct pse_control_status {
* May also return negative errno.
* @pi_enable: Configure the PSE PI as enabled.
* @pi_disable: Configure the PSE PI as disabled.
+ * @pi_get_voltage: Return voltage similarly to get_voltage regulator
+ * callback.
+ * @pi_get_current_limit: Get the configured current limit similarly to
+ * get_current_limit regulator callback.
+ * @pi_set_current_limit: Configure the current limit similarly to
+ * set_current_limit regulator callback.
+ * Should not return an error in case of MAX_PI_CURRENT
+ * current value set.
*/
struct pse_controller_ops {
int (*ethtool_get_status)(struct pse_controller_dev *pcdev,
@@ -70,6 +90,11 @@ struct pse_controller_ops {
int (*pi_is_enabled)(struct pse_controller_dev *pcdev, int id);
int (*pi_enable)(struct pse_controller_dev *pcdev, int id);
int (*pi_disable)(struct pse_controller_dev *pcdev, int id);
+ int (*pi_get_voltage)(struct pse_controller_dev *pcdev, int id);
+ int (*pi_get_current_limit)(struct pse_controller_dev *pcdev,
+ int id);
+ int (*pi_set_current_limit)(struct pse_controller_dev *pcdev,
+ int id, int max_uA);
};
struct module;
@@ -156,6 +181,11 @@ int pse_ethtool_get_status(struct pse_control *psec,
int pse_ethtool_set_config(struct pse_control *psec,
struct netlink_ext_ack *extack,
const struct pse_control_config *config);
+int pse_ethtool_set_pw_limit(struct pse_control *psec,
+ struct netlink_ext_ack *extack,
+ const unsigned int pw_limit);
+int pse_ethtool_get_pw_limit(struct pse_control *psec,
+ struct netlink_ext_ack *extack);
bool pse_has_podl(struct pse_control *psec);
bool pse_has_c33(struct pse_control *psec);
@@ -185,6 +215,19 @@ static inline int pse_ethtool_set_config(struct pse_control *psec,
return -EOPNOTSUPP;
}
+static inline int pse_ethtool_set_pw_limit(struct pse_control *psec,
+ struct netlink_ext_ack *extack,
+ const unsigned int pw_limit)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int pse_ethtool_get_pw_limit(struct pse_control *psec,
+ struct netlink_ext_ack *extack)
+{
+ return -EOPNOTSUPP;
+}
+
static inline bool pse_has_podl(struct pse_control *psec)
{
return false;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
` (3 preceding siblings ...)
2024-07-04 8:11 ` [PATCH net-next v6 4/7] net: pse-pd: Add new power limit get and set c33 features Kory Maincent
@ 2024-07-04 8:12 ` Kory Maincent
2024-07-06 1:41 ` Jakub Kicinski
2024-07-04 8:12 ` [PATCH net-next v6 6/7] netlink: specs: Expand the PSE netlink command with C33 pw-limit attributes Kory Maincent
` (3 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:12 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
This patch expands the status information provided by ethtool for PSE c33
with available power limit and available power limit ranges. It also adds
a call to pse_ethtool_set_pw_limit() to configure the PSE control power
limit.
Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v3:
- Add ethtool netlink documentation.
Change in v4:
- Update documentation
- Add support for c33 pse power limit ranges.
---
Documentation/networking/ethtool-netlink.rst | 64 ++++++++++++++------
include/linux/ethtool.h | 5 ++
include/uapi/linux/ethtool_netlink.h | 8 +++
net/ethtool/pse-pd.c | 89 +++++++++++++++++++++++++---
4 files changed, 141 insertions(+), 25 deletions(-)
diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index 0656ad4be000..3ab423b80e91 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -1730,24 +1730,28 @@ Request contents:
Kernel response contents:
- ====================================== ====== =============================
- ``ETHTOOL_A_PSE_HEADER`` nested reply header
- ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` u32 Operational state of the PoDL
- PSE functions
- ``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` u32 power detection status of the
- PoDL PSE.
- ``ETHTOOL_A_C33_PSE_ADMIN_STATE`` u32 Operational state of the PoE
- PSE functions.
- ``ETHTOOL_A_C33_PSE_PW_D_STATUS`` u32 power detection status of the
- PoE PSE.
- ``ETHTOOL_A_C33_PSE_PW_CLASS`` u32 power class of the PoE PSE.
- ``ETHTOOL_A_C33_PSE_ACTUAL_PW`` u32 actual power drawn on the
- PoE PSE.
- ``ETHTOOL_A_C33_PSE_EXT_STATE`` u32 power extended state of the
- PoE PSE.
- ``ETHTOOL_A_C33_PSE_EXT_SUBSTATE`` u32 power extended substatus of
- the PoE PSE.
- ====================================== ====== =============================
+ ========================================== ====== =============================
+ ``ETHTOOL_A_PSE_HEADER`` nested reply header
+ ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` u32 Operational state of the PoDL
+ PSE functions
+ ``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` u32 power detection status of the
+ PoDL PSE.
+ ``ETHTOOL_A_C33_PSE_ADMIN_STATE`` u32 Operational state of the PoE
+ PSE functions.
+ ``ETHTOOL_A_C33_PSE_PW_D_STATUS`` u32 power detection status of the
+ PoE PSE.
+ ``ETHTOOL_A_C33_PSE_PW_CLASS`` u32 power class of the PoE PSE.
+ ``ETHTOOL_A_C33_PSE_ACTUAL_PW`` u32 actual power drawn on the
+ PoE PSE.
+ ``ETHTOOL_A_C33_PSE_EXT_STATE`` u32 power extended state of the
+ PoE PSE.
+ ``ETHTOOL_A_C33_PSE_EXT_SUBSTATE`` u32 power extended substatus of
+ the PoE PSE.
+ ``ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT`` u32 currently configured power
+ limit of the PoE PSE.
+ ``ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES`` nested Supported power limit
+ configuration ranges.
+ ========================================== ====== =============================
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
the operational state of the PoDL PSE functions. The operational state of the
@@ -1809,6 +1813,16 @@ Possible values are:
ethtool_c33_pse_ext_substate_power_not_available
ethtool_c33_pse_ext_substate_short_detected
+When set, the optional ``ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT`` attribute
+identifies the C33 PSE power limit in mW.
+
+When set the optional ``ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES`` nested attribute
+identifies the C33 PSE power limit ranges through
+``ETHTOOL_A_C33_PSE_PWR_VAL_LIMIT_RANGE_MIN`` and
+``ETHTOOL_A_C33_PSE_PWR_VAL_LIMIT_RANGE_MAX``.
+If the controller works with fixed classes, the min and max values will be
+equal.
+
PSE_SET
=======
@@ -1820,6 +1834,8 @@ Request contents:
``ETHTOOL_A_PSE_HEADER`` nested request header
``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` u32 Control PoDL PSE Admin state
``ETHTOOL_A_C33_PSE_ADMIN_CONTROL`` u32 Control PSE Admin state
+ ``ETHTOOL_A_C33_PSE_AVAIL_PWR_LIMIT`` u32 Control PoE PSE available
+ power limit
====================================== ====== =============================
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` attribute is used
@@ -1830,6 +1846,18 @@ to control PoDL PSE Admin functions. This option is implementing
The same goes for ``ETHTOOL_A_C33_PSE_ADMIN_CONTROL`` implementing
``IEEE 802.3-2022`` 30.9.1.2.1 acPSEAdminControl.
+When set, the optional ``ETHTOOL_A_C33_PSE_AVAIL_PWR_LIMIT`` attribute is
+used to control the available power value limit for C33 PSE in milliwatts.
+This attribute corresponds to the `pse_available_power` variable described in
+``IEEE 802.3-2022`` 33.2.4.4 Variables and `pse_avail_pwr` in 145.2.5.4
+Variables, which are described in power classes.
+
+It was decided to use milliwatts for this interface to unify it with other
+power monitoring interfaces, which also use milliwatts, and to align with
+various existing products that document power consumption in watts rather than
+classes. If power limit configuration based on classes is needed, the
+conversion can be done in user space, for example by ethtool.
+
RSS_GET
=======
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 4d1fc0679d5d..784e63102c3a 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -1286,4 +1286,9 @@ struct ethtool_c33_pse_ext_state_info {
u32 __c33_pse_ext_substate;
};
};
+
+struct ethtool_c33_pse_pw_limit_range {
+ u32 min;
+ u32 max;
+};
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index b8895da001bc..6d5bdcc67631 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -930,6 +930,12 @@ enum {
};
/* Power Sourcing Equipment */
+enum {
+ ETHTOOL_A_C33_PSE_PW_LIMIT_UNSPEC,
+ ETHTOOL_A_C33_PSE_PW_LIMIT_MIN, /* u32 */
+ ETHTOOL_A_C33_PSE_PW_LIMIT_MAX, /* u32 */
+};
+
enum {
ETHTOOL_A_PSE_UNSPEC,
ETHTOOL_A_PSE_HEADER, /* nest - _A_HEADER_* */
@@ -943,6 +949,8 @@ enum {
ETHTOOL_A_C33_PSE_ACTUAL_PW, /* u32 */
ETHTOOL_A_C33_PSE_EXT_STATE, /* u32 */
ETHTOOL_A_C33_PSE_EXT_SUBSTATE, /* u32 */
+ ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT, /* u32 */
+ ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES, /* nest - _C33_PSE_PW_LIMIT_* */
/* add new constants above here */
__ETHTOOL_A_PSE_CNT,
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index d2a1c14d789f..ba46c9c8b12d 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -96,9 +96,46 @@ static int pse_reply_size(const struct ethnl_req_info *req_base,
/* _C33_PSE_EXT_SUBSTATE */
len += nla_total_size(sizeof(u32));
}
+ if (st->c33_avail_pw_limit > 0)
+ /* _C33_AVAIL_PSE_PW_LIMIT */
+ len += nla_total_size(sizeof(u32));
+ if (st->c33_pw_limit_nb_ranges > 0)
+ /* _C33_PSE_PW_LIMIT_RANGES */
+ len += st->c33_pw_limit_nb_ranges *
+ (nla_total_size(0) +
+ nla_total_size(sizeof(u32)) * 2);
+
return len;
}
+static int pse_put_pw_limit_ranges(struct sk_buff *skb,
+ const struct pse_control_status *st)
+{
+ const struct ethtool_c33_pse_pw_limit_range *pw_limit_ranges;
+ int i;
+
+ pw_limit_ranges = st->c33_pw_limit_ranges;
+ for (i = 0; i < st->c33_pw_limit_nb_ranges; i++) {
+ struct nlattr *nest;
+
+ nest = nla_nest_start(skb, ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES);
+ if (!nest)
+ return -EMSGSIZE;
+
+ if (nla_put_u32(skb, ETHTOOL_A_C33_PSE_PW_LIMIT_MIN,
+ pw_limit_ranges->min) ||
+ nla_put_u32(skb, ETHTOOL_A_C33_PSE_PW_LIMIT_MAX,
+ pw_limit_ranges->max)) {
+ nla_nest_cancel(skb, nest);
+ return -EMSGSIZE;
+ }
+ nla_nest_end(skb, nest);
+ pw_limit_ranges++;
+ }
+
+ return 0;
+}
+
static int pse_fill_reply(struct sk_buff *skb,
const struct ethnl_req_info *req_base,
const struct ethnl_reply_data *reply_base)
@@ -147,9 +184,25 @@ static int pse_fill_reply(struct sk_buff *skb,
return -EMSGSIZE;
}
+ if (st->c33_avail_pw_limit > 0 &&
+ nla_put_u32(skb, ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT,
+ st->c33_avail_pw_limit))
+ return -EMSGSIZE;
+
+ if (st->c33_pw_limit_nb_ranges > 0 &&
+ pse_put_pw_limit_ranges(skb, st))
+ return -EMSGSIZE;
+
return 0;
}
+static void pse_cleanup_data(struct ethnl_reply_data *reply_base)
+{
+ const struct pse_reply_data *data = PSE_REPDATA(reply_base);
+
+ kfree(data->status.c33_pw_limit_ranges);
+}
+
/* PSE_SET */
const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1] = {
@@ -160,6 +213,7 @@ const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1] = {
[ETHTOOL_A_C33_PSE_ADMIN_CONTROL] =
NLA_POLICY_RANGE(NLA_U32, ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED,
ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED),
+ [ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT] = { .type = NLA_U32 },
};
static int
@@ -202,19 +256,39 @@ static int
ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
{
struct net_device *dev = req_info->dev;
- struct pse_control_config config = {};
struct nlattr **tb = info->attrs;
struct phy_device *phydev;
+ int ret = 0;
phydev = dev->phydev;
+
+ if (tb[ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT]) {
+ unsigned int pw_limit;
+
+ pw_limit = nla_get_u32(tb[ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT]);
+ ret = pse_ethtool_set_pw_limit(phydev->psec, info->extack,
+ pw_limit);
+ if (ret)
+ return ret;
+ }
+
/* These values are already validated by the ethnl_pse_set_policy */
- if (pse_has_podl(phydev->psec))
- config.podl_admin_control = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
- if (pse_has_c33(phydev->psec))
- config.c33_admin_control = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]);
+ if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] ||
+ tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]) {
+ struct pse_control_config config = {};
+
+ if (pse_has_podl(phydev->psec))
+ config.podl_admin_control = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
+ if (pse_has_c33(phydev->psec))
+ config.c33_admin_control = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]);
+
+ ret = pse_ethtool_set_config(phydev->psec, info->extack,
+ &config);
+ if (ret)
+ return ret;
+ }
- /* Return errno directly - PSE has no notification */
- return pse_ethtool_set_config(phydev->psec, info->extack, &config);
+ return ret;
}
const struct ethnl_request_ops ethnl_pse_request_ops = {
@@ -227,6 +301,7 @@ const struct ethnl_request_ops ethnl_pse_request_ops = {
.prepare_data = pse_prepare_data,
.reply_size = pse_reply_size,
.fill_reply = pse_fill_reply,
+ .cleanup_data = pse_cleanup_data,
.set_validate = ethnl_set_pse_validate,
.set = ethnl_set_pse,
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v6 6/7] netlink: specs: Expand the PSE netlink command with C33 pw-limit attributes
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
` (4 preceding siblings ...)
2024-07-04 8:12 ` [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features Kory Maincent
@ 2024-07-04 8:12 ` Kory Maincent
2024-07-04 8:12 ` [PATCH net-next v6 7/7] net: pse-pd: pd692x0: Enhance with new current limit and voltage read callbacks Kory Maincent
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:12 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
Expand the c33 PSE attributes with power limit to be able to set and get
the PSE Power Interface power limit.
./ynl/cli.py --spec netlink/specs/ethtool.yaml --no-schema --do pse-get
--json '{"header":{"dev-name":"eth1"}}'
{'c33-pse-actual-pw': 1700,
'c33-pse-admin-state': 3,
'c33-pse-avail-pw-limit': 97500,
'c33-pse-pw-class': 4,
'c33-pse-pw-d-status': 4,
'c33-pse-pw-limit-ranges': [{'max': 18100, 'min': 15000},
{'max': 38000, 'min': 30000},
{'max': 65000, 'min': 60000},
{'max': 97500, 'min': 90000}],
'header': {'dev-index': 5, 'dev-name': 'eth1'}}
./ynl/cli.py --spec netlink/specs/ethtool.yaml --no-schema --do pse-set
--json '{"header":{"dev-name":"eth1"},
"c33-pse-avail-pw-limit":19000}'
None
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v4:
- Add support for c33 pse power limit ranges.
---
Documentation/netlink/specs/ethtool.yaml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 3c7744acc6c7..495e35fcfb21 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -939,6 +939,15 @@ attribute-sets:
-
name: power-mode
type: u8
+ -
+ name: c33-pse-pw-limit
+ attributes:
+ -
+ name: min
+ type: u32
+ -
+ name: max
+ type: u32
-
name: pse
attributes:
@@ -987,6 +996,16 @@ attribute-sets:
name: c33-pse-ext-substate
type: u32
name-prefix: ethtool-a-
+ -
+ name: c33-pse-avail-pw-limit
+ type: u32
+ name-prefix: ethtool-a-
+ -
+ name: c33-pse-pw-limit-ranges
+ name-prefix: ethtool-a-
+ type: nest
+ multi-attr: true
+ nested-attributes: c33-pse-pw-limit
-
name: rss
attributes:
@@ -1708,6 +1727,8 @@ operations:
- c33-pse-actual-pw
- c33-pse-ext-state
- c33-pse-ext-substate
+ - c33-pse-avail-pw-limit
+ - c33-pse-pw-limit-ranges
dump: *pse-get-op
-
name: pse-set
@@ -1721,6 +1742,7 @@ operations:
- header
- podl-pse-admin-control
- c33-pse-admin-control
+ - c33-pse-avail-pw-limit
-
name: rss-get
doc: Get RSS params.
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v6 7/7] net: pse-pd: pd692x0: Enhance with new current limit and voltage read callbacks
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
` (5 preceding siblings ...)
2024-07-04 8:12 ` [PATCH net-next v6 6/7] netlink: specs: Expand the PSE netlink command with C33 pw-limit attributes Kory Maincent
@ 2024-07-04 8:12 ` Kory Maincent
2024-07-05 13:10 ` [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
2024-07-06 1:50 ` patchwork-bot+netdevbpf
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-04 8:12 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Kory Maincent
From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
This patch expands PSE callbacks with newly introduced
pi_get/set_current_limit() and pi_get_voltage() callback.
It also add the power limit ranges description in the status returned.
The only way to set ps692x0 port power limit is by configure the power
class plus a small power supplement which maximum depends on each class.
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Change in v2:
- Use uA and uV instead of mA and mV to have more precision in the power
calculation. Need to use 64bit variables for the calculation.
- Modify the behavior in case of setting the current out of the available
ranges. Report an error now.
Change in v4:
- Add support for c33 pse power limit ranges.
---
drivers/net/pse-pd/pd692x0.c | 218 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 216 insertions(+), 2 deletions(-)
diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index cce1b7ce044b..29cc76a66c13 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -74,6 +74,8 @@ enum {
PD692X0_MSG_GET_PORT_STATUS,
PD692X0_MSG_DOWNLOAD_CMD,
PD692X0_MSG_GET_PORT_CLASS,
+ PD692X0_MSG_GET_PORT_MEAS,
+ PD692X0_MSG_GET_PORT_PARAM,
/* add new message above here */
PD692X0_MSG_CNT
@@ -135,7 +137,7 @@ static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
[PD692X0_MSG_SET_PORT_PARAM] = {
.key = PD692X0_KEY_CMD,
.sub = {0x05, 0xc0},
- .data = { 0, 0xff, 0xff, 0xff,
+ .data = { 0xf, 0xff, 0xff, 0xff,
0x4e, 0x4e, 0x4e, 0x4e},
},
[PD692X0_MSG_GET_PORT_STATUS] = {
@@ -156,6 +158,18 @@ static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
.data = {0x4e, 0x4e, 0x4e, 0x4e,
0x4e, 0x4e, 0x4e, 0x4e},
},
+ [PD692X0_MSG_GET_PORT_MEAS] = {
+ .key = PD692X0_KEY_REQ,
+ .sub = {0x05, 0xc5},
+ .data = {0x4e, 0x4e, 0x4e, 0x4e,
+ 0x4e, 0x4e, 0x4e, 0x4e},
+ },
+ [PD692X0_MSG_GET_PORT_PARAM] = {
+ .key = PD692X0_KEY_REQ,
+ .sub = {0x05, 0xc0},
+ .data = {0x4e, 0x4e, 0x4e, 0x4e,
+ 0x4e, 0x4e, 0x4e, 0x4e},
+ },
};
static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
@@ -520,6 +534,106 @@ pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info,
}
}
+struct pd692x0_class_pw {
+ int class;
+ int class_cfg_value;
+ int class_pw;
+ int max_added_class_pw;
+};
+
+#define PD692X0_CLASS_PW_TABLE_SIZE 4
+/* 4/2 pairs class configuration power table in compliance mode.
+ * Need to be arranged in ascending order of power support.
+ */
+static const struct pd692x0_class_pw
+pd692x0_class_pw_table[PD692X0_CLASS_PW_TABLE_SIZE] = {
+ {.class = 3, .class_cfg_value = 0x3, .class_pw = 15000, .max_added_class_pw = 3100},
+ {.class = 4, .class_cfg_value = 0x2, .class_pw = 30000, .max_added_class_pw = 8000},
+ {.class = 6, .class_cfg_value = 0x1, .class_pw = 60000, .max_added_class_pw = 5000},
+ {.class = 8, .class_cfg_value = 0x0, .class_pw = 90000, .max_added_class_pw = 7500},
+};
+
+static int pd692x0_pi_get_pw_from_table(int op_mode, int added_pw)
+{
+ const struct pd692x0_class_pw *pw_table;
+ int i;
+
+ pw_table = pd692x0_class_pw_table;
+ for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
+ if (pw_table->class_cfg_value == op_mode)
+ return pw_table->class_pw + added_pw * 100;
+ }
+
+ return -ERANGE;
+}
+
+static int pd692x0_pi_set_pw_from_table(struct device *dev,
+ struct pd692x0_msg *msg, int pw)
+{
+ const struct pd692x0_class_pw *pw_table;
+ int i;
+
+ pw_table = pd692x0_class_pw_table;
+ if (pw < pw_table->class_pw) {
+ dev_err(dev,
+ "Power limit %dmW not supported. Ranges minimal available: [%d-%d]\n",
+ pw,
+ pw_table->class_pw,
+ pw_table->class_pw + pw_table->max_added_class_pw);
+ return -ERANGE;
+ }
+
+ for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
+ if (pw > (pw_table->class_pw + pw_table->max_added_class_pw))
+ continue;
+
+ if (pw < pw_table->class_pw) {
+ dev_err(dev,
+ "Power limit %dmW not supported. Ranges availables: [%d-%d] or [%d-%d]\n",
+ pw,
+ (pw_table - 1)->class_pw,
+ (pw_table - 1)->class_pw + (pw_table - 1)->max_added_class_pw,
+ pw_table->class_pw,
+ pw_table->class_pw + pw_table->max_added_class_pw);
+ return -ERANGE;
+ }
+
+ msg->data[2] = pw_table->class_cfg_value;
+ msg->data[3] = (pw - pw_table->class_pw) / 100;
+ return 0;
+ }
+
+ pw_table--;
+ dev_warn(dev,
+ "Power limit %dmW not supported. Set to highest power limit %dmW\n",
+ pw, pw_table->class_pw + pw_table->max_added_class_pw);
+ msg->data[2] = pw_table->class_cfg_value;
+ msg->data[3] = pw_table->max_added_class_pw / 100;
+ return 0;
+}
+
+static int
+pd692x0_pi_get_pw_ranges(struct pse_control_status *st)
+{
+ const struct pd692x0_class_pw *pw_table;
+ int i;
+
+ pw_table = pd692x0_class_pw_table;
+ st->c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
+ sizeof(struct ethtool_c33_pse_pw_limit_range),
+ GFP_KERNEL);
+ if (!st->c33_pw_limit_ranges)
+ return -ENOMEM;
+
+ for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
+ st->c33_pw_limit_ranges[i].min = pw_table->class_pw;
+ st->c33_pw_limit_ranges[i].max = pw_table->class_pw + pw_table->max_added_class_pw;
+ }
+
+ st->c33_pw_limit_nb_ranges = i;
+ return 0;
+}
+
static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
unsigned long id,
struct netlink_ext_ack *extack,
@@ -558,9 +672,20 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
priv->admin_state[id] = status->c33_admin_state;
pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]);
-
status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100;
+ msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
+ msg.sub[2] = id;
+ memset(&buf, 0, sizeof(buf));
+ ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
+ if (ret < 0)
+ return ret;
+
+ ret = pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
+ if (ret < 0)
+ return ret;
+ status->c33_avail_pw_limit = ret;
+
memset(&buf, 0, sizeof(buf));
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
msg.sub[2] = id;
@@ -572,6 +697,10 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
if (class <= 8)
status->c33_pw_class = class;
+ ret = pd692x0_pi_get_pw_ranges(status);
+ if (ret < 0)
+ return ret;
+
return 0;
}
@@ -850,12 +979,97 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
return ret;
}
+static int pd692x0_pi_get_voltage(struct pse_controller_dev *pcdev, int id)
+{
+ struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
+ struct pd692x0_msg msg, buf = {0};
+ int ret;
+
+ ret = pd692x0_fw_unavailable(priv);
+ if (ret)
+ return ret;
+
+ msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_MEAS];
+ msg.sub[2] = id;
+ ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
+ if (ret < 0)
+ return ret;
+
+ /* Convert 0.1V unit to uV */
+ return (buf.sub[0] << 8 | buf.sub[1]) * 100000;
+}
+
+static int pd692x0_pi_get_current_limit(struct pse_controller_dev *pcdev,
+ int id)
+{
+ struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
+ struct pd692x0_msg msg, buf = {0};
+ int mW, uV, uA, ret;
+ s64 tmp_64;
+
+ msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
+ msg.sub[2] = id;
+ ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
+ if (ret < 0)
+ return ret;
+
+ ret = pd692x0_pi_get_pw_from_table(buf.data[2], buf.data[3]);
+ if (ret < 0)
+ return ret;
+ mW = ret;
+
+ ret = pd692x0_pi_get_voltage(pcdev, id);
+ if (ret < 0)
+ return ret;
+ uV = ret;
+
+ tmp_64 = mW;
+ tmp_64 *= 1000000000ull;
+ /* uA = mW * 1000000000 / uV */
+ uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
+ return uA;
+}
+
+static int pd692x0_pi_set_current_limit(struct pse_controller_dev *pcdev,
+ int id, int max_uA)
+{
+ struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
+ struct device *dev = &priv->client->dev;
+ struct pd692x0_msg msg, buf = {0};
+ int uV, ret, mW;
+ s64 tmp_64;
+
+ ret = pd692x0_fw_unavailable(priv);
+ if (ret)
+ return ret;
+
+ ret = pd692x0_pi_get_voltage(pcdev, id);
+ if (ret < 0)
+ return ret;
+ uV = ret;
+
+ msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
+ msg.sub[2] = id;
+ tmp_64 = uV;
+ tmp_64 *= max_uA;
+ /* mW = uV * uA / 1000000000 */
+ mW = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
+ ret = pd692x0_pi_set_pw_from_table(dev, &msg, mW);
+ if (ret)
+ return ret;
+
+ return pd692x0_sendrecv_msg(priv, &msg, &buf);
+}
+
static const struct pse_controller_ops pd692x0_ops = {
.setup_pi_matrix = pd692x0_setup_pi_matrix,
.ethtool_get_status = pd692x0_ethtool_get_status,
.pi_enable = pd692x0_pi_enable,
.pi_disable = pd692x0_pi_disable,
.pi_is_enabled = pd692x0_pi_is_enabled,
+ .pi_get_voltage = pd692x0_pi_get_voltage,
+ .pi_get_current_limit = pd692x0_pi_get_current_limit,
+ .pi_set_current_limit = pd692x0_pi_set_current_limit,
};
#define PD692X0_FW_LINE_MAX_SZ 0xff
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
` (6 preceding siblings ...)
2024-07-04 8:12 ` [PATCH net-next v6 7/7] net: pse-pd: pd692x0: Enhance with new current limit and voltage read callbacks Kory Maincent
@ 2024-07-05 13:10 ` Kory Maincent
2024-07-06 1:50 ` patchwork-bot+netdevbpf
8 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-05 13:10 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Oleksij Rempel, Jonathan Corbet
Cc: Thomas Petazzoni, linux-kernel, netdev, Dent Project, kernel,
linux-doc, Sai Krishna
On Thu, 04 Jul 2024 10:11:55 +0200
Kory Maincent <kory.maincent@bootlin.com> wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
>
> This patch series adds new c33 features to the PSE API.
> - Expand the PSE PI informations status with power, class and failure
> reason
> - Add the possibility to get and set the PSE PIs power limit
Hello, any news on this patch series?
Nearly all the patches have Oleksij Acked-by tag.
Is there anything that is missing?
Regards,
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features
2024-07-04 8:12 ` [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features Kory Maincent
@ 2024-07-06 1:41 ` Jakub Kicinski
2024-07-08 9:38 ` Kory Maincent
0 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2024-07-06 1:41 UTC (permalink / raw)
To: Kory Maincent
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Donald Hunter,
Oleksij Rempel, Jonathan Corbet, Thomas Petazzoni, linux-kernel,
netdev, Dent Project, kernel, linux-doc
On Thu, 04 Jul 2024 10:12:00 +0200 Kory Maincent wrote:
> + if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] ||
> + tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]) {
> + struct pse_control_config config = {};
> +
> + if (pse_has_podl(phydev->psec))
> + config.podl_admin_control = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
> + if (pse_has_c33(phydev->psec))
> + config.c33_admin_control = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]);
This smells of null-deref if user only passes one of the attributes.
But the fix should probably be in ethnl_set_pse_validate() so it won't
conflict (I'm speculating that it will need to go to net).
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
` (7 preceding siblings ...)
2024-07-05 13:10 ` [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
@ 2024-07-06 1:50 ` patchwork-bot+netdevbpf
8 siblings, 0 replies; 14+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-07-06 1:50 UTC (permalink / raw)
To: Kory Maincent
Cc: davem, edumazet, kuba, pabeni, donald.hunter, o.rempel, corbet,
thomas.petazzoni, linux-kernel, netdev, dentproject, kernel,
linux-doc, saikrishnag
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 04 Jul 2024 10:11:55 +0200 you wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
>
> This patch series adds new c33 features to the PSE API.
> - Expand the PSE PI informations status with power, class and failure
> reason
> - Add the possibility to get and set the PSE PIs power limit
>
> [...]
Here is the summary with links:
- [net-next,v6,1/7] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state
https://git.kernel.org/netdev/net-next/c/e46296002113
- [net-next,v6,2/7] netlink: specs: Expand the PSE netlink command with C33 new features
https://git.kernel.org/netdev/net-next/c/c8149739af86
- [net-next,v6,3/7] net: pse-pd: pd692x0: Expand ethtool status message
https://git.kernel.org/netdev/net-next/c/ae37dc574259
- [net-next,v6,4/7] net: pse-pd: Add new power limit get and set c33 features
https://git.kernel.org/netdev/net-next/c/4a83abcef5f4
- [net-next,v6,5/7] net: ethtool: Add new power limit get and set features
https://git.kernel.org/netdev/net-next/c/30d7b6727724
- [net-next,v6,6/7] netlink: specs: Expand the PSE netlink command with C33 pw-limit attributes
https://git.kernel.org/netdev/net-next/c/dac3de193095
- [net-next,v6,7/7] net: pse-pd: pd692x0: Enhance with new current limit and voltage read callbacks
https://git.kernel.org/netdev/net-next/c/a87e699c9d33
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features
2024-07-06 1:41 ` Jakub Kicinski
@ 2024-07-08 9:38 ` Kory Maincent
2024-07-08 18:33 ` Jakub Kicinski
0 siblings, 1 reply; 14+ messages in thread
From: Kory Maincent @ 2024-07-08 9:38 UTC (permalink / raw)
To: Jakub Kicinski
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Donald Hunter,
Oleksij Rempel, Jonathan Corbet, Thomas Petazzoni, linux-kernel,
netdev, Dent Project, kernel, linux-doc
On Fri, 5 Jul 2024 18:41:16 -0700
Jakub Kicinski <kuba@kernel.org> wrote:
> On Thu, 04 Jul 2024 10:12:00 +0200 Kory Maincent wrote:
> > + if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] ||
> > + tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]) {
> > + struct pse_control_config config = {};
> > +
> > + if (pse_has_podl(phydev->psec))
> > + config.podl_admin_control =
> > nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
> > + if (pse_has_c33(phydev->psec))
> > + config.c33_admin_control =
> > nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]);
>
> This smells of null-deref if user only passes one of the attributes.
> But the fix should probably be in ethnl_set_pse_validate() so it won't
> conflict (I'm speculating that it will need to go to net).
Mmh, indeed if the netlink PSE type attribute is different with the supported
PSE type we might have an issue here.
I am wondering, if I fix it in net won't it conflict with net-next now that
this series is merged?
Regards,
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features
2024-07-08 9:38 ` Kory Maincent
@ 2024-07-08 18:33 ` Jakub Kicinski
2024-07-09 13:20 ` Kory Maincent
0 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2024-07-08 18:33 UTC (permalink / raw)
To: Kory Maincent
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Donald Hunter,
Oleksij Rempel, Jonathan Corbet, Thomas Petazzoni, linux-kernel,
netdev, Dent Project, kernel, linux-doc
On Mon, 8 Jul 2024 11:38:46 +0200 Kory Maincent wrote:
> > This smells of null-deref if user only passes one of the attributes.
> > But the fix should probably be in ethnl_set_pse_validate() so it won't
> > conflict (I'm speculating that it will need to go to net).
>
> Mmh, indeed if the netlink PSE type attribute is different with the supported
> PSE type we might have an issue here.
>
> I am wondering, if I fix it in net won't it conflict with net-next now that
> this series is merged?
Don't worry I understand the code well enough to resolve any conflicts
(famous last words?). And if we fix as part of ethnl_set_pse_validate()
then there's no conflict, AFAICT.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features
2024-07-08 18:33 ` Jakub Kicinski
@ 2024-07-09 13:20 ` Kory Maincent
0 siblings, 0 replies; 14+ messages in thread
From: Kory Maincent @ 2024-07-09 13:20 UTC (permalink / raw)
To: Jakub Kicinski
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Donald Hunter,
Oleksij Rempel, Jonathan Corbet, Thomas Petazzoni, linux-kernel,
netdev, Dent Project, kernel, linux-doc
On Mon, 8 Jul 2024 11:33:00 -0700
Jakub Kicinski <kuba@kernel.org> wrote:
> On Mon, 8 Jul 2024 11:38:46 +0200 Kory Maincent wrote:
> [...]
> [...]
>
> Don't worry I understand the code well enough to resolve any conflicts
> (famous last words?). And if we fix as part of ethnl_set_pse_validate()
> then there's no conflict, AFAICT.
As you can see in the patch I just sent
https://lore.kernel.org/netdev/20240709131201.166421-1-kory.maincent@bootlin.com/T/#u
the fix is not in set_pse_validate() therefore you will have a merge conflict.
You could do this to solve the merge conflict:
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -256,6 +256,7 @@ static int
ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
{
struct net_device *dev = req_info->dev;
+ struct pse_control_config config = {};
struct nlattr **tb = info->attrs;
struct phy_device *phydev;
int ret = 0;
@@ -273,15 +274,13 @@ ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
}
/* These values are already validated by the ethnl_pse_set_policy */
+ if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL])
+ config.podl_admin_control = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
+ if (tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL])
+ config.c33_admin_control = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]);
+
if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] ||
tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]) {
- struct pse_control_config config = {};
-
- if (pse_has_podl(phydev->psec))
- config.podl_admin_control = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
- if (pse_has_c33(phydev->psec))
- config.c33_admin_control = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]);
-
ret = pse_ethtool_set_config(phydev->psec, info->extack,
&config);
if (ret)
Regards,
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-07-09 13:20 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-04 8:11 [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 1/7] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 2/7] netlink: specs: Expand the PSE netlink command with C33 new features Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 3/7] net: pse-pd: pd692x0: Expand ethtool status message Kory Maincent
2024-07-04 8:11 ` [PATCH net-next v6 4/7] net: pse-pd: Add new power limit get and set c33 features Kory Maincent
2024-07-04 8:12 ` [PATCH net-next v6 5/7] net: ethtool: Add new power limit get and set features Kory Maincent
2024-07-06 1:41 ` Jakub Kicinski
2024-07-08 9:38 ` Kory Maincent
2024-07-08 18:33 ` Jakub Kicinski
2024-07-09 13:20 ` Kory Maincent
2024-07-04 8:12 ` [PATCH net-next v6 6/7] netlink: specs: Expand the PSE netlink command with C33 pw-limit attributes Kory Maincent
2024-07-04 8:12 ` [PATCH net-next v6 7/7] net: pse-pd: pd692x0: Enhance with new current limit and voltage read callbacks Kory Maincent
2024-07-05 13:10 ` [PATCH net-next v6 0/7] net: pse-pd: Add new PSE c33 features Kory Maincent
2024-07-06 1:50 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).