diff mbox series

[net-next,v2,2/8] net: ethtool: pse-pd: Expand C33 PSE status with class, power and extended state

Message ID 20240607-feature_poe_power_cap-v2-2-c03c2deb83ab@bootlin.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: pse-pd: Add new PSE c33 features | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; GEN HAS DIFF 2 files changed, 95 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 success Errors and warnings before: 2509 this patch: 2509
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 2 maintainers not CCed: andrew@lunn.ch ahmed.zaki@intel.com
netdev/build_clang success Errors and warnings before: 933 this patch: 933
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 success Errors and warnings before: 2680 this patch: 2680
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>'
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 5 this patch: 5
netdev/source_inline success Was 0 now: 0

Commit Message

Kory Maincent June 7, 2024, 7:30 a.m. UTC
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.

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.
---
 include/linux/ethtool.h              | 11 ++++++++++
 include/linux/pse-pd/pse.h           |  8 +++++++
 include/uapi/linux/ethtool.h         | 41 ++++++++++++++++++++++++++++++++++++
 include/uapi/linux/ethtool_netlink.h |  4 ++++
 net/ethtool/pse-pd.c                 | 29 ++++++++++++++++++++++++-
 5 files changed, 92 insertions(+), 1 deletion(-)

Comments

Oleksij Rempel June 10, 2024, 5:16 a.m. UTC | #1
Hi Köry,

Thank you for your work.

On Fri, Jun 07, 2024 at 09:30:19AM +0200, Kory Maincent wrote:
> From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>

...

>  /**
> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> index 8733a3117902..ef65ad4612d2 100644
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
> @@ -752,6 +752,47 @@ enum ethtool_module_power_mode {
>  	ETHTOOL_MODULE_POWER_MODE_HIGH,
>  };
>  
> +/* C33 PSE extended state */
> +enum ethtool_c33_pse_ext_state {
> +	ETHTOOL_C33_PSE_EXT_STATE_UNKNOWN = 1,

I assume, In case the state is unknown, better to set it to 0 and not
report it to the user space in the first place. Do we really need it?

> +	ETHTOOL_C33_PSE_EXT_STATE_DETECTION,
> +	ETHTOOL_C33_PSE_EXT_STATE_CLASSIFICATION_FAILURE,
> +	ETHTOOL_C33_PSE_EXT_STATE_HARDWARE_ISSUE,
> +	ETHTOOL_C33_PSE_EXT_STATE_VOLTAGE_ISSUE,
> +	ETHTOOL_C33_PSE_EXT_STATE_CURRENT_ISSUE,
> +	ETHTOOL_C33_PSE_EXT_STATE_POWER_BUDGET_EXCEEDED,

What is the difference between POWER_BUDGET_EXCEEDED and
STATE_CURRENT_ISSUE->CRT_OVERLOAD? If there is some difference, it
should be commented.

Please provide comments describing how all of this states and substates
should be used.

> +	ETHTOOL_C33_PSE_EXT_STATE_CONFIG,
> +	ETHTOOL_C33_PSE_EXT_STATE_TEMP_ISSUE,
> +};

...

>  /**
>   * 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 b49b804b9495..ccbe8294dfd5 100644
> --- a/include/uapi/linux/ethtool_netlink.h
> +++ b/include/uapi/linux/ethtool_netlink.h
> @@ -915,6 +915,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,		/* u8 */
> +	ETHTOOL_A_C33_PSE_EXT_SUBSTATE,		/* u8 */

Please, increase the size to u32 for state and substate.

>  	/* 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..3d74cfe7765b 100644
> --- a/net/ethtool/pse-pd.c
> +++ b/net/ethtool/pse-pd.c
> @@ -86,7 +86,14 @@ 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)
> +		len += nla_total_size(sizeof(u8)); /* _C33_PSE_EXT_STATE */
> +	if (st->c33_ext_state_info.__c33_pse_ext_substate)
> +		len += nla_total_size(sizeof(u8)); /* _C33_PSE_EXT_SUBSTATE */

Substate can be properly decoded only if state is not zero.

>  	return len;
>  }
>  
> @@ -117,6 +124,26 @@ 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 &&
> +	    nla_put_u8(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_u8(skb, ETHTOOL_A_C33_PSE_EXT_SUBSTATE,
> +		       st->c33_ext_state_info.__c33_pse_ext_substate))
> +		return -EMSGSIZE;

ditto.

Please update Documentation/networking/ethtool-netlink.rst
Kory Maincent June 10, 2024, 9:25 a.m. UTC | #2
Hello Oleksij,

