Skip to content

Commit d7d4cfc

Browse files
daniellertsdavem330
authored andcommitted
ethtool: Add flashing transceiver modules' firmware notifications ability
Add progress notifications ability to user space while flashing modules' firmware by implementing the interface between the user space and the kernel. Signed-off-by: Danielle Ratson <[email protected]> Reviewed-by: Petr Machata <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 46fb3ba commit d7d4cfc

File tree

4 files changed

+154
-0
lines changed

4 files changed

+154
-0
lines changed

net/ethtool/module.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "netlink.h"
66
#include "common.h"
77
#include "bitset.h"
8+
#include "module_fw.h"
89

910
struct module_req_info {
1011
struct ethnl_req_info base;
@@ -158,3 +159,119 @@ const struct ethnl_request_ops ethnl_module_request_ops = {
158159
.set = ethnl_set_module,
159160
.set_ntf_cmd = ETHTOOL_MSG_MODULE_NTF,
160161
};
162+
163+
/* MODULE_FW_FLASH_NTF */
164+
165+
static int
166+
ethnl_module_fw_flash_ntf_put_err(struct sk_buff *skb, char *err_msg,
167+
char *sub_err_msg)
168+
{
169+
int err_msg_len, sub_err_msg_len, total_len;
170+
struct nlattr *attr;
171+
172+
if (!err_msg)
173+
return 0;
174+
175+
err_msg_len = strlen(err_msg);
176+
total_len = err_msg_len + 2; /* For period and NUL. */
177+
178+
if (sub_err_msg) {
179+
sub_err_msg_len = strlen(sub_err_msg);
180+
total_len += sub_err_msg_len + 2; /* For ", ". */
181+
}
182+
183+
attr = nla_reserve(skb, ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG,
184+
total_len);
185+
if (!attr)
186+
return -ENOMEM;
187+
188+
if (sub_err_msg)
189+
sprintf(nla_data(attr), "%s, %s.", err_msg, sub_err_msg);
190+
else
191+
sprintf(nla_data(attr), "%s.", err_msg);
192+
193+
return 0;
194+
}
195+
196+
static void
197+
ethnl_module_fw_flash_ntf(struct net_device *dev,
198+
enum ethtool_module_fw_flash_status status,
199+
struct ethnl_module_fw_flash_ntf_params *ntf_params,
200+
char *err_msg, char *sub_err_msg,
201+
u64 done, u64 total)
202+
{
203+
struct sk_buff *skb;
204+
void *hdr;
205+
int ret;
206+
207+
if (ntf_params->closed_sock)
208+
return;
209+
210+
skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
211+
if (!skb)
212+
return;
213+
214+
hdr = ethnl_unicast_put(skb, ntf_params->portid, ntf_params->seq,
215+
ETHTOOL_MSG_MODULE_FW_FLASH_NTF);
216+
if (!hdr)
217+
goto err_skb;
218+
219+
ret = ethnl_fill_reply_header(skb, dev,
220+
ETHTOOL_A_MODULE_FW_FLASH_HEADER);
221+
if (ret < 0)
222+
goto err_skb;
223+
224+
if (nla_put_u32(skb, ETHTOOL_A_MODULE_FW_FLASH_STATUS, status))
225+
goto err_skb;
226+
227+
ret = ethnl_module_fw_flash_ntf_put_err(skb, err_msg, sub_err_msg);
228+
if (ret < 0)
229+
goto err_skb;
230+
231+
if (nla_put_uint(skb, ETHTOOL_A_MODULE_FW_FLASH_DONE, done))
232+
goto err_skb;
233+
234+
if (nla_put_uint(skb, ETHTOOL_A_MODULE_FW_FLASH_TOTAL, total))
235+
goto err_skb;
236+
237+
genlmsg_end(skb, hdr);
238+
genlmsg_unicast(dev_net(dev), skb, ntf_params->portid);
239+
return;
240+
241+
err_skb:
242+
nlmsg_free(skb);
243+
}
244+
245+
void ethnl_module_fw_flash_ntf_err(struct net_device *dev,
246+
struct ethnl_module_fw_flash_ntf_params *params,
247+
char *err_msg, char *sub_err_msg)
248+
{
249+
ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR,
250+
params, err_msg, sub_err_msg, 0, 0);
251+
}
252+
253+
void
254+
ethnl_module_fw_flash_ntf_start(struct net_device *dev,
255+
struct ethnl_module_fw_flash_ntf_params *params)
256+
{
257+
ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED,
258+
params, NULL, NULL, 0, 0);
259+
}
260+
261+
void
262+
ethnl_module_fw_flash_ntf_complete(struct net_device *dev,
263+
struct ethnl_module_fw_flash_ntf_params *params)
264+
{
265+
ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED,
266+
params, NULL, NULL, 0, 0);
267+
}
268+
269+
void
270+
ethnl_module_fw_flash_ntf_in_progress(struct net_device *dev,
271+
struct ethnl_module_fw_flash_ntf_params *params,
272+
u64 done, u64 total)
273+
{
274+
ethnl_module_fw_flash_ntf(dev,
275+
ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS,
276+
params, NULL, NULL, done, total);
277+
}

net/ethtool/module_fw.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#include <uapi/linux/ethtool.h>
4+
5+
/**
6+
* struct ethnl_module_fw_flash_ntf_params - module firmware flashing
7+
* notifications parameters
8+
* @portid: Netlink portid of sender.
9+
* @seq: Sequence number of sender.
10+
* @closed_sock: Indicates whether the socket was closed from user space.
11+
*/
12+
struct ethnl_module_fw_flash_ntf_params {
13+
u32 portid;
14+
u32 seq;
15+
bool closed_sock;
16+
};
17+
18+
void
19+
ethnl_module_fw_flash_ntf_err(struct net_device *dev,
20+
struct ethnl_module_fw_flash_ntf_params *params,
21+
char *err_msg, char *sub_err_msg);
22+
void
23+
ethnl_module_fw_flash_ntf_start(struct net_device *dev,
24+
struct ethnl_module_fw_flash_ntf_params *params);
25+
void
26+
ethnl_module_fw_flash_ntf_complete(struct net_device *dev,
27+
struct ethnl_module_fw_flash_ntf_params *params);
28+
void
29+
ethnl_module_fw_flash_ntf_in_progress(struct net_device *dev,
30+
struct ethnl_module_fw_flash_ntf_params *params,
31+
u64 done, u64 total);

net/ethtool/netlink.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ void *ethnl_bcastmsg_put(struct sk_buff *skb, u8 cmd)
239239
cmd);
240240
}
241241

242+
void *ethnl_unicast_put(struct sk_buff *skb, u32 portid, u32 seq, u8 cmd)
243+
{
244+
return genlmsg_put(skb, portid, seq, &ethtool_genl_family, 0, cmd);
245+
}
246+
242247
int ethnl_multicast(struct sk_buff *skb, struct net_device *dev)
243248
{
244249
return genlmsg_multicast_netns(&ethtool_genl_family, dev_net(dev), skb,

net/ethtool/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct sk_buff *ethnl_reply_init(size_t payload, struct net_device *dev, u8 cmd,
2121
void **ehdrp);
2222
void *ethnl_dump_put(struct sk_buff *skb, struct netlink_callback *cb, u8 cmd);
2323
void *ethnl_bcastmsg_put(struct sk_buff *skb, u8 cmd);
24+
void *ethnl_unicast_put(struct sk_buff *skb, u32 portid, u32 seq, u8 cmd);
2425
int ethnl_multicast(struct sk_buff *skb, struct net_device *dev);
2526

2627
/**

0 commit comments

Comments
 (0)