xref: /openbmc/linux/net/devlink/dev.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4   * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
5   */
6  
7  #include <net/genetlink.h>
8  #include <net/sock.h>
9  #include "devl_internal.h"
10  
11  struct devlink_info_req {
12  	struct sk_buff *msg;
13  	void (*version_cb)(const char *version_name,
14  			   enum devlink_info_version_type version_type,
15  			   void *version_cb_priv);
16  	void *version_cb_priv;
17  };
18  
19  struct devlink_reload_combination {
20  	enum devlink_reload_action action;
21  	enum devlink_reload_limit limit;
22  };
23  
24  static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
25  	{
26  		/* can't reinitialize driver with no down time */
27  		.action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
28  		.limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
29  	},
30  };
31  
32  static bool
devlink_reload_combination_is_invalid(enum devlink_reload_action action,enum devlink_reload_limit limit)33  devlink_reload_combination_is_invalid(enum devlink_reload_action action,
34  				      enum devlink_reload_limit limit)
35  {
36  	int i;
37  
38  	for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
39  		if (devlink_reload_invalid_combinations[i].action == action &&
40  		    devlink_reload_invalid_combinations[i].limit == limit)
41  			return true;
42  	return false;
43  }
44  
45  static bool
devlink_reload_action_is_supported(struct devlink * devlink,enum devlink_reload_action action)46  devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
47  {
48  	return test_bit(action, &devlink->ops->reload_actions);
49  }
50  
51  static bool
devlink_reload_limit_is_supported(struct devlink * devlink,enum devlink_reload_limit limit)52  devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
53  {
54  	return test_bit(limit, &devlink->ops->reload_limits);
55  }
56  
devlink_reload_stat_put(struct sk_buff * msg,enum devlink_reload_limit limit,u32 value)57  static int devlink_reload_stat_put(struct sk_buff *msg,
58  				   enum devlink_reload_limit limit, u32 value)
59  {
60  	struct nlattr *reload_stats_entry;
61  
62  	reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
63  	if (!reload_stats_entry)
64  		return -EMSGSIZE;
65  
66  	if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
67  	    nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
68  		goto nla_put_failure;
69  	nla_nest_end(msg, reload_stats_entry);
70  	return 0;
71  
72  nla_put_failure:
73  	nla_nest_cancel(msg, reload_stats_entry);
74  	return -EMSGSIZE;
75  }
76  
77  static int
devlink_reload_stats_put(struct sk_buff * msg,struct devlink * devlink,bool is_remote)78  devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
79  {
80  	struct nlattr *reload_stats_attr, *act_info, *act_stats;
81  	int i, j, stat_idx;
82  	u32 value;
83  
84  	if (!is_remote)
85  		reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
86  	else
87  		reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
88  
89  	if (!reload_stats_attr)
90  		return -EMSGSIZE;
91  
92  	for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
93  		if ((!is_remote &&
94  		     !devlink_reload_action_is_supported(devlink, i)) ||
95  		    i == DEVLINK_RELOAD_ACTION_UNSPEC)
96  			continue;
97  		act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
98  		if (!act_info)
99  			goto nla_put_failure;
100  
101  		if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
102  			goto action_info_nest_cancel;
103  		act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
104  		if (!act_stats)
105  			goto action_info_nest_cancel;
106  
107  		for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
108  			/* Remote stats are shown even if not locally supported.
109  			 * Stats of actions with unspecified limit are shown
110  			 * though drivers don't need to register unspecified
111  			 * limit.
112  			 */
113  			if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
114  			     !devlink_reload_limit_is_supported(devlink, j)) ||
115  			    devlink_reload_combination_is_invalid(i, j))
116  				continue;
117  
118  			stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
119  			if (!is_remote)
120  				value = devlink->stats.reload_stats[stat_idx];
121  			else
122  				value = devlink->stats.remote_reload_stats[stat_idx];
123  			if (devlink_reload_stat_put(msg, j, value))
124  				goto action_stats_nest_cancel;
125  		}
126  		nla_nest_end(msg, act_stats);
127  		nla_nest_end(msg, act_info);
128  	}
129  	nla_nest_end(msg, reload_stats_attr);
130  	return 0;
131  
132  action_stats_nest_cancel:
133  	nla_nest_cancel(msg, act_stats);
134  action_info_nest_cancel:
135  	nla_nest_cancel(msg, act_info);
136  nla_put_failure:
137  	nla_nest_cancel(msg, reload_stats_attr);
138  	return -EMSGSIZE;
139  }
140  
devlink_nl_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags)141  static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
142  			   enum devlink_command cmd, u32 portid,
143  			   u32 seq, int flags)
144  {
145  	struct nlattr *dev_stats;
146  	void *hdr;
147  
148  	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
149  	if (!hdr)
150  		return -EMSGSIZE;
151  
152  	if (devlink_nl_put_handle(msg, devlink))
153  		goto nla_put_failure;
154  	if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
155  		goto nla_put_failure;
156  
157  	dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
158  	if (!dev_stats)
159  		goto nla_put_failure;
160  
161  	if (devlink_reload_stats_put(msg, devlink, false))
162  		goto dev_stats_nest_cancel;
163  	if (devlink_reload_stats_put(msg, devlink, true))
164  		goto dev_stats_nest_cancel;
165  
166  	nla_nest_end(msg, dev_stats);
167  	genlmsg_end(msg, hdr);
168  	return 0;
169  
170  dev_stats_nest_cancel:
171  	nla_nest_cancel(msg, dev_stats);
172  nla_put_failure:
173  	genlmsg_cancel(msg, hdr);
174  	return -EMSGSIZE;
175  }
176  
devlink_notify(struct devlink * devlink,enum devlink_command cmd)177  static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
178  {
179  	struct sk_buff *msg;
180  	int err;
181  
182  	WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
183  	WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
184  
185  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
186  	if (!msg)
187  		return;
188  
189  	err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
190  	if (err) {
191  		nlmsg_free(msg);
192  		return;
193  	}
194  
195  	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
196  				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
197  }
198  
devlink_nl_get_doit(struct sk_buff * skb,struct genl_info * info)199  int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info)
200  {
201  	struct devlink *devlink = info->user_ptr[0];
202  	struct sk_buff *msg;
203  	int err;
204  
205  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
206  	if (!msg)
207  		return -ENOMEM;
208  
209  	err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
210  			      info->snd_portid, info->snd_seq, 0);
211  	if (err) {
212  		nlmsg_free(msg);
213  		return err;
214  	}
215  
216  	return genlmsg_reply(msg, info);
217  }
218  
219  static int
devlink_nl_get_dump_one(struct sk_buff * msg,struct devlink * devlink,struct netlink_callback * cb,int flags)220  devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
221  			struct netlink_callback *cb, int flags)
222  {
223  	return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
224  			       NETLINK_CB(cb->skb).portid,
225  			       cb->nlh->nlmsg_seq, flags);
226  }
227  
devlink_nl_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)228  int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
229  {
230  	return devlink_nl_dumpit(msg, cb, devlink_nl_get_dump_one);
231  }
232  
devlink_notify_register(struct devlink * devlink)233  void devlink_notify_register(struct devlink *devlink)
234  {
235  	devlink_notify(devlink, DEVLINK_CMD_NEW);
236  	devlink_linecards_notify_register(devlink);
237  	devlink_ports_notify_register(devlink);
238  	devlink_trap_policers_notify_register(devlink);
239  	devlink_trap_groups_notify_register(devlink);
240  	devlink_traps_notify_register(devlink);
241  	devlink_rates_notify_register(devlink);
242  	devlink_regions_notify_register(devlink);
243  	devlink_params_notify_register(devlink);
244  }
245  
devlink_notify_unregister(struct devlink * devlink)246  void devlink_notify_unregister(struct devlink *devlink)
247  {
248  	devlink_params_notify_unregister(devlink);
249  	devlink_regions_notify_unregister(devlink);
250  	devlink_rates_notify_unregister(devlink);
251  	devlink_traps_notify_unregister(devlink);
252  	devlink_trap_groups_notify_unregister(devlink);
253  	devlink_trap_policers_notify_unregister(devlink);
254  	devlink_ports_notify_unregister(devlink);
255  	devlink_linecards_notify_unregister(devlink);
256  	devlink_notify(devlink, DEVLINK_CMD_DEL);
257  }
258  
devlink_reload_failed_set(struct devlink * devlink,bool reload_failed)259  static void devlink_reload_failed_set(struct devlink *devlink,
260  				      bool reload_failed)
261  {
262  	if (devlink->reload_failed == reload_failed)
263  		return;
264  	devlink->reload_failed = reload_failed;
265  	devlink_notify(devlink, DEVLINK_CMD_NEW);
266  }
267  
devlink_is_reload_failed(const struct devlink * devlink)268  bool devlink_is_reload_failed(const struct devlink *devlink)
269  {
270  	return devlink->reload_failed;
271  }
272  EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
273  
274  static void
__devlink_reload_stats_update(struct devlink * devlink,u32 * reload_stats,enum devlink_reload_limit limit,u32 actions_performed)275  __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
276  			      enum devlink_reload_limit limit, u32 actions_performed)
277  {
278  	unsigned long actions = actions_performed;
279  	int stat_idx;
280  	int action;
281  
282  	for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
283  		stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
284  		reload_stats[stat_idx]++;
285  	}
286  	devlink_notify(devlink, DEVLINK_CMD_NEW);
287  }
288  
289  static void
devlink_reload_stats_update(struct devlink * devlink,enum devlink_reload_limit limit,u32 actions_performed)290  devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
291  			    u32 actions_performed)
292  {
293  	__devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
294  				      actions_performed);
295  }
296  
297  /**
298   *	devlink_remote_reload_actions_performed - Update devlink on reload actions
299   *	  performed which are not a direct result of devlink reload call.
300   *
301   *	This should be called by a driver after performing reload actions in case it was not
302   *	a result of devlink reload call. For example fw_activate was performed as a result
303   *	of devlink reload triggered fw_activate on another host.
304   *	The motivation for this function is to keep data on reload actions performed on this
305   *	function whether it was done due to direct devlink reload call or not.
306   *
307   *	@devlink: devlink
308   *	@limit: reload limit
309   *	@actions_performed: bitmask of actions performed
310   */
devlink_remote_reload_actions_performed(struct devlink * devlink,enum devlink_reload_limit limit,u32 actions_performed)311  void devlink_remote_reload_actions_performed(struct devlink *devlink,
312  					     enum devlink_reload_limit limit,
313  					     u32 actions_performed)
314  {
315  	if (WARN_ON(!actions_performed ||
316  		    actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
317  		    actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
318  		    limit > DEVLINK_RELOAD_LIMIT_MAX))
319  		return;
320  
321  	__devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
322  				      actions_performed);
323  }
324  EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
325  
devlink_netns_get(struct sk_buff * skb,struct genl_info * info)326  static struct net *devlink_netns_get(struct sk_buff *skb,
327  				     struct genl_info *info)
328  {
329  	struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
330  	struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
331  	struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
332  	struct net *net;
333  
334  	if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
335  		NL_SET_ERR_MSG(info->extack, "multiple netns identifying attributes specified");
336  		return ERR_PTR(-EINVAL);
337  	}
338  
339  	if (netns_pid_attr) {
340  		net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
341  	} else if (netns_fd_attr) {
342  		net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
343  	} else if (netns_id_attr) {
344  		net = get_net_ns_by_id(sock_net(skb->sk),
345  				       nla_get_u32(netns_id_attr));
346  		if (!net)
347  			net = ERR_PTR(-EINVAL);
348  	} else {
349  		WARN_ON(1);
350  		net = ERR_PTR(-EINVAL);
351  	}
352  	if (IS_ERR(net)) {
353  		NL_SET_ERR_MSG(info->extack, "Unknown network namespace");
354  		return ERR_PTR(-EINVAL);
355  	}
356  	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
357  		put_net(net);
358  		return ERR_PTR(-EPERM);
359  	}
360  	return net;
361  }
362  
devlink_reload_netns_change(struct devlink * devlink,struct net * curr_net,struct net * dest_net)363  static void devlink_reload_netns_change(struct devlink *devlink,
364  					struct net *curr_net,
365  					struct net *dest_net)
366  {
367  	/* Userspace needs to be notified about devlink objects
368  	 * removed from original and entering new network namespace.
369  	 * The rest of the devlink objects are re-created during
370  	 * reload process so the notifications are generated separatelly.
371  	 */
372  	devlink_notify_unregister(devlink);
373  	write_pnet(&devlink->_net, dest_net);
374  	devlink_notify_register(devlink);
375  }
376  
devlink_reload(struct devlink * devlink,struct net * dest_net,enum devlink_reload_action action,enum devlink_reload_limit limit,u32 * actions_performed,struct netlink_ext_ack * extack)377  int devlink_reload(struct devlink *devlink, struct net *dest_net,
378  		   enum devlink_reload_action action,
379  		   enum devlink_reload_limit limit,
380  		   u32 *actions_performed, struct netlink_ext_ack *extack)
381  {
382  	u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
383  	struct net *curr_net;
384  	int err;
385  
386  	memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
387  	       sizeof(remote_reload_stats));
388  
389  	err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
390  	if (err)
391  		return err;
392  
393  	curr_net = devlink_net(devlink);
394  	if (dest_net && !net_eq(dest_net, curr_net))
395  		devlink_reload_netns_change(devlink, curr_net, dest_net);
396  
397  	if (action == DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
398  		devlink_params_driverinit_load_new(devlink);
399  
400  	err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
401  	devlink_reload_failed_set(devlink, !!err);
402  	if (err)
403  		return err;
404  
405  	WARN_ON(!(*actions_performed & BIT(action)));
406  	/* Catch driver on updating the remote action within devlink reload */
407  	WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
408  		       sizeof(remote_reload_stats)));
409  	devlink_reload_stats_update(devlink, limit, *actions_performed);
410  	return 0;
411  }
412  
413  static int
devlink_nl_reload_actions_performed_snd(struct devlink * devlink,u32 actions_performed,enum devlink_command cmd,struct genl_info * info)414  devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
415  					enum devlink_command cmd, struct genl_info *info)
416  {
417  	struct sk_buff *msg;
418  	void *hdr;
419  
420  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
421  	if (!msg)
422  		return -ENOMEM;
423  
424  	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
425  	if (!hdr)
426  		goto free_msg;
427  
428  	if (devlink_nl_put_handle(msg, devlink))
429  		goto nla_put_failure;
430  
431  	if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
432  			       actions_performed))
433  		goto nla_put_failure;
434  	genlmsg_end(msg, hdr);
435  
436  	return genlmsg_reply(msg, info);
437  
438  nla_put_failure:
439  	genlmsg_cancel(msg, hdr);
440  free_msg:
441  	nlmsg_free(msg);
442  	return -EMSGSIZE;
443  }
444  
devlink_nl_cmd_reload(struct sk_buff * skb,struct genl_info * info)445  int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
446  {
447  	struct devlink *devlink = info->user_ptr[0];
448  	enum devlink_reload_action action;
449  	enum devlink_reload_limit limit;
450  	struct net *dest_net = NULL;
451  	u32 actions_performed;
452  	int err;
453  
454  	err = devlink_resources_validate(devlink, NULL, info);
455  	if (err) {
456  		NL_SET_ERR_MSG(info->extack, "resources size validation failed");
457  		return err;
458  	}
459  
460  	if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
461  		action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
462  	else
463  		action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
464  
465  	if (!devlink_reload_action_is_supported(devlink, action)) {
466  		NL_SET_ERR_MSG(info->extack, "Requested reload action is not supported by the driver");
467  		return -EOPNOTSUPP;
468  	}
469  
470  	limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
471  	if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
472  		struct nla_bitfield32 limits;
473  		u32 limits_selected;
474  
475  		limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
476  		limits_selected = limits.value & limits.selector;
477  		if (!limits_selected) {
478  			NL_SET_ERR_MSG(info->extack, "Invalid limit selected");
479  			return -EINVAL;
480  		}
481  		for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
482  			if (limits_selected & BIT(limit))
483  				break;
484  		/* UAPI enables multiselection, but currently it is not used */
485  		if (limits_selected != BIT(limit)) {
486  			NL_SET_ERR_MSG(info->extack, "Multiselection of limit is not supported");
487  			return -EOPNOTSUPP;
488  		}
489  		if (!devlink_reload_limit_is_supported(devlink, limit)) {
490  			NL_SET_ERR_MSG(info->extack, "Requested limit is not supported by the driver");
491  			return -EOPNOTSUPP;
492  		}
493  		if (devlink_reload_combination_is_invalid(action, limit)) {
494  			NL_SET_ERR_MSG(info->extack, "Requested limit is invalid for this action");
495  			return -EINVAL;
496  		}
497  	}
498  	if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
499  	    info->attrs[DEVLINK_ATTR_NETNS_FD] ||
500  	    info->attrs[DEVLINK_ATTR_NETNS_ID]) {
501  		dest_net = devlink_netns_get(skb, info);
502  		if (IS_ERR(dest_net))
503  			return PTR_ERR(dest_net);
504  		if (!net_eq(dest_net, devlink_net(devlink)) &&
505  		    action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) {
506  			NL_SET_ERR_MSG_MOD(info->extack,
507  					   "Changing namespace is only supported for reinit action");
508  			return -EOPNOTSUPP;
509  		}
510  	}
511  
512  	err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
513  
514  	if (dest_net)
515  		put_net(dest_net);
516  
517  	if (err)
518  		return err;
519  	/* For backward compatibility generate reply only if attributes used by user */
520  	if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
521  		return 0;
522  
523  	return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
524  						       DEVLINK_CMD_RELOAD, info);
525  }
526  
devlink_reload_actions_valid(const struct devlink_ops * ops)527  bool devlink_reload_actions_valid(const struct devlink_ops *ops)
528  {
529  	const struct devlink_reload_combination *comb;
530  	int i;
531  
532  	if (!devlink_reload_supported(ops)) {
533  		if (WARN_ON(ops->reload_actions))
534  			return false;
535  		return true;
536  	}
537  
538  	if (WARN_ON(!ops->reload_actions ||
539  		    ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
540  		    ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
541  		return false;
542  
543  	if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
544  		    ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
545  		return false;
546  
547  	for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)  {
548  		comb = &devlink_reload_invalid_combinations[i];
549  		if (ops->reload_actions == BIT(comb->action) &&
550  		    ops->reload_limits == BIT(comb->limit))
551  			return false;
552  	}
553  	return true;
554  }
555  
devlink_nl_eswitch_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags)556  static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
557  				   enum devlink_command cmd, u32 portid,
558  				   u32 seq, int flags)
559  {
560  	const struct devlink_ops *ops = devlink->ops;
561  	enum devlink_eswitch_encap_mode encap_mode;
562  	u8 inline_mode;
563  	void *hdr;
564  	int err = 0;
565  	u16 mode;
566  
567  	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
568  	if (!hdr)
569  		return -EMSGSIZE;
570  
571  	err = devlink_nl_put_handle(msg, devlink);
572  	if (err)
573  		goto nla_put_failure;
574  
575  	if (ops->eswitch_mode_get) {
576  		err = ops->eswitch_mode_get(devlink, &mode);
577  		if (err)
578  			goto nla_put_failure;
579  		err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
580  		if (err)
581  			goto nla_put_failure;
582  	}
583  
584  	if (ops->eswitch_inline_mode_get) {
585  		err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
586  		if (err)
587  			goto nla_put_failure;
588  		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
589  				 inline_mode);
590  		if (err)
591  			goto nla_put_failure;
592  	}
593  
594  	if (ops->eswitch_encap_mode_get) {
595  		err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
596  		if (err)
597  			goto nla_put_failure;
598  		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
599  		if (err)
600  			goto nla_put_failure;
601  	}
602  
603  	genlmsg_end(msg, hdr);
604  	return 0;
605  
606  nla_put_failure:
607  	genlmsg_cancel(msg, hdr);
608  	return err;
609  }
610  
devlink_nl_cmd_eswitch_get_doit(struct sk_buff * skb,struct genl_info * info)611  int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info)
612  {
613  	struct devlink *devlink = info->user_ptr[0];
614  	struct sk_buff *msg;
615  	int err;
616  
617  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
618  	if (!msg)
619  		return -ENOMEM;
620  
621  	err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
622  				      info->snd_portid, info->snd_seq, 0);
623  
624  	if (err) {
625  		nlmsg_free(msg);
626  		return err;
627  	}
628  
629  	return genlmsg_reply(msg, info);
630  }
631  
devlink_nl_cmd_eswitch_set_doit(struct sk_buff * skb,struct genl_info * info)632  int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info)
633  {
634  	struct devlink *devlink = info->user_ptr[0];
635  	const struct devlink_ops *ops = devlink->ops;
636  	enum devlink_eswitch_encap_mode encap_mode;
637  	u8 inline_mode;
638  	int err = 0;
639  	u16 mode;
640  
641  	if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
642  		if (!ops->eswitch_mode_set)
643  			return -EOPNOTSUPP;
644  		mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
645  		err = devlink_rate_nodes_check(devlink, mode, info->extack);
646  		if (err)
647  			return err;
648  		err = ops->eswitch_mode_set(devlink, mode, info->extack);
649  		if (err)
650  			return err;
651  	}
652  
653  	if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
654  		if (!ops->eswitch_inline_mode_set)
655  			return -EOPNOTSUPP;
656  		inline_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
657  		err = ops->eswitch_inline_mode_set(devlink, inline_mode,
658  						   info->extack);
659  		if (err)
660  			return err;
661  	}
662  
663  	if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
664  		if (!ops->eswitch_encap_mode_set)
665  			return -EOPNOTSUPP;
666  		encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
667  		err = ops->eswitch_encap_mode_set(devlink, encap_mode,
668  						  info->extack);
669  		if (err)
670  			return err;
671  	}
672  
673  	return 0;
674  }
675  
devlink_info_serial_number_put(struct devlink_info_req * req,const char * sn)676  int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
677  {
678  	if (!req->msg)
679  		return 0;
680  	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
681  }
682  EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
683  
devlink_info_board_serial_number_put(struct devlink_info_req * req,const char * bsn)684  int devlink_info_board_serial_number_put(struct devlink_info_req *req,
685  					 const char *bsn)
686  {
687  	if (!req->msg)
688  		return 0;
689  	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
690  			      bsn);
691  }
692  EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
693  
devlink_info_version_put(struct devlink_info_req * req,int attr,const char * version_name,const char * version_value,enum devlink_info_version_type version_type)694  static int devlink_info_version_put(struct devlink_info_req *req, int attr,
695  				    const char *version_name,
696  				    const char *version_value,
697  				    enum devlink_info_version_type version_type)
698  {
699  	struct nlattr *nest;
700  	int err;
701  
702  	if (req->version_cb)
703  		req->version_cb(version_name, version_type,
704  				req->version_cb_priv);
705  
706  	if (!req->msg)
707  		return 0;
708  
709  	nest = nla_nest_start_noflag(req->msg, attr);
710  	if (!nest)
711  		return -EMSGSIZE;
712  
713  	err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
714  			     version_name);
715  	if (err)
716  		goto nla_put_failure;
717  
718  	err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
719  			     version_value);
720  	if (err)
721  		goto nla_put_failure;
722  
723  	nla_nest_end(req->msg, nest);
724  
725  	return 0;
726  
727  nla_put_failure:
728  	nla_nest_cancel(req->msg, nest);
729  	return err;
730  }
731  
devlink_info_version_fixed_put(struct devlink_info_req * req,const char * version_name,const char * version_value)732  int devlink_info_version_fixed_put(struct devlink_info_req *req,
733  				   const char *version_name,
734  				   const char *version_value)
735  {
736  	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
737  					version_name, version_value,
738  					DEVLINK_INFO_VERSION_TYPE_NONE);
739  }
740  EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
741  
devlink_info_version_stored_put(struct devlink_info_req * req,const char * version_name,const char * version_value)742  int devlink_info_version_stored_put(struct devlink_info_req *req,
743  				    const char *version_name,
744  				    const char *version_value)
745  {
746  	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
747  					version_name, version_value,
748  					DEVLINK_INFO_VERSION_TYPE_NONE);
749  }
750  EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
751  
devlink_info_version_stored_put_ext(struct devlink_info_req * req,const char * version_name,const char * version_value,enum devlink_info_version_type version_type)752  int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
753  					const char *version_name,
754  					const char *version_value,
755  					enum devlink_info_version_type version_type)
756  {
757  	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
758  					version_name, version_value,
759  					version_type);
760  }
761  EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
762  
devlink_info_version_running_put(struct devlink_info_req * req,const char * version_name,const char * version_value)763  int devlink_info_version_running_put(struct devlink_info_req *req,
764  				     const char *version_name,
765  				     const char *version_value)
766  {
767  	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
768  					version_name, version_value,
769  					DEVLINK_INFO_VERSION_TYPE_NONE);
770  }
771  EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
772  
devlink_info_version_running_put_ext(struct devlink_info_req * req,const char * version_name,const char * version_value,enum devlink_info_version_type version_type)773  int devlink_info_version_running_put_ext(struct devlink_info_req *req,
774  					 const char *version_name,
775  					 const char *version_value,
776  					 enum devlink_info_version_type version_type)
777  {
778  	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
779  					version_name, version_value,
780  					version_type);
781  }
782  EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
783  
devlink_nl_driver_info_get(struct device_driver * drv,struct devlink_info_req * req)784  static int devlink_nl_driver_info_get(struct device_driver *drv,
785  				      struct devlink_info_req *req)
786  {
787  	if (!drv)
788  		return 0;
789  
790  	if (drv->name[0])
791  		return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME,
792  				      drv->name);
793  
794  	return 0;
795  }
796  
797  static int
devlink_nl_info_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)798  devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
799  		     enum devlink_command cmd, u32 portid,
800  		     u32 seq, int flags, struct netlink_ext_ack *extack)
801  {
802  	struct device *dev = devlink_to_dev(devlink);
803  	struct devlink_info_req req = {};
804  	void *hdr;
805  	int err;
806  
807  	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
808  	if (!hdr)
809  		return -EMSGSIZE;
810  
811  	err = -EMSGSIZE;
812  	if (devlink_nl_put_handle(msg, devlink))
813  		goto err_cancel_msg;
814  
815  	req.msg = msg;
816  	if (devlink->ops->info_get) {
817  		err = devlink->ops->info_get(devlink, &req, extack);
818  		if (err)
819  			goto err_cancel_msg;
820  	}
821  
822  	err = devlink_nl_driver_info_get(dev->driver, &req);
823  	if (err)
824  		goto err_cancel_msg;
825  
826  	genlmsg_end(msg, hdr);
827  	return 0;
828  
829  err_cancel_msg:
830  	genlmsg_cancel(msg, hdr);
831  	return err;
832  }
833  
devlink_nl_info_get_doit(struct sk_buff * skb,struct genl_info * info)834  int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info)
835  {
836  	struct devlink *devlink = info->user_ptr[0];
837  	struct sk_buff *msg;
838  	int err;
839  
840  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
841  	if (!msg)
842  		return -ENOMEM;
843  
844  	err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
845  				   info->snd_portid, info->snd_seq, 0,
846  				   info->extack);
847  	if (err) {
848  		nlmsg_free(msg);
849  		return err;
850  	}
851  
852  	return genlmsg_reply(msg, info);
853  }
854  
855  static int
devlink_nl_info_get_dump_one(struct sk_buff * msg,struct devlink * devlink,struct netlink_callback * cb,int flags)856  devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
857  			     struct netlink_callback *cb, int flags)
858  {
859  	int err;
860  
861  	err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
862  				   NETLINK_CB(cb->skb).portid,
863  				   cb->nlh->nlmsg_seq, flags,
864  				   cb->extack);
865  	if (err == -EOPNOTSUPP)
866  		err = 0;
867  	return err;
868  }
869  
devlink_nl_info_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)870  int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
871  {
872  	return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one);
873  }
874  
devlink_nl_flash_update_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,struct devlink_flash_notify * params)875  static int devlink_nl_flash_update_fill(struct sk_buff *msg,
876  					struct devlink *devlink,
877  					enum devlink_command cmd,
878  					struct devlink_flash_notify *params)
879  {
880  	void *hdr;
881  
882  	hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
883  	if (!hdr)
884  		return -EMSGSIZE;
885  
886  	if (devlink_nl_put_handle(msg, devlink))
887  		goto nla_put_failure;
888  
889  	if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
890  		goto out;
891  
892  	if (params->status_msg &&
893  	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
894  			   params->status_msg))
895  		goto nla_put_failure;
896  	if (params->component &&
897  	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
898  			   params->component))
899  		goto nla_put_failure;
900  	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
901  			      params->done, DEVLINK_ATTR_PAD))
902  		goto nla_put_failure;
903  	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
904  			      params->total, DEVLINK_ATTR_PAD))
905  		goto nla_put_failure;
906  	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
907  			      params->timeout, DEVLINK_ATTR_PAD))
908  		goto nla_put_failure;
909  
910  out:
911  	genlmsg_end(msg, hdr);
912  	return 0;
913  
914  nla_put_failure:
915  	genlmsg_cancel(msg, hdr);
916  	return -EMSGSIZE;
917  }
918  
__devlink_flash_update_notify(struct devlink * devlink,enum devlink_command cmd,struct devlink_flash_notify * params)919  static void __devlink_flash_update_notify(struct devlink *devlink,
920  					  enum devlink_command cmd,
921  					  struct devlink_flash_notify *params)
922  {
923  	struct sk_buff *msg;
924  	int err;
925  
926  	WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
927  		cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
928  		cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
929  
930  	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
931  		return;
932  
933  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
934  	if (!msg)
935  		return;
936  
937  	err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
938  	if (err)
939  		goto out_free_msg;
940  
941  	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
942  				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
943  	return;
944  
945  out_free_msg:
946  	nlmsg_free(msg);
947  }
948  
devlink_flash_update_begin_notify(struct devlink * devlink)949  static void devlink_flash_update_begin_notify(struct devlink *devlink)
950  {
951  	struct devlink_flash_notify params = {};
952  
953  	__devlink_flash_update_notify(devlink,
954  				      DEVLINK_CMD_FLASH_UPDATE,
955  				      &params);
956  }
957  
devlink_flash_update_end_notify(struct devlink * devlink)958  static void devlink_flash_update_end_notify(struct devlink *devlink)
959  {
960  	struct devlink_flash_notify params = {};
961  
962  	__devlink_flash_update_notify(devlink,
963  				      DEVLINK_CMD_FLASH_UPDATE_END,
964  				      &params);
965  }
966  
devlink_flash_update_status_notify(struct devlink * devlink,const char * status_msg,const char * component,unsigned long done,unsigned long total)967  void devlink_flash_update_status_notify(struct devlink *devlink,
968  					const char *status_msg,
969  					const char *component,
970  					unsigned long done,
971  					unsigned long total)
972  {
973  	struct devlink_flash_notify params = {
974  		.status_msg = status_msg,
975  		.component = component,
976  		.done = done,
977  		.total = total,
978  	};
979  
980  	__devlink_flash_update_notify(devlink,
981  				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
982  				      &params);
983  }
984  EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
985  
devlink_flash_update_timeout_notify(struct devlink * devlink,const char * status_msg,const char * component,unsigned long timeout)986  void devlink_flash_update_timeout_notify(struct devlink *devlink,
987  					 const char *status_msg,
988  					 const char *component,
989  					 unsigned long timeout)
990  {
991  	struct devlink_flash_notify params = {
992  		.status_msg = status_msg,
993  		.component = component,
994  		.timeout = timeout,
995  	};
996  
997  	__devlink_flash_update_notify(devlink,
998  				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
999  				      &params);
1000  }
1001  EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
1002  
1003  struct devlink_flash_component_lookup_ctx {
1004  	const char *lookup_name;
1005  	bool lookup_name_found;
1006  };
1007  
1008  static void
devlink_flash_component_lookup_cb(const char * version_name,enum devlink_info_version_type version_type,void * version_cb_priv)1009  devlink_flash_component_lookup_cb(const char *version_name,
1010  				  enum devlink_info_version_type version_type,
1011  				  void *version_cb_priv)
1012  {
1013  	struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
1014  
1015  	if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
1016  	    lookup_ctx->lookup_name_found)
1017  		return;
1018  
1019  	lookup_ctx->lookup_name_found =
1020  		!strcmp(lookup_ctx->lookup_name, version_name);
1021  }
1022  
devlink_flash_component_get(struct devlink * devlink,struct nlattr * nla_component,const char ** p_component,struct netlink_ext_ack * extack)1023  static int devlink_flash_component_get(struct devlink *devlink,
1024  				       struct nlattr *nla_component,
1025  				       const char **p_component,
1026  				       struct netlink_ext_ack *extack)
1027  {
1028  	struct devlink_flash_component_lookup_ctx lookup_ctx = {};
1029  	struct devlink_info_req req = {};
1030  	const char *component;
1031  	int ret;
1032  
1033  	if (!nla_component)
1034  		return 0;
1035  
1036  	component = nla_data(nla_component);
1037  
1038  	if (!devlink->ops->info_get) {
1039  		NL_SET_ERR_MSG_ATTR(extack, nla_component,
1040  				    "component update is not supported by this device");
1041  		return -EOPNOTSUPP;
1042  	}
1043  
1044  	lookup_ctx.lookup_name = component;
1045  	req.version_cb = devlink_flash_component_lookup_cb;
1046  	req.version_cb_priv = &lookup_ctx;
1047  
1048  	ret = devlink->ops->info_get(devlink, &req, NULL);
1049  	if (ret)
1050  		return ret;
1051  
1052  	if (!lookup_ctx.lookup_name_found) {
1053  		NL_SET_ERR_MSG_ATTR(extack, nla_component,
1054  				    "selected component is not supported by this device");
1055  		return -EINVAL;
1056  	}
1057  	*p_component = component;
1058  	return 0;
1059  }
1060  
devlink_nl_cmd_flash_update(struct sk_buff * skb,struct genl_info * info)1061  int devlink_nl_cmd_flash_update(struct sk_buff *skb, struct genl_info *info)
1062  {
1063  	struct nlattr *nla_overwrite_mask, *nla_file_name;
1064  	struct devlink_flash_update_params params = {};
1065  	struct devlink *devlink = info->user_ptr[0];
1066  	const char *file_name;
1067  	u32 supported_params;
1068  	int ret;
1069  
1070  	if (!devlink->ops->flash_update)
1071  		return -EOPNOTSUPP;
1072  
1073  	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME))
1074  		return -EINVAL;
1075  
1076  	ret = devlink_flash_component_get(devlink,
1077  					  info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
1078  					  &params.component, info->extack);
1079  	if (ret)
1080  		return ret;
1081  
1082  	supported_params = devlink->ops->supported_flash_update_params;
1083  
1084  	nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
1085  	if (nla_overwrite_mask) {
1086  		struct nla_bitfield32 sections;
1087  
1088  		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
1089  			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
1090  					    "overwrite settings are not supported by this device");
1091  			return -EOPNOTSUPP;
1092  		}
1093  		sections = nla_get_bitfield32(nla_overwrite_mask);
1094  		params.overwrite_mask = sections.value & sections.selector;
1095  	}
1096  
1097  	nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
1098  	file_name = nla_data(nla_file_name);
1099  	ret = request_firmware(&params.fw, file_name, devlink->dev);
1100  	if (ret) {
1101  		NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name,
1102  				    "failed to locate the requested firmware file");
1103  		return ret;
1104  	}
1105  
1106  	devlink_flash_update_begin_notify(devlink);
1107  	ret = devlink->ops->flash_update(devlink, &params, info->extack);
1108  	devlink_flash_update_end_notify(devlink);
1109  
1110  	release_firmware(params.fw);
1111  
1112  	return ret;
1113  }
1114  
__devlink_compat_running_version(struct devlink * devlink,char * buf,size_t len)1115  static void __devlink_compat_running_version(struct devlink *devlink,
1116  					     char *buf, size_t len)
1117  {
1118  	struct devlink_info_req req = {};
1119  	const struct nlattr *nlattr;
1120  	struct sk_buff *msg;
1121  	int rem, err;
1122  
1123  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1124  	if (!msg)
1125  		return;
1126  
1127  	req.msg = msg;
1128  	err = devlink->ops->info_get(devlink, &req, NULL);
1129  	if (err)
1130  		goto free_msg;
1131  
1132  	nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
1133  		const struct nlattr *kv;
1134  		int rem_kv;
1135  
1136  		if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
1137  			continue;
1138  
1139  		nla_for_each_nested(kv, nlattr, rem_kv) {
1140  			if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
1141  				continue;
1142  
1143  			strlcat(buf, nla_data(kv), len);
1144  			strlcat(buf, " ", len);
1145  		}
1146  	}
1147  free_msg:
1148  	nlmsg_free(msg);
1149  }
1150  
devlink_compat_running_version(struct devlink * devlink,char * buf,size_t len)1151  void devlink_compat_running_version(struct devlink *devlink,
1152  				    char *buf, size_t len)
1153  {
1154  	if (!devlink->ops->info_get)
1155  		return;
1156  
1157  	devl_lock(devlink);
1158  	if (devl_is_registered(devlink))
1159  		__devlink_compat_running_version(devlink, buf, len);
1160  	devl_unlock(devlink);
1161  }
1162  
devlink_compat_flash_update(struct devlink * devlink,const char * file_name)1163  int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
1164  {
1165  	struct devlink_flash_update_params params = {};
1166  	int ret;
1167  
1168  	devl_lock(devlink);
1169  	if (!devl_is_registered(devlink)) {
1170  		ret = -ENODEV;
1171  		goto out_unlock;
1172  	}
1173  
1174  	if (!devlink->ops->flash_update) {
1175  		ret = -EOPNOTSUPP;
1176  		goto out_unlock;
1177  	}
1178  
1179  	ret = request_firmware(&params.fw, file_name, devlink->dev);
1180  	if (ret)
1181  		goto out_unlock;
1182  
1183  	devlink_flash_update_begin_notify(devlink);
1184  	ret = devlink->ops->flash_update(devlink, &params, NULL);
1185  	devlink_flash_update_end_notify(devlink);
1186  
1187  	release_firmware(params.fw);
1188  out_unlock:
1189  	devl_unlock(devlink);
1190  
1191  	return ret;
1192  }
1193  
1194  static int
devlink_nl_selftests_fill(struct sk_buff * msg,struct devlink * devlink,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)1195  devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
1196  			  u32 portid, u32 seq, int flags,
1197  			  struct netlink_ext_ack *extack)
1198  {
1199  	struct nlattr *selftests;
1200  	void *hdr;
1201  	int err;
1202  	int i;
1203  
1204  	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
1205  			  DEVLINK_CMD_SELFTESTS_GET);
1206  	if (!hdr)
1207  		return -EMSGSIZE;
1208  
1209  	err = -EMSGSIZE;
1210  	if (devlink_nl_put_handle(msg, devlink))
1211  		goto err_cancel_msg;
1212  
1213  	selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
1214  	if (!selftests)
1215  		goto err_cancel_msg;
1216  
1217  	for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
1218  	     i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
1219  		if (devlink->ops->selftest_check(devlink, i, extack)) {
1220  			err = nla_put_flag(msg, i);
1221  			if (err)
1222  				goto err_cancel_msg;
1223  		}
1224  	}
1225  
1226  	nla_nest_end(msg, selftests);
1227  	genlmsg_end(msg, hdr);
1228  	return 0;
1229  
1230  err_cancel_msg:
1231  	genlmsg_cancel(msg, hdr);
1232  	return err;
1233  }
1234  
devlink_nl_selftests_get_doit(struct sk_buff * skb,struct genl_info * info)1235  int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info)
1236  {
1237  	struct devlink *devlink = info->user_ptr[0];
1238  	struct sk_buff *msg;
1239  	int err;
1240  
1241  	if (!devlink->ops->selftest_check)
1242  		return -EOPNOTSUPP;
1243  
1244  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1245  	if (!msg)
1246  		return -ENOMEM;
1247  
1248  	err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
1249  					info->snd_seq, 0, info->extack);
1250  	if (err) {
1251  		nlmsg_free(msg);
1252  		return err;
1253  	}
1254  
1255  	return genlmsg_reply(msg, info);
1256  }
1257  
devlink_nl_selftests_get_dump_one(struct sk_buff * msg,struct devlink * devlink,struct netlink_callback * cb,int flags)1258  static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg,
1259  					     struct devlink *devlink,
1260  					     struct netlink_callback *cb,
1261  					     int flags)
1262  {
1263  	if (!devlink->ops->selftest_check)
1264  		return 0;
1265  
1266  	return devlink_nl_selftests_fill(msg, devlink,
1267  					 NETLINK_CB(cb->skb).portid,
1268  					 cb->nlh->nlmsg_seq, flags,
1269  					 cb->extack);
1270  }
1271  
devlink_nl_selftests_get_dumpit(struct sk_buff * skb,struct netlink_callback * cb)1272  int devlink_nl_selftests_get_dumpit(struct sk_buff *skb,
1273  				    struct netlink_callback *cb)
1274  {
1275  	return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one);
1276  }
1277  
devlink_selftest_result_put(struct sk_buff * skb,unsigned int id,enum devlink_selftest_status test_status)1278  static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
1279  				       enum devlink_selftest_status test_status)
1280  {
1281  	struct nlattr *result_attr;
1282  
1283  	result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT);
1284  	if (!result_attr)
1285  		return -EMSGSIZE;
1286  
1287  	if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) ||
1288  	    nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
1289  		       test_status))
1290  		goto nla_put_failure;
1291  
1292  	nla_nest_end(skb, result_attr);
1293  	return 0;
1294  
1295  nla_put_failure:
1296  	nla_nest_cancel(skb, result_attr);
1297  	return -EMSGSIZE;
1298  }
1299  
1300  static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = {
1301  	[DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG },
1302  };
1303  
devlink_nl_cmd_selftests_run(struct sk_buff * skb,struct genl_info * info)1304  int devlink_nl_cmd_selftests_run(struct sk_buff *skb, struct genl_info *info)
1305  {
1306  	struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1];
1307  	struct devlink *devlink = info->user_ptr[0];
1308  	struct nlattr *attrs, *selftests;
1309  	struct sk_buff *msg;
1310  	void *hdr;
1311  	int err;
1312  	int i;
1313  
1314  	if (!devlink->ops->selftest_run || !devlink->ops->selftest_check)
1315  		return -EOPNOTSUPP;
1316  
1317  	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS))
1318  		return -EINVAL;
1319  
1320  	attrs = info->attrs[DEVLINK_ATTR_SELFTESTS];
1321  
1322  	err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs,
1323  			       devlink_selftest_nl_policy, info->extack);
1324  	if (err < 0)
1325  		return err;
1326  
1327  	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1328  	if (!msg)
1329  		return -ENOMEM;
1330  
1331  	err = -EMSGSIZE;
1332  	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
1333  			  &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
1334  	if (!hdr)
1335  		goto free_msg;
1336  
1337  	if (devlink_nl_put_handle(msg, devlink))
1338  		goto genlmsg_cancel;
1339  
1340  	selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
1341  	if (!selftests)
1342  		goto genlmsg_cancel;
1343  
1344  	for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
1345  	     i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
1346  		enum devlink_selftest_status test_status;
1347  
1348  		if (nla_get_flag(tb[i])) {
1349  			if (!devlink->ops->selftest_check(devlink, i,
1350  							  info->extack)) {
1351  				if (devlink_selftest_result_put(msg, i,
1352  								DEVLINK_SELFTEST_STATUS_SKIP))
1353  					goto selftests_nest_cancel;
1354  				continue;
1355  			}
1356  
1357  			test_status = devlink->ops->selftest_run(devlink, i,
1358  								 info->extack);
1359  			if (devlink_selftest_result_put(msg, i, test_status))
1360  				goto selftests_nest_cancel;
1361  		}
1362  	}
1363  
1364  	nla_nest_end(msg, selftests);
1365  	genlmsg_end(msg, hdr);
1366  	return genlmsg_reply(msg, info);
1367  
1368  selftests_nest_cancel:
1369  	nla_nest_cancel(msg, selftests);
1370  genlmsg_cancel:
1371  	genlmsg_cancel(msg, hdr);
1372  free_msg:
1373  	nlmsg_free(msg);
1374  	return err;
1375  }
1376