On Mon, 10 Jun 2024 07:16:09 +0200
Oleksij Rempel <o.rempel@pengutronix.de> wrote:

> Hi Köry,
> 
> Thank you for your work.
> 
> On Fri, Jun 07, 2024 at 09:30:19AM +0200, Kory Maincent wrote:
> > From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>  
> 
> ...
> 
> >  /**
> > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> > index 8733a3117902..ef65ad4612d2 100644
> > --- a/include/uapi/linux/ethtool.h
> > +++ b/include/uapi/linux/ethtool.h
> > @@ -752,6 +752,47 @@ enum ethtool_module_power_mode {
> >  	ETHTOOL_MODULE_POWER_MODE_HIGH,
> >  };
> >  
> > +/* C33 PSE extended state */
> > +enum ethtool_c33_pse_ext_state {
> > +	ETHTOOL_C33_PSE_EXT_STATE_UNKNOWN = 1,  
> 
> I assume, In case the state is unknown, better to set it to 0 and not
> report it to the user space in the first place. Do we really need it?

The pd692x0 report this for the unknown state: "Port is not mapped to physical
port, port is in unknown state, or PD692x0 fails to communicate with PD69208
device allocated for this port."
Also it has a status for open port (not connected) state.
(ETHTOOL_C33_PSE_EXT_SUBSTATE_V_OPEN)
Do you prefer to use the same error for both state?
 
> > +	ETHTOOL_C33_PSE_EXT_STATE_DETECTION,
> > +	ETHTOOL_C33_PSE_EXT_STATE_CLASSIFICATION_FAILURE,
> > +	ETHTOOL_C33_PSE_EXT_STATE_HARDWARE_ISSUE,
> > +	ETHTOOL_C33_PSE_EXT_STATE_VOLTAGE_ISSUE,
> > +	ETHTOOL_C33_PSE_EXT_STATE_CURRENT_ISSUE,
> > +	ETHTOOL_C33_PSE_EXT_STATE_POWER_BUDGET_EXCEEDED,  
> 
> What is the difference between POWER_BUDGET_EXCEEDED and
> STATE_CURRENT_ISSUE->CRT_OVERLOAD? If there is some difference, it
> should be commented.

Current overload seems to be describing the "Overload current detection range
(Icut)" As described in the IEEE standard.
Not sure If budget exceeded should use the same error.

> Please provide comments describing how all of this states and substates
> should be used.

The enum errors I wrote is a bit subjective and are taken from the PD692x0
port status list. Go ahead to purpose any change, I have tried to make
categories that make sense but I might have made wrong choice.

> >  /**
> >   * 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 b49b804b9495..ccbe8294dfd5
> > 100644 --- a/include/uapi/linux/ethtool_netlink.h
> > +++ b/include/uapi/linux/ethtool_netlink.h
> > @@ -915,6 +915,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,		/* u8 */
> > +	ETHTOOL_A_C33_PSE_EXT_SUBSTATE,		/* u8 */  
> 
> Please, increase the size to u32 for state and substate.

Ack,

> >  	/* 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..3d74cfe7765b 100644
> > --- a/net/ethtool/pse-pd.c
> > +++ b/net/ethtool/pse-pd.c
> > @@ -86,7 +86,14 @@ 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)
> > +		len += nla_total_size(sizeof(u8)); /* _C33_PSE_EXT_STATE */
> > +	if (st->c33_ext_state_info.__c33_pse_ext_substate)
> > +		len += nla_total_size(sizeof(u8)); /*
> > _C33_PSE_EXT_SUBSTATE */  
> 
> Substate can be properly decoded only if state is not zero.

Indeed, thanks for spotting that mistake.
 
> Please update Documentation/networking/ethtool-netlink.rst

Oh right, indeed. Forgot to add the netlink docs. 

Regards,
Oleksij Rempel June 11, 2024, 8:05 a.m. UTC | #3
On Mon, Jun 10, 2024 at 11:25:59AM +0200, Kory Maincent wrote:
> Hello Oleksij,
> 
> On Mon, 10 Jun 2024 07:16:09 +0200
> Oleksij Rempel <o.rempel@pengutronix.de> wrote:
> 
> > Hi Köry,
> > 
> > Thank you for your work.
> > 
> > On Fri, Jun 07, 2024 at 09:30:19AM +0200, Kory Maincent wrote:
> > > From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>  
> > 
> > ...
> > 
> > >  /**
> > > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> > > index 8733a3117902..ef65ad4612d2 100644
> > > --- a/include/uapi/linux/ethtool.h
> > > +++ b/include/uapi/linux/ethtool.h
> > > @@ -752,6 +752,47 @@ enum ethtool_module_power_mode {
> > >  	ETHTOOL_MODULE_POWER_MODE_HIGH,
> > >  };
> > >  
> > > +/* C33 PSE extended state */
> > > +enum ethtool_c33_pse_ext_state {
> > > +	ETHTOOL_C33_PSE_EXT_STATE_UNKNOWN = 1,  
> > 
> > I assume, In case the state is unknown, better to set it to 0 and not
> > report it to the user space in the first place. Do we really need it?
> 
> The pd692x0 report this for the unknown state: "Port is not mapped to physical
> port, port is in unknown state, or PD692x0 fails to communicate with PD69208
> device allocated for this port."
> Also it has a status for open port (not connected) state.
> (ETHTOOL_C33_PSE_EXT_SUBSTATE_V_OPEN)
> Do you prefer to use the same error for both state?
>  
> > > +	ETHTOOL_C33_PSE_EXT_STATE_DETECTION,
> > > +	ETHTOOL_C33_PSE_EXT_STATE_CLASSIFICATION_FAILURE,
> > > +	ETHTOOL_C33_PSE_EXT_STATE_HARDWARE_ISSUE,
> > > +	ETHTOOL_C33_PSE_EXT_STATE_VOLTAGE_ISSUE,
> > > +	ETHTOOL_C33_PSE_EXT_STATE_CURRENT_ISSUE,
> > > +	ETHTOOL_C33_PSE_EXT_STATE_POWER_BUDGET_EXCEEDED,  
> > 
> > What is the difference between POWER_BUDGET_EXCEEDED and
> > STATE_CURRENT_ISSUE->CRT_OVERLOAD? If there is some difference, it
> > should be commented.
> 
> Current overload seems to be describing the "Overload current detection range
> (Icut)" As described in the IEEE standard.
> Not sure If budget exceeded should use the same error.
> 
> > Please provide comments describing how all of this states and substates
> > should be used.
> 
> The enum errors I wrote is a bit subjective and are taken from the PD692x0
> port status list. Go ahead to purpose any change, I have tried to make
> categories that make sense but I might have made wrong choice.

Here is my proposal aligned with IEEE 802.3-2022 33.2.4.4:

/**                                                                                  
 * 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_PSE_ENABLE: Group of mr_pse_enable 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         
 * @ETHTOOL_C33_PSE_EXT_STATE_TINRUSH_TIMER: Group of tinrush_timer states            
 */ 
enum ethtool_c33_pse_ext_state {
    ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
    ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
    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,
    ETHTOOL_C33_PSE_EXT_STATE_TINRUSH_TIMER,
};

/**                                                                                  
 * 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 (PD692x0 0x0C)                  
 *      "Port is off: Non-existing port number. Fewer ports are available than the maximum number of ports that the Controller can support. Unavailable ports are considered 'off'. Currently not used."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT: Undefined port (PD692x0 0x11)                                
 *      "Port is yet undefined. Port is not mapped to physical port or port is in unknown state or PD69200 failed to communicate with PD69208 device allocated for this port."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT: Internal hardware fault (PD692x0 0x12)                   
 *      "Port is off: Internal hardware fault. Port does not respond. Hardware fault, system initialization or PD69200 lost communication with PD69208 device allocated for this port. (Part of refresh function)."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT_2: Internal hardware fault (PD692x0 0x21)                 
 *      "Port is off: Internal hardware fault. Hardware problems preventing port operation. Currently not used. Used for 4P mapping with PD39208 device."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON: Communication error after force on (PD692x0 0x33) 
 *      "Port is off: Communication error with PoE devices after Force On. This error appears only after port is forced on."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS: Unknown port status (PD692x0 0x37)                     
 *      "Port is off: Unknown device port status. The device returns an unknown port status for the software. Currently not used."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF: Host crash turn off (PD692x0 0x44)                     
 *      "Port is off: Turn off during host crash. Port is off - After host crash the port is off and waits for host command to proceed with new detection cycles. The port was delivering power before host crash but was configured to be forced shut when host crashes."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN: Host crash force shutdown (PD692x0 0x46)         
 *      "Port is off: An enabled port was forced to be shut down at host crash. Port is off - after host crash the port is off and waits for host command to proceed with new detection cycles. The port was enabled and not delivering power before host crash and was configured to be forced shut when host crashes."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_RECOVERY_UDL: Recovery UDL (PD692x0 0x48)                                    
 *      "Port is off: Recovery UDL. During crash a recovery port delivering power was disconnected due to UDL."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_RECOVERY_PG_EVENT: Recovery PG Event (PD692x0 0x49)                          
 *      "Port is off: Recovery PG Event. During crash a recovery port delivering power was disconnected due to PG event."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_RECOVERY_OVL: Recovery OVL (PD692x0 0x4A)                                    
 *      "Port is off: Recovery OVL. During crash a recovery port delivering power was disconnected due to OVL."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DVDT_FAIL_STARTUP: DVDT fail during startup (PD692x0 0x4D)                   
 *      "Port is off: DVDT fail during startup. DVDT algorithm that checks power up sequence failed to power up the port."

 **error_condition**  
  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.  
  Values:  
  FALSE: No fault indication.  
  TRUE: A fault indication exists.
 */ 
enum ethtool_c33_pse_ext_substate_error_condition {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT,
    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_INTERNAL_HW_FAULT_2,
    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_RECOVERY_UDL,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_RECOVERY_PG_EVENT,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_RECOVERY_OVL,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DVDT_FAIL_STARTUP,
};

/**                                                                                  
 * 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 (PD692x0 0x08)                           
 *      "Port is off: 'Disable all ports' pin is active. Hardware pin disables all ports."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PDU_FLAG_FORCE_ON: Disable PDU flag during force on (PD692x0 0x2F)      
 *      "Port is off: Disable PDU flag raised during Force On."

 **mr_pse_enable**  
  A control variable that selects PSE operation and test functions. This variable is provided by a
  management interface that may be mapped to the PSE Control register PSE Enable bits (11.1:0), as
  described below, or other equivalent functions.  
  Values:  
  disable: All PSE functions disabled (behavior is as if there was no PSE functionality).  
  enable: Normal PSE operation.  
  force_power: Test mode selected that causes the PSE to apply power to the PI when there are no detected error conditions.
 */ 
enum ethtool_c33_pse_ext_substate_mr_pse_enable {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PDU_FLAG_FORCE_ON,
};

/**                                                                                  
 * 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 (PD692x0 0x06)                     
 *      "Port is off: Main supply voltage is high. Mains voltage is higher than Max Voltage limit."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE_FORCED: Supply voltage higher than settings (PD692x0 0x2D)     
 *      "Port is off: Supply voltage higher than settings. These errors appear only after port is in Force On."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE: Main supply voltage is low (PD692x0 0x07)                       
 *      "Port is off: Main supply voltage is low. Mains voltage is lower than Min Voltage limit."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE_FORCED: Supply voltage lower than settings (PD692x0 0x2E)       
 *      "Port is off: Supply voltage lower than settings."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_RECOVERY_VOLTAGE_INJECTION: Recovery voltage injection (PD692x0 0x4C)       
 *      "Port is off: Recovery Voltage injection. Voltage was applied to the port from external source, during or before crash."

 **option_vport_lim**  
  This optional variable indicates if VPSE is out of the operating range during normal operating state.  
  Values:  
  FALSE: VPSE is within the VPort_PSE operating range as defined in Table 33–11.  
  TRUE: VPSE is outside of the VPort_PSE operating range as defined in Table 33–11.
 */ 
enum ethtool_c33_pse_ext_substate_option_vport_lim {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE_FORCED,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE_FORCED,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_RECOVERY_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 (PD692x0 0x1F)                                          
 *      "Port is off: Overload state. Overload state according to 802.3AF/AT (current is above Icut) OR (PM3 != 0 and (PD class report > user predefined power value))."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD_FORCED: Forced power error due to overload (PD692x0 0x31)              
 *      "Port is off: Forced power error due to Overload. Overload condition according to 802.3AF/AT during Force On."

 **ovld_detected**  
  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.  
  Values:  
  FALSE: The PSE has not detected an overload condition.  
  TRUE: The PSE has detected an overload condition.
 */ 
enum ethtool_c33_pse_ext_substate_ovld_detected {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD_FORCED,
};

/**                                                                                  
 * enum ethtool_c33_pse_ext_substate_pd_dll_power_type - pd_dll_power_type states    
 *      functions. IEEE 802.3-2022 33.2.4.4 Variables                                
 *                                                                                  
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_PD_DLL_POWER_TYPE_NON_802_3AF_AT_DEVICE: Non-802.3AF/AT powered device (PD692x0 0x1C)           
 *      "Port is off: Non-802.3AF/AT powered device. Non-standard PD connected."

 **pd_dll_power_type**  
  A control variable initially output by the PSE power control state diagram (Figure 33–27), which can be updated by LLDP (see Table 33–26), that indicates the type of PD as advertised through Data Link Layer classification.  
  Values:  
  1: PD is a Type 1 PD (default)  
  2: PD is a Type 2 PD
 */ 
enum ethtool_c33_pse_ext_substate_pd_dll_power_type {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_PD_DLL_POWER_TYPE_NON_802_3AF_AT_DEVICE,
};

/**                                                                                  
 * 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 (PD692x0 0x20)                     
 *      "Port is off: Power budget exceeded. Power Management function shuts down port, due to lack of power. Port is shut down or remains off."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PM_STATIC: Power Management-Static (PD692x0 0x3C)                         
 *      "Power Management-Static. Calculated power > power limit."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PM_STATIC_OVL: Power Management-Static-ovl (PD692x0 0x3D)                 
 *      "Power Management-Static-ovl. Port Power up was denied due to (PD class report power > user predefined power value). Note: Power denied counter will advance."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_ERROR_MANAGEMENT_STATIC: Force Power Error Management Static (PD692x0 0x3E)
 *      "Force Power Error Management Static. Calculated power > power limit during Force On."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_ERROR_MANAGEMENT_STATIC_OVL: Force Power Error Management Static-ovl (PD692x0 0x3F)
 *      "Force Power Error Management Static-ovl. PD class report > user predefined power value during Force On. Note: Power denied counter will advance."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_INSUFFICIENT_POWER_FORCE_ON: Port is not ON during Force On due to exceeded max power level or insufficient power (PD692x0 0x32)
 *      "Port is not ON during Force On due to exceeded max power level or insufficient power."

 **power_not_available**  
  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.  
  Values:  
  FALSE: PSE is capable to continue to source power to a PD.  
  TRUE: PSE is no longer capable of sourcing power to a PD.
 */ 
enum ethtool_c33_pse_ext_substate_power_not_available {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PM_STATIC,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PM_STATIC_OVL,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_ERROR_MANAGEMENT_STATIC,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_ERROR_MANAGEMENT_STATIC_OVL,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_INSUFFICIENT_POWER_FORCE_ON,
};

/**                                                                                  
 * 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_CIRCUIT_FORCED: Force Power Error Short Circuit (PD692x0 0x38)             
 *      "Force Power Error Short Circuit. Short condition during Force On."
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_RECOVERY_SC: Recovery short circuit (PD692x0 0x4B)                              
 *      "Recovery SC. During crash a recovery port delivering power was disconnected due to SC."

 **short_detected**  
  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).  
  Values:  
  FALSE: The PSE has not detected a short circuit condition.  
  TRUE: The PSE has detected qualified short circuit condition.
 */ 
enum ethtool_c33_pse_ext_substate_short_detected {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CIRCUIT_FORCED,
    ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_RECOVERY_SC,
};

/**                                                                                  
 * enum ethtool_c33_pse_ext_substate_tinrush_timer - tinrush_timer states             
 *      functions. IEEE 802.3-2022 33.2.4.5 Timers                                   
 *                                                                                  
 * @ETHTOOL_C33_PSE_EXT_SUBSTATE_TINRUSH_TIMER_FAIL_STARTUP: DVDT fail during startup (PD692x0 0x4D)                            
 *      "Port is off: DVDT fail during startup. DVDT algorithm that checks power up sequence failed to power up the port."

 **tinrush_timer**  
  A timer used to monitor the duration of the inrush event; see TInrush in Table 33–11.
 */ 
enum ethtool_c33_pse_ext_substate_tinrush_timer {
    ETHTOOL_C33_PSE_EXT_SUBSTATE_TINRUSH_TIMER_FAIL_STARTUP,
};
Kory Maincent June 11, 2024, 12:01 p.m. UTC | #4
On Tue, 11 Jun 2024 10:05:02 +0200
Oleksij Rempel <o.rempel@pengutronix.de> wrote:

> On Mon, Jun 10, 2024 at 11:25:59AM +0200, Kory Maincent wrote:
 
> > The enum errors I wrote is a bit subjective and are taken from the PD692x0
> > port status list. Go ahead to purpose any change, I have tried to make
> > categories that make sense but I might have made wrong choice.  
> 
> Here is my proposal aligned with IEEE 802.3-2022 33.2.4.4:

Hello Oleksij,

Wow! You fully rewrite the netlink UAPI.
Thanks, this is more standard complaint than my proposal!
I will remove the PD692x0 specific description and update my patch series
accordingly.

Regards,
Kory Maincent June 12, 2024, 9:08 a.m. UTC | #5
On Tue, 11 Jun 2024 10:05:02 +0200
Oleksij Rempel <o.rempel@pengutronix.de> wrote:

> On Mon, Jun 10, 2024 at 11:25:59AM +0200, Kory Maincent wrote:
> 
> Here is my proposal aligned with IEEE 802.3-2022 33.2.4.4:

FYI: It seems your are using an old user guide for the PD692x0 communication
protocol. The one I have is based on the last firmware version 3.55.
So don't be surprised if the next series version will have few differences with
your proposal.

Regards,
diff mbox series

Patch

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 6fd9107d3cc0..1a0c8d6a22a0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -1155,4 +1155,15 @@  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_voltage_issue voltage_issue;
+		enum ethtool_c33_pse_ext_substate_current_issue current_issue;
+		enum ethtool_c33_pse_ext_substate_config config;
+		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 8733a3117902..ef65ad4612d2 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -752,6 +752,47 @@  enum ethtool_module_power_mode {
 	ETHTOOL_MODULE_POWER_MODE_HIGH,
 };
 
+/* C33 PSE extended state */
+enum ethtool_c33_pse_ext_state {
+	ETHTOOL_C33_PSE_EXT_STATE_UNKNOWN = 1,
+	ETHTOOL_C33_PSE_EXT_STATE_DETECTION,
+	ETHTOOL_C33_PSE_EXT_STATE_CLASSIFICATION_FAILURE,
+	ETHTOOL_C33_PSE_EXT_STATE_HARDWARE_ISSUE,
+	ETHTOOL_C33_PSE_EXT_STATE_VOLTAGE_ISSUE,
+	ETHTOOL_C33_PSE_EXT_STATE_CURRENT_ISSUE,
+	ETHTOOL_C33_PSE_EXT_STATE_POWER_BUDGET_EXCEEDED,
+	ETHTOOL_C33_PSE_EXT_STATE_CONFIG,
+	ETHTOOL_C33_PSE_EXT_STATE_TEMP_ISSUE,
+};
+
+/* More information in addition to ETHTOOL_C33_PSE_EXT_STATE_DETECTION. */
+enum ethtool_c33_pse_ext_substate_detection {
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_DET_IN_PROGRESS = 1,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_DET_FAILURE,
+};
+
+/* More information in addition to ETHTOOL_C33_PSE_EXT_STATE_VOLTAGE_ISSUE. */
+enum ethtool_c33_pse_ext_substate_voltage_issue {
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_V_INJECTION = 1,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_V_SHORT_DETECTED,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_V_OVERVOLTAGE,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_V_UNDERVOLTAGE,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_V_OPEN,
+};
+
+/* More information in addition to ETHTOOL_C33_PSE_EXT_STATE_CURRENT_ISSUE. */
+enum ethtool_c33_pse_ext_substate_current_issue {
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_CRT_OVERLOAD = 1,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_CRT_UNDERLOAD,
+};
+
+/* More information in addition to ETHTOOL_C33_PSE_EXT_STATE_CONFIG.
+ */
+enum ethtool_c33_pse_ext_substate_config {
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_CFG_CHANGED = 1,
+	ETHTOOL_C33_PSE_EXT_SUBSTATE_CFG_UNDEFINED,
+};
+
 /**
  * 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 b49b804b9495..ccbe8294dfd5 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -915,6 +915,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,		/* u8 */
+	ETHTOOL_A_C33_PSE_EXT_SUBSTATE,		/* u8 */
 
 	/* 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..3d74cfe7765b 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -86,7 +86,14 @@  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)
+		len += nla_total_size(sizeof(u8)); /* _C33_PSE_EXT_STATE */
+	if (st->c33_ext_state_info.__c33_pse_ext_substate)
+		len += nla_total_size(sizeof(u8)); /* _C33_PSE_EXT_SUBSTATE */
 	return len;
 }
 
@@ -117,6 +124,26 @@  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 &&
+	    nla_put_u8(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_u8(skb, ETHTOOL_A_C33_PSE_EXT_SUBSTATE,
+		       st->c33_ext_state_info.__c33_pse_ext_substate))
+		return -EMSGSIZE;
+
 	return 0;
 }