Skip to content

Commit 18ff0bc

Browse files
oleremkuba-moo
authored andcommitted
ethtool: add interface to interact with Ethernet Power Equipment
Add interface to support Power Sourcing Equipment. At current step it provides generic way to address all variants of PSE devices as defined in IEEE 802.3-2018 but support only objects specified for IEEE 802.3-2018 104.4 PoDL Power Sourcing Equipment (PSE). Currently supported and mandatory objects are: IEEE 802.3-2018 30.15.1.1.3 aPoDLPSEPowerDetectionStatus IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState IEEE 802.3-2018 30.15.1.2.1 acPoDLPSEAdminControl This is minimal interface needed to control PSE on each separate ethernet port but it provides not all mandatory objects specified in IEEE 802.3-2018. Since "PoDL PSE" and "PSE" have similar names, but some different values I decide to not merge them and keep separate naming schema. This should allow as to be as close to IEEE 802.3 spec as possible and avoid name conflicts in the future. This implementation is connected to PHYs instead of MACs because PSE auto classification can potentially interfere with PHY auto negotiation. So, may be some extra PHY related initialization will be needed. With WIP version of ethtools interaction with PSE capable link looks as following: $ ip l ... 5: t1l1@eth0: <BROADCAST,MULTICAST> .. ... $ ethtool --show-pse t1l1 PSE attributs for t1l1: PoDL PSE Admin State: disabled PoDL PSE Power Detection Status: disabled $ ethtool --set-pse t1l1 podl-pse-admin-control enable $ ethtool --show-pse t1l1 PSE attributs for t1l1: PoDL PSE Admin State: enabled PoDL PSE Power Detection Status: delivering power Signed-off-by: kernel test robot <[email protected]> Signed-off-by: Oleksij Rempel <[email protected]> Reviewed-by: Bagas Sanjaya <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5e82147 commit 18ff0bc

File tree

10 files changed

+449
-1
lines changed

10 files changed

+449
-1
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ Userspace to kernel:
220220
``ETHTOOL_MSG_PHC_VCLOCKS_GET`` get PHC virtual clocks info
221221
``ETHTOOL_MSG_MODULE_SET`` set transceiver module parameters
222222
``ETHTOOL_MSG_MODULE_GET`` get transceiver module parameters
223+
``ETHTOOL_MSG_PSE_SET`` set PSE parameters
224+
``ETHTOOL_MSG_PSE_GET`` get PSE parameters
223225
===================================== =================================
224226

225227
Kernel to userspace:
@@ -260,6 +262,7 @@ Kernel to userspace:
260262
``ETHTOOL_MSG_STATS_GET_REPLY`` standard statistics
261263
``ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY`` PHC virtual clocks info
262264
``ETHTOOL_MSG_MODULE_GET_REPLY`` transceiver module parameters
265+
``ETHTOOL_MSG_PSE_GET_REPLY`` PSE parameters
263266
======================================== =================================
264267

265268
``GET`` requests are sent by userspace applications to retrieve device
@@ -1627,6 +1630,62 @@ For SFF-8636 modules, low power mode is forced by the host according to table
16271630
For CMIS modules, low power mode is forced by the host according to table 6-12
16281631
in revision 5.0 of the specification.
16291632

1633+
PSE_GET
1634+
=======
1635+
1636+
Gets PSE attributes.
1637+
1638+
Request contents:
1639+
1640+
===================================== ====== ==========================
1641+
``ETHTOOL_A_PSE_HEADER`` nested request header
1642+
===================================== ====== ==========================
1643+
1644+
Kernel response contents:
1645+
1646+
====================================== ====== =============================
1647+
``ETHTOOL_A_PSE_HEADER`` nested reply header
1648+
``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` u32 Operational state of the PoDL
1649+
PSE functions
1650+
``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` u32 power detection status of the
1651+
PoDL PSE.
1652+
====================================== ====== =============================
1653+
1654+
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
1655+
the operational state of the PoDL PSE functions. The operational state of the
1656+
PSE function can be changed using the ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL``
1657+
action. This option is corresponding to ``IEEE 802.3-2018`` 30.15.1.1.2
1658+
aPoDLPSEAdminState. Possible values are:
1659+
1660+
.. kernel-doc:: include/uapi/linux/ethtool.h
1661+
:identifiers: ethtool_podl_pse_admin_state
1662+
1663+
When set, the optional ``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` attribute identifies
1664+
the power detection status of the PoDL PSE. The status depend on internal PSE
1665+
state machine and automatic PD classification support. This option is
1666+
corresponding to ``IEEE 802.3-2018`` 30.15.1.1.3 aPoDLPSEPowerDetectionStatus.
1667+
Possible values are:
1668+
1669+
.. kernel-doc:: include/uapi/linux/ethtool.h
1670+
:identifiers: ethtool_podl_pse_pw_d_status
1671+
1672+
PSE_SET
1673+
=======
1674+
1675+
Sets PSE parameters.
1676+
1677+
Request contents:
1678+
1679+
====================================== ====== =============================
1680+
``ETHTOOL_A_PSE_HEADER`` nested request header
1681+
``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` u32 Control PoDL PSE Admin state
1682+
====================================== ====== =============================
1683+
1684+
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` attribute is used
1685+
to control PoDL PSE Admin functions. This option is implementing
1686+
``IEEE 802.3-2018`` 30.15.1.2.1 acPoDLPSEAdminControl. See
1687+
``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` for supported values.
1688+
16301689
Request translation
16311690
===================
16321691

