diff mbox series

[4/8] net: pse-pd: pd692x0: Expand ethtool status message

Message ID 20240529-feature_poe_power_cap-v1-4-0c4b1d5953b8@bootlin.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [1/8] net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP | expand

Checks

Context Check Description
netdev/series_format warning Series does not have a cover letter
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; GEN HAS DIFF 2 files changed, 87 insertions(+);
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 902 this patch: 903
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 906 this patch: 906
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 906 this patch: 907
netdev/checkpatch warning CHECK: From:/Signed-off-by: email comments mismatch: 'From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>' != 'Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>' WARNING: line length of 83 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns WARNING: line length of 94 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Kory Maincent May 29, 2024, 2:09 p.m. UTC
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 a detailed status message.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/pse-pd/pd692x0.c | 96 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

Comments

Andrew Lunn May 29, 2024, 11:13 p.m. UTC | #1
> +static const struct pd692x0_status_msg pd692x0_status_msg_list[] = {
> +	{.id = 0x06, .msg = "Port is off: Main supply voltage is high."},
> +	{.id = 0x07, .msg = "Port is off: Main supply voltage is low."},
> +	{.id = 0x08, .msg = "Port is off: Disable all ports pin is active."},
> +	{.id = 0x0C, .msg = "Port is off: Non-existing port number."},
> +	{.id = 0x11, .msg = "Port is yet undefined."},
> +	{.id = 0x12, .msg = "Port is off: Internal hardware fault."},
> +	{.id = 0x1A, .msg = "Port is off: User setting."},
> +	{.id = 0x1B, .msg = "Port is off: Detection is in process."},
> +	{.id = 0x1C, .msg = "Port is off: Non-802.3AF/AT powered device."},
> +	{.id = 0x1E, .msg = "Port is off: Underload state."},
> +	{.id = 0x1F, .msg = "Port is off: Overload state."},
> +	{.id = 0x20, .msg = "Port is off: Power budget exceeded."},
> +	{.id = 0x21, .msg = "Port is off: Internal hardware routing error."},
> +	{.id = 0x22, .msg = "Port is off: Configuration change."},
> +	{.id = 0x24, .msg = "Port is off: Voltage injection into the port."},
> +	{.id = 0x25, .msg = "Port is off: Improper Capacitor Detection"},
> +	{.id = 0x26, .msg = "Port is off: Discharged load."},

I don't know of any other driver returning strings like this. Have you
seen any other PSE driver with anything similar?

> +	{.id = 0x34, .msg = "Port is off: Short condition."},
> +	{.id = 0x35, .msg = "Port is off: Over temperature at the port."},
> +	{.id = 0x36, .msg = "Port is off: Device is too hot."},
> +	{.id = 0x37, .msg = "Unknown device port status."},
> +	{.id = 0x3C, .msg = "Power Management-Static."},
> +	{.id = 0x3D, .msg = "Power Management-Static\u2014OVL."},

Is there something going on with UTF here? the \u2014 ?

	Andrew
Kory Maincent May 30, 2024, 9:33 a.m. UTC | #2
Thanks for the review!

On Thu, 30 May 2024 01:13:59 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

> > +static const struct pd692x0_status_msg pd692x0_status_msg_list[] = {
> > +	{.id = 0x06, .msg = "Port is off: Main supply voltage is high."},
> > +	{.id = 0x07, .msg = "Port is off: Main supply voltage is low."},
> > +	{.id = 0x08, .msg = "Port is off: Disable all ports pin is
> > active."},
> > +	{.id = 0x0C, .msg = "Port is off: Non-existing port number."},
> > +	{.id = 0x11, .msg = "Port is yet undefined."},
> > +	{.id = 0x12, .msg = "Port is off: Internal hardware fault."},
> > +	{.id = 0x1A, .msg = "Port is off: User setting."},
> > +	{.id = 0x1B, .msg = "Port is off: Detection is in process."},
> > +	{.id = 0x1C, .msg = "Port is off: Non-802.3AF/AT powered device."},
> > +	{.id = 0x1E, .msg = "Port is off: Underload state."},
> > +	{.id = 0x1F, .msg = "Port is off: Overload state."},
> > +	{.id = 0x20, .msg = "Port is off: Power budget exceeded."},
> > +	{.id = 0x21, .msg = "Port is off: Internal hardware routing
> > error."},
> > +	{.id = 0x22, .msg = "Port is off: Configuration change."},
> > +	{.id = 0x24, .msg = "Port is off: Voltage injection into the
> > port."},
> > +	{.id = 0x25, .msg = "Port is off: Improper Capacitor Detection"},
> > +	{.id = 0x26, .msg = "Port is off: Discharged load."},  
> 
> I don't know of any other driver returning strings like this. Have you
> seen any other PSE driver with anything similar?

We would like to be able to return the failure reason but there is nothing
generic in the IEEE 802.3 standard to be able to add it to the UAPI.
The TI controller has SUPPLY and FAULT EVENT Register which could report few
messages. I am not aware of other PoE controller and how they deal with it.
We could add sysfs for reporting the status messages for all the ports but I
don't think it is a better idea.

> > +	{.id = 0x34, .msg = "Port is off: Short condition."},
> > +	{.id = 0x35, .msg = "Port is off: Over temperature at the port."},
> > +	{.id = 0x36, .msg = "Port is off: Device is too hot."},
> > +	{.id = 0x37, .msg = "Unknown device port status."},
> > +	{.id = 0x3C, .msg = "Power Management-Static."},
> > +	{.id = 0x3D, .msg = "Power Management-Static\u2014OVL."},  
> 
> Is there something going on with UTF here? the \u2014 ?

Some copy paste of the messages bring a non utf-8 character :/
Will fix it, thanks for spotting it.

Regards,
Oleksij Rempel May 30, 2024, 10:13 a.m. UTC | #3
Hi,

On Thu, May 30, 2024 at 11:33:41AM +0200, Kory Maincent wrote:
> Thanks for the review!
> 
> On Thu, 30 May 2024 01:13:59 +0200
> Andrew Lunn <andrew@lunn.ch> wrote:
> 
> > > +static const struct pd692x0_status_msg pd692x0_status_msg_list[] = {
> > > +	{.id = 0x06, .msg = "Port is off: Main supply voltage is high."},
> > > +	{.id = 0x07, .msg = "Port is off: Main supply voltage is low."},
> > > +	{.id = 0x08, .msg = "Port is off: Disable all ports pin is
> > > active."},
> > > +	{.id = 0x0C, .msg = "Port is off: Non-existing port number."},
> > > +	{.id = 0x11, .msg = "Port is yet undefined."},
> > > +	{.id = 0x12, .msg = "Port is off: Internal hardware fault."},
> > > +	{.id = 0x1A, .msg = "Port is off: User setting."},
> > > +	{.id = 0x1B, .msg = "Port is off: Detection is in process."},
> > > +	{.id = 0x1C, .msg = "Port is off: Non-802.3AF/AT powered device."},
> > > +	{.id = 0x1E, .msg = "Port is off: Underload state."},
> > > +	{.id = 0x1F, .msg = "Port is off: Overload state."},
> > > +	{.id = 0x20, .msg = "Port is off: Power budget exceeded."},
> > > +	{.id = 0x21, .msg = "Port is off: Internal hardware routing
> > > error."},
> > > +	{.id = 0x22, .msg = "Port is off: Configuration change."},
> > > +	{.id = 0x24, .msg = "Port is off: Voltage injection into the
> > > port."},
> > > +	{.id = 0x25, .msg = "Port is off: Improper Capacitor Detection"},
> > > +	{.id = 0x26, .msg = "Port is off: Discharged load."},  
> > 
> > I don't know of any other driver returning strings like this. Have you
> > seen any other PSE driver with anything similar?
> 
> We would like to be able to return the failure reason but there is nothing
> generic in the IEEE 802.3 standard to be able to add it to the UAPI.
> The TI controller has SUPPLY and FAULT EVENT Register which could report few
> messages. I am not aware of other PoE controller and how they deal with it.
> We could add sysfs for reporting the status messages for all the ports but I
> don't think it is a better idea.

We have ETHTOOL_LINK_EXT_STATE* and THTOOL_LINK_EXT_SUBSTATE_ for
different kind of link fail diagnostic. I think it would be good to make
the same for PSE ports. Not all of them will overlap with other PSE
controllers, but we will have one unified diagnostic interface. It will
be easier for user space application to parse and react on it.
diff mbox series

Patch

diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index 6488b941703c..017a8efc43c4 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,79 @@  static int pd692x0_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
 	}
 }
 
+struct pd692x0_status_msg {
+	int id;
+	const char msg[63];
+};
+
+static const struct pd692x0_status_msg pd692x0_status_msg_list[] = {
+	{.id = 0x06, .msg = "Port is off: Main supply voltage is high."},
+	{.id = 0x07, .msg = "Port is off: Main supply voltage is low."},
+	{.id = 0x08, .msg = "Port is off: Disable all ports pin is active."},
+	{.id = 0x0C, .msg = "Port is off: Non-existing port number."},
+	{.id = 0x11, .msg = "Port is yet undefined."},
+	{.id = 0x12, .msg = "Port is off: Internal hardware fault."},
+	{.id = 0x1A, .msg = "Port is off: User setting."},
+	{.id = 0x1B, .msg = "Port is off: Detection is in process."},
+	{.id = 0x1C, .msg = "Port is off: Non-802.3AF/AT powered device."},
+	{.id = 0x1E, .msg = "Port is off: Underload state."},
+	{.id = 0x1F, .msg = "Port is off: Overload state."},
+	{.id = 0x20, .msg = "Port is off: Power budget exceeded."},
+	{.id = 0x21, .msg = "Port is off: Internal hardware routing error."},
+	{.id = 0x22, .msg = "Port is off: Configuration change."},
+	{.id = 0x24, .msg = "Port is off: Voltage injection into the port."},
+	{.id = 0x25, .msg = "Port is off: Improper Capacitor Detection"},
+	{.id = 0x26, .msg = "Port is off: Discharged load."},
+	{.id = 0x34, .msg = "Port is off: Short condition."},
+	{.id = 0x35, .msg = "Port is off: Over temperature at the port."},
+	{.id = 0x36, .msg = "Port is off: Device is too hot."},
+	{.id = 0x37, .msg = "Unknown device port status."},
+	{.id = 0x3C, .msg = "Power Management-Static."},
+	{.id = 0x3D, .msg = "Power Management-Static\u2014OVL."},
+	{.id = 0x41, .msg = "Power denied: Hardware power limit."},
+	{.id = 0x43, .msg = "Port is off: Class error."},
+	{.id = 0x44, .msg = "Port turn off during Host crash."},
+	{.id = 0x45, .msg = "Delivered power port was forced to be shut down at host crash."},
+	{.id = 0x46, .msg = "An enabled port was forced to be shut down at Host crash."},
+	{.id = 0x47, .msg = "Force Power Crash Error."},
+	{.id = 0x48, .msg = "Port is off: Recovery UDL."},
+	{.id = 0x49, .msg = "Port is off: Recovery PG Event."},
+	{.id = 0x4A, .msg = "Port is off: Recovery OVL."},
+	{.id = 0x4B, .msg = "Port is off: Recovery SC."},
+	{.id = 0x4C, .msg = "Port is off: Recovery Voltage injection."},
+	{.id = 0x80, .msg = "2P Port delivering non-IEEE."},
+	{.id = 0x81, .msg = "2P Port delivering IEEE."},
+	{.id = 0x82, .msg = "4P Port that deliver only 2 Pair non-IEEE."},
+	{.id = 0x83, .msg = "4P Port delivering 2P non-IEEE."},
+	{.id = 0x84, .msg = "4P Port delivering 4P non-IEEE."},
+	{.id = 0x85, .msg = "4P Port delivering 2P IEEE SSPD."},
+	{.id = 0x86, .msg = "4P Port delivering 4P IEEE SSPD."},
+	{.id = 0x87, .msg = "4P Port delivering 2P IEEE DSPD in the first phase."},
+	{.id = 0x88, .msg = "4P Port delivering 2P IEEE DSPD."},
+	{.id = 0x89, .msg = "4P Port delivering 4P IEEE DSPD."},
+	{.id = 0x90, .msg = "Force Power BT 2P."},
+	{.id = 0x91, .msg = "Force Power BT 4P."},
+	{.id = 0xA0, .msg = "Force Power BT error."},
+	{.id = 0xA7, .msg = "Connection Check error."},
+	{.id = 0xA8, .msg = "Open Port is not connected."},
+	{ /* sentinel */ }
+};
+
+static const char *pd692x0_get_status_msg(int id)
+{
+	const struct pd692x0_status_msg *msg_list;
+
+	msg_list = pd692x0_status_msg_list;
+	while (msg_list->id) {
+		if (msg_list->id == id)
+			return msg_list->msg;
+
+		msg_list++;
+	}
+
+	return NULL;
+}
+
 static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
 				      unsigned long id,
 				      struct netlink_ext_ack *extack,
@@ -442,6 +522,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 +552,21 @@  static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
 
 	priv->admin_state[id] = status->c33_admin_state;
 
+	status->c33_pw_status_msg = pd692x0_get_status_msg(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;
 }