1 // SPDX-License-Identifier: GPL-2.0-only
8 struct ethnl_req_info base
;
11 struct wol_reply_data
{
12 struct ethnl_reply_data base
;
13 struct ethtool_wolinfo wol
;
17 #define WOL_REPDATA(__reply_base) \
18 container_of(__reply_base, struct wol_reply_data, base)
20 static const struct nla_policy
21 wol_get_policy
[ETHTOOL_A_WOL_MAX
+ 1] = {
22 [ETHTOOL_A_WOL_UNSPEC
] = { .type
= NLA_REJECT
},
23 [ETHTOOL_A_WOL_HEADER
] = { .type
= NLA_NESTED
},
24 [ETHTOOL_A_WOL_MODES
] = { .type
= NLA_REJECT
},
25 [ETHTOOL_A_WOL_SOPASS
] = { .type
= NLA_REJECT
},
28 static int wol_prepare_data(const struct ethnl_req_info
*req_base
,
29 struct ethnl_reply_data
*reply_base
,
30 struct genl_info
*info
)
32 struct wol_reply_data
*data
= WOL_REPDATA(reply_base
);
33 struct net_device
*dev
= reply_base
->dev
;
36 if (!dev
->ethtool_ops
->get_wol
)
39 ret
= ethnl_ops_begin(dev
);
42 dev
->ethtool_ops
->get_wol(dev
, &data
->wol
);
43 ethnl_ops_complete(dev
);
44 data
->show_sopass
= data
->wol
.supported
& WAKE_MAGICSECURE
;
49 static int wol_reply_size(const struct ethnl_req_info
*req_base
,
50 const struct ethnl_reply_data
*reply_base
)
52 bool compact
= req_base
->flags
& ETHTOOL_FLAG_COMPACT_BITSETS
;
53 const struct wol_reply_data
*data
= WOL_REPDATA(reply_base
);
56 len
= ethnl_bitset32_size(&data
->wol
.wolopts
, &data
->wol
.supported
,
57 WOL_MODE_COUNT
, wol_mode_names
, compact
);
60 if (data
->show_sopass
)
61 len
+= nla_total_size(sizeof(data
->wol
.sopass
));
66 static int wol_fill_reply(struct sk_buff
*skb
,
67 const struct ethnl_req_info
*req_base
,
68 const struct ethnl_reply_data
*reply_base
)
70 bool compact
= req_base
->flags
& ETHTOOL_FLAG_COMPACT_BITSETS
;
71 const struct wol_reply_data
*data
= WOL_REPDATA(reply_base
);
74 ret
= ethnl_put_bitset32(skb
, ETHTOOL_A_WOL_MODES
, &data
->wol
.wolopts
,
75 &data
->wol
.supported
, WOL_MODE_COUNT
,
76 wol_mode_names
, compact
);
79 if (data
->show_sopass
&&
80 nla_put(skb
, ETHTOOL_A_WOL_SOPASS
, sizeof(data
->wol
.sopass
),
87 const struct ethnl_request_ops ethnl_wol_request_ops
= {
88 .request_cmd
= ETHTOOL_MSG_WOL_GET
,
89 .reply_cmd
= ETHTOOL_MSG_WOL_GET_REPLY
,
90 .hdr_attr
= ETHTOOL_A_WOL_HEADER
,
91 .max_attr
= ETHTOOL_A_WOL_MAX
,
92 .req_info_size
= sizeof(struct wol_req_info
),
93 .reply_data_size
= sizeof(struct wol_reply_data
),
94 .request_policy
= wol_get_policy
,
96 .prepare_data
= wol_prepare_data
,
97 .reply_size
= wol_reply_size
,
98 .fill_reply
= wol_fill_reply
,