drivers/net/pse-pd/pse_core.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,61 @@ of_pse_control_get(struct device_node *node)
254254
return psec;
255255
}
256256
EXPORT_SYMBOL_GPL(of_pse_control_get);
257+
258+
/**
259+
* pse_ethtool_get_status - get status of PSE control
260+
* @psec: PSE control pointer
261+
* @extack: extack for reporting useful error messages
262+
* @status: struct to store PSE status
263+
*/
264+
int pse_ethtool_get_status(struct pse_control *psec,
265+
struct netlink_ext_ack *extack,
266+
struct pse_control_status *status)
267+
{
268+
const struct pse_controller_ops *ops;
269+
int err;
270+
271+
ops = psec->pcdev->ops;
272+
273+
if (!ops->ethtool_get_status) {
274+
NL_SET_ERR_MSG(extack,
275+
"PSE driver does not support status report");
276+
return -EOPNOTSUPP;
277+
}
278+
279+
mutex_lock(&psec->pcdev->lock);
280+
err = ops->ethtool_get_status(psec->pcdev, psec->id, extack, status);
281+
mutex_unlock(&psec->pcdev->lock);
282+
283+
return err;
284+
}
285+
EXPORT_SYMBOL_GPL(pse_ethtool_get_status);
286+
287+
/**
288+
* pse_ethtool_set_config - set PSE control configuration
289+
* @psec: PSE control pointer
290+
* @extack: extack for reporting useful error messages
291+
* @config: Configuration of the test to run
292+
*/
293+
int pse_ethtool_set_config(struct pse_control *psec,
294+
struct netlink_ext_ack *extack,
295+
const struct pse_control_config *config)
296+
{
297+
const struct pse_controller_ops *ops;
298+
int err;
299+
300+
ops = psec->pcdev->ops;
301+
302+
if (!ops->ethtool_set_config) {
303+
NL_SET_ERR_MSG(extack,
304+
"PSE driver does not configuration");
305+
return -EOPNOTSUPP;
306+
}
307+
308+
mutex_lock(&psec->pcdev->lock);
309+
err = ops->ethtool_set_config(psec->pcdev, psec->id, extack, config);
310+
mutex_unlock(&psec->pcdev->lock);
311+
312+
return err;
313+
}
314+
EXPORT_SYMBOL_GPL(pse_ethtool_set_config);

include/linux/pse-pd/pse.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,47 @@
99
#include <linux/list.h>
1010
#include <uapi/linux/ethtool.h>
1111

