1 // SPDX-License-Identifier: GPL-2.0-only
8 struct ethnl_req_info base
;
11 struct eee_reply_data
{
12 struct ethnl_reply_data base
;
13 struct ethtool_keee eee
;
16 #define EEE_REPDATA(__reply_base) \
17 container_of(__reply_base, struct eee_reply_data, base)
19 const struct nla_policy ethnl_eee_get_policy
[] = {
20 [ETHTOOL_A_EEE_HEADER
] =
21 NLA_POLICY_NESTED(ethnl_header_policy
),
24 static int eee_prepare_data(const struct ethnl_req_info
*req_base
,
25 struct ethnl_reply_data
*reply_base
,
26 const struct genl_info
*info
)
28 struct eee_reply_data
*data
= EEE_REPDATA(reply_base
);
29 struct net_device
*dev
= reply_base
->dev
;
30 struct ethtool_keee
*eee
= &data
->eee
;
33 if (!dev
->ethtool_ops
->get_eee
)
35 ret
= ethnl_ops_begin(dev
);
38 ret
= dev
->ethtool_ops
->get_eee(dev
, eee
);
39 ethnl_ops_complete(dev
);
44 static int eee_reply_size(const struct ethnl_req_info
*req_base
,
45 const struct ethnl_reply_data
*reply_base
)
47 bool compact
= req_base
->flags
& ETHTOOL_FLAG_COMPACT_BITSETS
;
48 const struct eee_reply_data
*data
= EEE_REPDATA(reply_base
);
49 const struct ethtool_keee
*eee
= &data
->eee
;
54 ret
= ethnl_bitset_size(eee
->advertised
, eee
->supported
,
55 __ETHTOOL_LINK_MODE_MASK_NBITS
,
56 link_mode_names
, compact
);
61 ret
= ethnl_bitset_size(eee
->lp_advertised
, NULL
,
62 __ETHTOOL_LINK_MODE_MASK_NBITS
,
63 link_mode_names
, compact
);
68 len
+= nla_total_size(sizeof(u8
)) + /* _EEE_ACTIVE */
69 nla_total_size(sizeof(u8
)) + /* _EEE_ENABLED */
70 nla_total_size(sizeof(u8
)) + /* _EEE_TX_LPI_ENABLED */
71 nla_total_size(sizeof(u32
)); /* _EEE_TX_LPI_TIMER */
76 static int eee_fill_reply(struct sk_buff
*skb
,
77 const struct ethnl_req_info
*req_base
,
78 const struct ethnl_reply_data
*reply_base
)
80 bool compact
= req_base
->flags
& ETHTOOL_FLAG_COMPACT_BITSETS
;
81 const struct eee_reply_data
*data
= EEE_REPDATA(reply_base
);
82 const struct ethtool_keee
*eee
= &data
->eee
;
85 ret
= ethnl_put_bitset(skb
, ETHTOOL_A_EEE_MODES_OURS
,
86 eee
->advertised
, eee
->supported
,
87 __ETHTOOL_LINK_MODE_MASK_NBITS
,
88 link_mode_names
, compact
);
91 ret
= ethnl_put_bitset(skb
, ETHTOOL_A_EEE_MODES_PEER
,
92 eee
->lp_advertised
, NULL
,
93 __ETHTOOL_LINK_MODE_MASK_NBITS
,
94 link_mode_names
, compact
);
98 if (nla_put_u8(skb
, ETHTOOL_A_EEE_ACTIVE
, eee
->eee_active
) ||
99 nla_put_u8(skb
, ETHTOOL_A_EEE_ENABLED
, eee
->eee_enabled
) ||
100 nla_put_u8(skb
, ETHTOOL_A_EEE_TX_LPI_ENABLED
,
101 eee
->tx_lpi_enabled
) ||
102 nla_put_u32(skb
, ETHTOOL_A_EEE_TX_LPI_TIMER
, eee
->tx_lpi_timer
))
110 const struct nla_policy ethnl_eee_set_policy
[] = {
111 [ETHTOOL_A_EEE_HEADER
] =
112 NLA_POLICY_NESTED(ethnl_header_policy
),
113 [ETHTOOL_A_EEE_MODES_OURS
] = { .type
= NLA_NESTED
},
114 [ETHTOOL_A_EEE_ENABLED
] = { .type
= NLA_U8
},
115 [ETHTOOL_A_EEE_TX_LPI_ENABLED
] = { .type
= NLA_U8
},
116 [ETHTOOL_A_EEE_TX_LPI_TIMER
] = { .type
= NLA_U32
},
120 ethnl_set_eee_validate(struct ethnl_req_info
*req_info
, struct genl_info
*info
)
122 const struct ethtool_ops
*ops
= req_info
->dev
->ethtool_ops
;
124 return ops
->get_eee
&& ops
->set_eee
? 1 : -EOPNOTSUPP
;
128 ethnl_set_eee(struct ethnl_req_info
*req_info
, struct genl_info
*info
)
130 struct net_device
*dev
= req_info
->dev
;
131 struct nlattr
**tb
= info
->attrs
;
132 struct ethtool_keee eee
= {};
136 ret
= dev
->ethtool_ops
->get_eee(dev
, &eee
);
140 ret
= ethnl_update_bitset(eee
.advertised
,
141 __ETHTOOL_LINK_MODE_MASK_NBITS
,
142 tb
[ETHTOOL_A_EEE_MODES_OURS
],
143 link_mode_names
, info
->extack
, &mod
);
146 ethnl_update_bool(&eee
.eee_enabled
, tb
[ETHTOOL_A_EEE_ENABLED
], &mod
);
147 ethnl_update_bool(&eee
.tx_lpi_enabled
, tb
[ETHTOOL_A_EEE_TX_LPI_ENABLED
],
149 ethnl_update_u32(&eee
.tx_lpi_timer
, tb
[ETHTOOL_A_EEE_TX_LPI_TIMER
],
154 ret
= dev
->ethtool_ops
->set_eee(dev
, &eee
);
155 return ret
< 0 ? ret
: 1;
158 const struct ethnl_request_ops ethnl_eee_request_ops
= {
159 .request_cmd
= ETHTOOL_MSG_EEE_GET
,
160 .reply_cmd
= ETHTOOL_MSG_EEE_GET_REPLY
,
161 .hdr_attr
= ETHTOOL_A_EEE_HEADER
,
162 .req_info_size
= sizeof(struct eee_req_info
),
163 .reply_data_size
= sizeof(struct eee_reply_data
),
165 .prepare_data
= eee_prepare_data
,
166 .reply_size
= eee_reply_size
,
167 .fill_reply
= eee_fill_reply
,
169 .set_validate
= ethnl_set_eee_validate
,
170 .set
= ethnl_set_eee
,
171 .set_ntf_cmd
= ETHTOOL_MSG_EEE_NTF
,