12+
struct phy_device;
13+
struct pse_controller_dev;
14+
15+
/**
16+
* struct pse_control_config - PSE control/channel configuration.
17+
*
18+
* @admin_cotrol: set PoDL PSE admin control as described in
19+
* IEEE 802.3-2018 30.15.1.2.1 acPoDLPSEAdminControl
20+
*/
21+
struct pse_control_config {
22+
enum ethtool_podl_pse_admin_state admin_cotrol;
23+
};
24+
25+
/**
26+
* struct pse_control_status - PSE control/channel status.
27+
*
28+
* @podl_admin_state: operational state of the PoDL PSE
29+
* functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
30+
* @podl_pw_status: power detection status of the PoDL PSE.
31+
* IEEE 802.3-2018 30.15.1.1.3 aPoDLPSEPowerDetectionStatus:
32+
*/
33+
struct pse_control_status {
34+
enum ethtool_podl_pse_admin_state podl_admin_state;
35+
enum ethtool_podl_pse_pw_d_status podl_pw_status;
36+
};
37+
38+
/**
39+
* struct pse_controller_ops - PSE controller driver callbacks
40+
*
41+
* @ethtool_get_status: get PSE control status for ethtool interface
42+
* @ethtool_set_config: set PSE control configuration over ethtool interface
43+
*/
44+
struct pse_controller_ops {
45+
int (*ethtool_get_status)(struct pse_controller_dev *pcdev,
46+
unsigned long id, struct netlink_ext_ack *extack,
47+
struct pse_control_status *status);
48+
int (*ethtool_set_config)(struct pse_controller_dev *pcdev,
49+
unsigned long id, struct netlink_ext_ack *extack,
50+
const struct pse_control_config *config);
51+
};
52+
1253
struct module;
1354
struct device_node;
1455
struct of_phandle_args;
@@ -51,6 +92,13 @@ int devm_pse_controller_register(struct device *dev,
5192
struct pse_control *of_pse_control_get(struct device_node *node);
5293
void pse_control_put(struct pse_control *psec);
5394

95+
int pse_ethtool_get_status(struct pse_control *psec,
96+
struct netlink_ext_ack *extack,
97+
struct pse_control_status *status);
98+
int pse_ethtool_set_config(struct pse_control *psec,
99+
struct netlink_ext_ack *extack,
100+
const struct pse_control_config *config);
101+
54102
#else
55103

56104
static inline struct pse_control *of_pse_control_get(struct device_node *node)
@@ -62,6 +110,20 @@ static inline void pse_control_put(struct pse_control *psec)
62110
{
63111
}
64112

113+
int pse_ethtool_get_status(struct pse_control *psec,
114+
struct netlink_ext_ack *extack,
115+
struct pse_control_status *status)
116+
{
117+
return -ENOTSUPP;
118+
}
119+
120+
int pse_ethtool_set_config(struct pse_control *psec,
121+
struct netlink_ext_ack *extack,
122+
const struct pse_control_config *config)
123+
{
124+
return -ENOTSUPP;
125+
}
126+
65127
#endif
66128

67129
#endif

include/uapi/linux/ethtool.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,51 @@ enum ethtool_module_power_mode {
736736
ETHTOOL_MODULE_POWER_MODE_HIGH,
737737
};
738738

739+
/**
740+
* enum ethtool_podl_pse_admin_state - operational state of the PoDL PSE
741+
* functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
742+
* @ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN: state of PoDL PSE functions are
743+
* unknown
744+
* @ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED: PoDL PSE functions are disabled
745+
* @ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED: PoDL PSE functions are enabled
746+
*/
747+
enum ethtool_podl_pse_admin_state {
748+
ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN = 1,
749+
ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED,
750+
ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED,
751+
};
752+
753+
/**
754+
* enum ethtool_podl_pse_pw_d_status - power detection status of the PoDL PSE.
755+
* IEEE 802.3-2018 30.15.1.1.3 aPoDLPSEPowerDetectionStatus:
756+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN: PoDL PSE
757+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED: "The enumeration “disabled” is
758+
* asserted true when the PoDL PSE state diagram variable mr_pse_enable is
759+
* false"
760+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING: "The enumeration “searching” is
761+
* asserted true when either of the PSE state diagram variables
762+
* pi_detecting or pi_classifying is true."
763+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING: "The enumeration “deliveringPower”
764+
* is asserted true when the PoDL PSE state diagram variable pi_powered is
765+
* true."
766+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP: "The enumeration “sleep” is asserted
767+
* true when the PoDL PSE state diagram variable pi_sleeping is true."
768+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE: "The enumeration “idle” is asserted true
769+
* when the logical combination of the PoDL PSE state diagram variables
770+
* pi_prebiased*!pi_sleeping is true."
771+
* @ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR: "The enumeration “error” is asserted
772+
* true when the PoDL PSE state diagram variable overload_held is true."
773+
*/
774+
enum ethtool_podl_pse_pw_d_status {
775+
ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN = 1,
776+
ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED,
777+
ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING,
778+
ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING,
779+
ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP,
780+
ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE,
781+
ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR,
782+
};
783+
739784
/**
740785
* struct ethtool_gstrings - string set for data tagging
741786
* @cmd: Command number = %ETHTOOL_GSTRINGS

include/uapi/linux/ethtool_netlink.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ enum {
4949
ETHTOOL_MSG_PHC_VCLOCKS_GET,
5050
ETHTOOL_MSG_MODULE_GET,
5151
ETHTOOL_MSG_MODULE_SET,
52+
ETHTOOL_MSG_PSE_GET,
53+
ETHTOOL_MSG_PSE_SET,
5254

5355
/* add new constants above here */
5456
__ETHTOOL_MSG_USER_CNT,
@@ -94,6 +96,7 @@ enum {
9496
ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY,
9597
ETHTOOL_MSG_MODULE_GET_REPLY,
9698
ETHTOOL_MSG_MODULE_NTF,
99+
ETHTOOL_MSG_PSE_GET_REPLY,
97100

98101
/* add new constants above here */
99102
__ETHTOOL_MSG_KERNEL_CNT,
@@ -863,6 +866,19 @@ enum {
863866
ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1)
864867
};
865868

869+
/* Power Sourcing Equipment */
870+
enum {
871+
ETHTOOL_A_PSE_UNSPEC,
872+
ETHTOOL_A_PSE_HEADER, /* nest - _A_HEADER_* */
873+
ETHTOOL_A_PODL_PSE_ADMIN_STATE, /* u32 */
874+
ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, /* u32 */
875+
ETHTOOL_A_PODL_PSE_PW_D_STATUS, /* u32 */
876+
877+
/* add new constants above here */
878+
__ETHTOOL_A_PSE_CNT,
879+
ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1)
880+
};
881+
866882
/* generic netlink info */
867883
#define ETHTOOL_GENL_NAME "ethtool"
868884
#define ETHTOOL_GENL_VERSION 1

net/ethtool/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o
77
ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
88
linkstate.o debug.o wol.o features.o privflags.o rings.o \
99
channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
10-
tunnels.o fec.o eeprom.o stats.o phc_vclocks.o module.o
10+
tunnels.o fec.o eeprom.o stats.o phc_vclocks.o module.o \
11+
pse-pd.o

net/ethtool/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max);
4646
int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
4747

4848
extern const struct ethtool_phy_ops *ethtool_phy_ops;
49+
extern const struct ethtool_pse_ops *ethtool_pse_ops;
4950

5051
int ethtool_get_module_info_call(struct net_device *dev,
5152
struct ethtool_modinfo *modinfo);

net/ethtool/netlink.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = {
286286
[ETHTOOL_MSG_STATS_GET] = &ethnl_stats_request_ops,
287287
[ETHTOOL_MSG_PHC_VCLOCKS_GET] = &ethnl_phc_vclocks_request_ops,
288288
[ETHTOOL_MSG_MODULE_GET] = &ethnl_module_request_ops,
289+
[ETHTOOL_MSG_PSE_GET] = &ethnl_pse_request_ops,
289290
};
290291

291292
static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -1023,6 +1024,22 @@ static const struct genl_ops ethtool_genl_ops[] = {
10231024
.policy = ethnl_module_set_policy,
10241025
.maxattr = ARRAY_SIZE(ethnl_module_set_policy) - 1,
10251026
},
1027+
{
1028+
.cmd = ETHTOOL_MSG_PSE_GET,
1029+
.doit = ethnl_default_doit,
1030+
.start = ethnl_default_start,
1031+
.dumpit = ethnl_default_dumpit,
1032+
.done = ethnl_default_done,
1033+
.policy = ethnl_pse_get_policy,
1034+
.maxattr = ARRAY_SIZE(ethnl_pse_get_policy) - 1,
1035+
},
1036+
{
1037+
.cmd = ETHTOOL_MSG_PSE_SET,
1038+
.flags = GENL_UNS_ADMIN_PERM,
1039+
.doit = ethnl_set_pse,
1040+
.policy = ethnl_pse_set_policy,
1041+
.maxattr = ARRAY_SIZE(ethnl_pse_set_policy) - 1,
1042+
},
10261043
};
10271044

10281045
static const struct genl_multicast_group ethtool_nl_mcgrps[] = {

net/ethtool/netlink.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ extern const struct ethnl_request_ops ethnl_module_eeprom_request_ops;
345345
extern const struct ethnl_request_ops ethnl_stats_request_ops;
346346
extern const struct ethnl_request_ops ethnl_phc_vclocks_request_ops;
347347
extern const struct ethnl_request_ops ethnl_module_request_ops;
348+
extern const struct ethnl_request_ops ethnl_pse_request_ops;
348349

349350
extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
350351
extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
@@ -383,6 +384,8 @@ extern const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1
383384
extern const struct nla_policy ethnl_phc_vclocks_get_policy[ETHTOOL_A_PHC_VCLOCKS_HEADER + 1];
384385
extern const struct nla_policy ethnl_module_get_policy[ETHTOOL_A_MODULE_HEADER + 1];
385386
extern const struct nla_policy ethnl_module_set_policy[ETHTOOL_A_MODULE_POWER_MODE_POLICY + 1];
387+
extern const struct nla_policy ethnl_pse_get_policy[ETHTOOL_A_PSE_HEADER + 1];
388+
extern const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1];
386389

387390
int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
388391
int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);
@@ -402,6 +405,7 @@ int ethnl_tunnel_info_start(struct netlink_callback *cb);
402405
int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
403406
int ethnl_set_fec(struct sk_buff *skb, struct genl_info *info);
404407
int ethnl_set_module(struct sk_buff *skb, struct genl_info *info);
408+
int ethnl_set_pse(struct sk_buff *skb, struct genl_info *info);
405409

406410
extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
407411
extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];

0 commit comments

Comments
 (0)