Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Apr 14-17, 2025
Register
Loading...
v4.6
 
  1/*
  2 * net/core/devlink.c - Network physical/parent device Netlink interface
  3 *
  4 * Heavily inspired by net/wireless/
  5 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
  6 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License as published by
 10 * the Free Software Foundation; either version 2 of the License, or
 11 * (at your option) any later version.
 12 */
 13
 
 14#include <linux/kernel.h>
 15#include <linux/module.h>
 16#include <linux/types.h>
 17#include <linux/slab.h>
 18#include <linux/gfp.h>
 19#include <linux/device.h>
 20#include <linux/list.h>
 21#include <linux/netdevice.h>
 
 
 
 
 
 22#include <rdma/ib_verbs.h>
 23#include <net/netlink.h>
 24#include <net/genetlink.h>
 25#include <net/rtnetlink.h>
 26#include <net/net_namespace.h>
 27#include <net/sock.h>
 28#include <net/devlink.h>
 
 
 29
 30static LIST_HEAD(devlink_list);
 
 31
 32/* devlink_mutex
 33 *
 34 * An overall lock guarding every operation coming from userspace.
 35 * It also guards devlink devices list and it is taken when
 36 * driver registers/unregisters it.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 37 */
 38static DEFINE_MUTEX(devlink_mutex);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 39
 40/* devlink_port_mutex
 
 
 
 
 
 
 41 *
 42 * Shared lock to guard lists of ports in all devlink devices.
 
 
 
 
 
 43 */
 44static DEFINE_MUTEX(devlink_port_mutex);
 
 
 
 45
 46static struct net *devlink_net(const struct devlink *devlink)
 47{
 48	return read_pnet(&devlink->_net);
 49}
 
 50
 51static void devlink_net_set(struct devlink *devlink, struct net *net)
 52{
 53	write_pnet(&devlink->_net, net);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 54}
 55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 56static struct devlink *devlink_get_from_attrs(struct net *net,
 57					      struct nlattr **attrs)
 58{
 59	struct devlink *devlink;
 
 60	char *busname;
 61	char *devname;
 62
 63	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
 64		return ERR_PTR(-EINVAL);
 65
 66	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
 67	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
 68
 69	list_for_each_entry(devlink, &devlink_list, list) {
 70		if (strcmp(devlink->dev->bus->name, busname) == 0 &&
 71		    strcmp(dev_name(devlink->dev), devname) == 0 &&
 72		    net_eq(devlink_net(devlink), net))
 73			return devlink;
 
 74	}
 75
 76	return ERR_PTR(-ENODEV);
 77}
 78
 79static struct devlink *devlink_get_from_info(struct genl_info *info)
 80{
 81	return devlink_get_from_attrs(genl_info_net(info), info->attrs);
 82}
 
 
 83
 84static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
 85						      int port_index)
 86{
 87	struct devlink_port *devlink_port;
 88
 89	list_for_each_entry(devlink_port, &devlink->port_list, list) {
 90		if (devlink_port->index == port_index)
 91			return devlink_port;
 92	}
 93	return NULL;
 94}
 95
 96static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
 97{
 98	return devlink_port_get_by_index(devlink, port_index);
 99}
100
101static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
102							struct nlattr **attrs)
103{
104	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
105		u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
106		struct devlink_port *devlink_port;
107
108		devlink_port = devlink_port_get_by_index(devlink, port_index);
109		if (!devlink_port)
110			return ERR_PTR(-ENODEV);
111		return devlink_port;
112	}
113	return ERR_PTR(-EINVAL);
114}
115
116static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
117						       struct genl_info *info)
118{
119	return devlink_port_get_from_attrs(devlink, info->attrs);
120}
121
122#define DEVLINK_NL_FLAG_NEED_PORT	BIT(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
124static int devlink_nl_pre_doit(const struct genl_ops *ops,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125			       struct sk_buff *skb, struct genl_info *info)
126{
 
 
127	struct devlink *devlink;
 
128
129	mutex_lock(&devlink_mutex);
130	devlink = devlink_get_from_info(info);
131	if (IS_ERR(devlink)) {
132		mutex_unlock(&devlink_mutex);
133		return PTR_ERR(devlink);
134	}
135	info->user_ptr[0] = devlink;
136	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
137		struct devlink_port *devlink_port;
138
139		mutex_lock(&devlink_port_mutex);
140		devlink_port = devlink_port_get_from_info(devlink, info);
141		if (IS_ERR(devlink_port)) {
142			mutex_unlock(&devlink_port_mutex);
143			mutex_unlock(&devlink_mutex);
144			return PTR_ERR(devlink_port);
145		}
146		info->user_ptr[1] = devlink_port;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147	}
148	return 0;
 
 
 
 
 
149}
150
151static void devlink_nl_post_doit(const struct genl_ops *ops,
152				 struct sk_buff *skb, struct genl_info *info)
153{
154	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
155		mutex_unlock(&devlink_port_mutex);
156	mutex_unlock(&devlink_mutex);
 
 
 
 
 
 
 
157}
158
159static struct genl_family devlink_nl_family = {
160	.id		= GENL_ID_GENERATE,
161	.name		= DEVLINK_GENL_NAME,
162	.version	= DEVLINK_GENL_VERSION,
163	.maxattr	= DEVLINK_ATTR_MAX,
164	.netnsok	= true,
165	.pre_doit	= devlink_nl_pre_doit,
166	.post_doit	= devlink_nl_post_doit,
167};
168
169enum devlink_multicast_groups {
170	DEVLINK_MCGRP_CONFIG,
171};
172
173static const struct genl_multicast_group devlink_nl_mcgrps[] = {
174	[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
175};
176
177static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
178{
179	if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
180		return -EMSGSIZE;
181	if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
182		return -EMSGSIZE;
183	return 0;
184}
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
187			   enum devlink_command cmd, u32 portid,
188			   u32 seq, int flags)
189{
 
190	void *hdr;
191
192	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
193	if (!hdr)
194		return -EMSGSIZE;
195
196	if (devlink_nl_put_handle(msg, devlink))
197		goto nla_put_failure;
 
 
 
 
 
 
198
 
 
 
 
 
 
199	genlmsg_end(msg, hdr);
200	return 0;
201
 
 
202nla_put_failure:
203	genlmsg_cancel(msg, hdr);
204	return -EMSGSIZE;
205}
206
207static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
208{
209	struct sk_buff *msg;
210	int err;
211
212	WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
 
213
214	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
215	if (!msg)
216		return;
217
218	err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
219	if (err) {
220		nlmsg_free(msg);
221		return;
222	}
223
224	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
225				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
226}
227
228static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229				struct devlink_port *devlink_port,
230				enum devlink_command cmd, u32 portid,
231				u32 seq, int flags)
232{
 
233	void *hdr;
234
235	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
236	if (!hdr)
237		return -EMSGSIZE;
238
239	if (devlink_nl_put_handle(msg, devlink))
240		goto nla_put_failure;
241	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
242		goto nla_put_failure;
 
 
243	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
244		goto nla_put_failure;
245	if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
246	    nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
247			devlink_port->desired_type))
248		goto nla_put_failure;
249	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
250		struct net_device *netdev = devlink_port->type_dev;
251
252		if (netdev &&
253		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
254				 netdev->ifindex) ||
255		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
256				    netdev->name)))
257			goto nla_put_failure;
258	}
259	if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
260		struct ib_device *ibdev = devlink_port->type_dev;
261
262		if (ibdev &&
263		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
264				   ibdev->name))
265			goto nla_put_failure;
266	}
267	if (devlink_port->split &&
268	    nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
269			devlink_port->split_group))
 
 
 
 
 
270		goto nla_put_failure;
271
272	genlmsg_end(msg, hdr);
273	return 0;
274
 
 
275nla_put_failure:
276	genlmsg_cancel(msg, hdr);
277	return -EMSGSIZE;
278}
279
280static void devlink_port_notify(struct devlink_port *devlink_port,
281				enum devlink_command cmd)
282{
283	struct devlink *devlink = devlink_port->devlink;
284	struct sk_buff *msg;
285	int err;
286
287	if (!devlink_port->registered)
 
 
288		return;
289
290	WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
292	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
293	if (!msg)
294		return;
295
296	err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
297	if (err) {
298		nlmsg_free(msg);
299		return;
300	}
301
302	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
303				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304}
305
306static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
307{
308	struct devlink *devlink = info->user_ptr[0];
309	struct sk_buff *msg;
310	int err;
311
312	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
313	if (!msg)
314		return -ENOMEM;
315
316	err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
317			      info->snd_portid, info->snd_seq, 0);
318	if (err) {
319		nlmsg_free(msg);
320		return err;
321	}
322
323	return genlmsg_reply(msg, info);
324}
325
326static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
327				     struct netlink_callback *cb)
328{
329	struct devlink *devlink;
330	int start = cb->args[0];
 
331	int idx = 0;
332	int err;
333
334	mutex_lock(&devlink_mutex);
335	list_for_each_entry(devlink, &devlink_list, list) {
336		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
337			continue;
338		if (idx < start) {
339			idx++;
 
340			continue;
341		}
 
 
342		err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
343				      NETLINK_CB(cb->skb).portid,
344				      cb->nlh->nlmsg_seq, NLM_F_MULTI);
 
 
 
345		if (err)
346			goto out;
347		idx++;
348	}
349out:
350	mutex_unlock(&devlink_mutex);
351
352	cb->args[0] = idx;
353	return msg->len;
354}
355
356static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
357					struct genl_info *info)
358{
359	struct devlink *devlink = info->user_ptr[0];
360	struct devlink_port *devlink_port = info->user_ptr[1];
361	struct sk_buff *msg;
362	int err;
363
364	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
365	if (!msg)
366		return -ENOMEM;
367
368	err = devlink_nl_port_fill(msg, devlink, devlink_port,
369				   DEVLINK_CMD_PORT_NEW,
370				   info->snd_portid, info->snd_seq, 0);
371	if (err) {
372		nlmsg_free(msg);
373		return err;
374	}
375
376	return genlmsg_reply(msg, info);
377}
378
379static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
380					  struct netlink_callback *cb)
381{
382	struct devlink *devlink;
383	struct devlink_port *devlink_port;
 
384	int start = cb->args[0];
385	int idx = 0;
386	int err;
387
388	mutex_lock(&devlink_mutex);
389	mutex_lock(&devlink_port_mutex);
390	list_for_each_entry(devlink, &devlink_list, list) {
391		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
392			continue;
393		list_for_each_entry(devlink_port, &devlink->port_list, list) {
394			if (idx < start) {
395				idx++;
396				continue;
397			}
398			err = devlink_nl_port_fill(msg, devlink, devlink_port,
399						   DEVLINK_CMD_NEW,
400						   NETLINK_CB(cb->skb).portid,
401						   cb->nlh->nlmsg_seq,
402						   NLM_F_MULTI);
403			if (err)
 
 
404				goto out;
 
405			idx++;
406		}
 
 
407	}
408out:
409	mutex_unlock(&devlink_port_mutex);
410	mutex_unlock(&devlink_mutex);
411
412	cb->args[0] = idx;
413	return msg->len;
414}
415
416static int devlink_port_type_set(struct devlink *devlink,
417				 struct devlink_port *devlink_port,
418				 enum devlink_port_type port_type)
419
420{
421	int err;
422
423	if (devlink->ops && devlink->ops->port_type_set) {
424		if (port_type == DEVLINK_PORT_TYPE_NOTSET)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425			return -EINVAL;
426		err = devlink->ops->port_type_set(devlink_port, port_type);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427		if (err)
428			return err;
429		devlink_port->desired_type = port_type;
430		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
431		return 0;
432	}
433	return -EOPNOTSUPP;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434}
435
436static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
437					struct genl_info *info)
438{
439	struct devlink *devlink = info->user_ptr[0];
440	struct devlink_port *devlink_port = info->user_ptr[1];
441	int err;
442
443	if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
444		enum devlink_port_type port_type;
445
446		port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
447		err = devlink_port_type_set(devlink, devlink_port, port_type);
448		if (err)
449			return err;
450	}
451	return 0;
452}
453
454static int devlink_port_split(struct devlink *devlink,
455			      u32 port_index, u32 count)
 
456
457{
458	if (devlink->ops && devlink->ops->port_split)
459		return devlink->ops->port_split(devlink, port_index, count);
460	return -EOPNOTSUPP;
 
 
461}
462
463static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
464					  struct genl_info *info)
465{
 
466	struct devlink *devlink = info->user_ptr[0];
467	u32 port_index;
468	u32 count;
469
470	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
471	    !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
472		return -EINVAL;
 
 
473
474	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
475	count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
476	return devlink_port_split(devlink, port_index, count);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477}
478
479static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
 
 
 
 
481{
482	if (devlink->ops && devlink->ops->port_unsplit)
483		return devlink->ops->port_unsplit(devlink, port_index);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484	return -EOPNOTSUPP;
485}
486
487static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488					    struct genl_info *info)
489{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490	struct devlink *devlink = info->user_ptr[0];
491	u32 port_index;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
493	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494		return -EINVAL;
 
 
 
 
 
 
495
496	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
497	return devlink_port_unsplit(devlink, port_index);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498}
499
500static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
 
 
501	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
502	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
503	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
504	[DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
 
505	[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506};
507
508static const struct genl_ops devlink_nl_ops[] = {
509	{
510		.cmd = DEVLINK_CMD_GET,
 
511		.doit = devlink_nl_cmd_get_doit,
512		.dumpit = devlink_nl_cmd_get_dumpit,
513		.policy = devlink_nl_policy,
514		/* can be retrieved by unprivileged users */
515	},
516	{
517		.cmd = DEVLINK_CMD_PORT_GET,
 
518		.doit = devlink_nl_cmd_port_get_doit,
519		.dumpit = devlink_nl_cmd_port_get_dumpit,
520		.policy = devlink_nl_policy,
521		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
522		/* can be retrieved by unprivileged users */
523	},
524	{
525		.cmd = DEVLINK_CMD_PORT_SET,
 
526		.doit = devlink_nl_cmd_port_set_doit,
527		.policy = devlink_nl_policy,
528		.flags = GENL_ADMIN_PERM,
529		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
530	},
531	{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
532		.cmd = DEVLINK_CMD_PORT_SPLIT,
 
533		.doit = devlink_nl_cmd_port_split_doit,
534		.policy = devlink_nl_policy,
535		.flags = GENL_ADMIN_PERM,
 
536	},
537	{
538		.cmd = DEVLINK_CMD_PORT_UNSPLIT,
 
539		.doit = devlink_nl_cmd_port_unsplit_doit,
540		.policy = devlink_nl_policy,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541		.flags = GENL_ADMIN_PERM,
542	},
543};
544
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545/**
546 *	devlink_alloc - Allocate new devlink instance resources
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547 *
548 *	@ops: ops
549 *	@priv_size: size of user private data
 
 
550 *
551 *	Allocate new devlink instance resources, including devlink index
552 *	and name.
553 */
554struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
 
 
555{
556	struct devlink *devlink;
 
 
 
 
 
 
557
558	devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
559	if (!devlink)
560		return NULL;
 
 
 
 
 
 
 
 
 
 
 
 
561	devlink->ops = ops;
562	devlink_net_set(devlink, &init_net);
563	INIT_LIST_HEAD(&devlink->port_list);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564	return devlink;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565}
566EXPORT_SYMBOL_GPL(devlink_alloc);
567
568/**
569 *	devlink_register - Register devlink instance
570 *
571 *	@devlink: devlink
572 */
573int devlink_register(struct devlink *devlink, struct device *dev)
574{
575	mutex_lock(&devlink_mutex);
576	devlink->dev = dev;
577	list_add_tail(&devlink->list, &devlink_list);
578	devlink_notify(devlink, DEVLINK_CMD_NEW);
579	mutex_unlock(&devlink_mutex);
580	return 0;
581}
582EXPORT_SYMBOL_GPL(devlink_register);
583
584/**
585 *	devlink_unregister - Unregister devlink instance
586 *
587 *	@devlink: devlink
588 */
589void devlink_unregister(struct devlink *devlink)
590{
591	mutex_lock(&devlink_mutex);
592	devlink_notify(devlink, DEVLINK_CMD_DEL);
593	list_del(&devlink->list);
594	mutex_unlock(&devlink_mutex);
 
 
 
 
 
 
595}
596EXPORT_SYMBOL_GPL(devlink_unregister);
597
598/**
599 *	devlink_free - Free devlink instance resources
600 *
601 *	@devlink: devlink
602 */
603void devlink_free(struct devlink *devlink)
604{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605	kfree(devlink);
606}
607EXPORT_SYMBOL_GPL(devlink_free);
608
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609/**
610 *	devlink_port_register - Register devlink port
611 *
612 *	@devlink: devlink
613 *	@devlink_port: devlink port
614 *	@port_index
615 *
616 *	Register devlink port with provided port index. User can use
617 *	any indexing, even hw-related one. devlink_port structure
618 *	is convenient to be embedded inside user driver private structure.
619 *	Note that the caller should take care of zeroing the devlink_port
620 *	structure.
 
 
621 */
622int devlink_port_register(struct devlink *devlink,
623			  struct devlink_port *devlink_port,
624			  unsigned int port_index)
625{
626	mutex_lock(&devlink_port_mutex);
627	if (devlink_port_index_exists(devlink, port_index)) {
628		mutex_unlock(&devlink_port_mutex);
629		return -EEXIST;
630	}
631	devlink_port->devlink = devlink;
632	devlink_port->index = port_index;
633	devlink_port->type = DEVLINK_PORT_TYPE_NOTSET;
634	devlink_port->registered = true;
635	list_add_tail(&devlink_port->list, &devlink->port_list);
636	mutex_unlock(&devlink_port_mutex);
637	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
638	return 0;
639}
640EXPORT_SYMBOL_GPL(devlink_port_register);
641
642/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643 *	devlink_port_unregister - Unregister devlink port
644 *
645 *	@devlink_port: devlink port
 
 
646 */
647void devlink_port_unregister(struct devlink_port *devlink_port)
648{
649	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
650	mutex_lock(&devlink_port_mutex);
651	list_del(&devlink_port->list);
652	mutex_unlock(&devlink_port_mutex);
 
653}
654EXPORT_SYMBOL_GPL(devlink_port_unregister);
655
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656static void __devlink_port_type_set(struct devlink_port *devlink_port,
657				    enum devlink_port_type type,
658				    void *type_dev)
659{
 
 
 
 
 
 
 
 
 
 
 
 
 
660	devlink_port->type = type;
661	devlink_port->type_dev = type_dev;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
663}
664
665/**
666 *	devlink_port_type_eth_set - Set port type to Ethernet
667 *
668 *	@devlink_port: devlink port
669 *	@netdev: related netdevice
 
670 */
671void devlink_port_type_eth_set(struct devlink_port *devlink_port,
672			       struct net_device *netdev)
673{
674	return __devlink_port_type_set(devlink_port,
675				       DEVLINK_PORT_TYPE_ETH, netdev);
 
 
676}
677EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
678
679/**
680 *	devlink_port_type_ib_set - Set port type to InfiniBand
681 *
682 *	@devlink_port: devlink port
683 *	@ibdev: related IB device
684 */
685void devlink_port_type_ib_set(struct devlink_port *devlink_port,
686			      struct ib_device *ibdev)
687{
688	return __devlink_port_type_set(devlink_port,
689				       DEVLINK_PORT_TYPE_IB, ibdev);
690}
691EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
692
693/**
694 *	devlink_port_type_clear - Clear port type
695 *
696 *	@devlink_port: devlink port
 
 
 
697 */
698void devlink_port_type_clear(struct devlink_port *devlink_port)
699{
700	return __devlink_port_type_set(devlink_port,
701				       DEVLINK_PORT_TYPE_NOTSET, NULL);
 
 
 
702}
703EXPORT_SYMBOL_GPL(devlink_port_type_clear);
704
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
705/**
706 *	devlink_port_split_set - Set port is split
707 *
708 *	@devlink_port: devlink port
709 *	@split_group: split group - identifies group split port is part of
710 */
711void devlink_port_split_set(struct devlink_port *devlink_port,
712			    u32 split_group)
713{
714	devlink_port->split = true;
715	devlink_port->split_group = split_group;
716	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717}
718EXPORT_SYMBOL_GPL(devlink_port_split_set);
719
720static int __init devlink_module_init(void)
 
721{
722	return genl_register_family_with_ops_groups(&devlink_nl_family,
723						    devlink_nl_ops,
724						    devlink_nl_mcgrps);
 
 
 
 
 
 
 
 
 
725}
726
727static void __exit devlink_module_exit(void)
 
728{
729	genl_unregister_family(&devlink_nl_family);
 
 
 
 
 
 
 
 
730}
731
732module_init(devlink_module_init);
733module_exit(devlink_module_exit);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
734
735MODULE_LICENSE("GPL v2");
736MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
737MODULE_DESCRIPTION("Network physical device Netlink interface");
738MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);
v6.2
    1// SPDX-License-Identifier: GPL-2.0-or-later
    2/*
    3 * net/core/devlink.c - Network physical/parent device Netlink interface
    4 *
    5 * Heavily inspired by net/wireless/
    6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
    7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
 
 
 
 
 
    8 */
    9
   10#include <linux/etherdevice.h>
   11#include <linux/kernel.h>
   12#include <linux/module.h>
   13#include <linux/types.h>
   14#include <linux/slab.h>
   15#include <linux/gfp.h>
   16#include <linux/device.h>
   17#include <linux/list.h>
   18#include <linux/netdevice.h>
   19#include <linux/spinlock.h>
   20#include <linux/refcount.h>
   21#include <linux/workqueue.h>
   22#include <linux/u64_stats_sync.h>
   23#include <linux/timekeeping.h>
   24#include <rdma/ib_verbs.h>
   25#include <net/netlink.h>
   26#include <net/genetlink.h>
   27#include <net/rtnetlink.h>
   28#include <net/net_namespace.h>
   29#include <net/sock.h>
   30#include <net/devlink.h>
   31#define CREATE_TRACE_POINTS
   32#include <trace/events/devlink.h>
   33
   34#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
   35	(__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
   36
   37struct devlink_dev_stats {
   38	u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
   39	u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
   40};
   41
   42struct devlink {
   43	u32 index;
   44	struct xarray ports;
   45	struct list_head rate_list;
   46	struct list_head sb_list;
   47	struct list_head dpipe_table_list;
   48	struct list_head resource_list;
   49	struct list_head param_list;
   50	struct list_head region_list;
   51	struct list_head reporter_list;
   52	struct mutex reporters_lock; /* protects reporter_list */
   53	struct devlink_dpipe_headers *dpipe_headers;
   54	struct list_head trap_list;
   55	struct list_head trap_group_list;
   56	struct list_head trap_policer_list;
   57	struct list_head linecard_list;
   58	struct mutex linecards_lock; /* protects linecard_list */
   59	const struct devlink_ops *ops;
   60	u64 features;
   61	struct xarray snapshot_ids;
   62	struct devlink_dev_stats stats;
   63	struct device *dev;
   64	possible_net_t _net;
   65	/* Serializes access to devlink instance specific objects such as
   66	 * port, sb, dpipe, resource, params, region, traps and more.
   67	 */
   68	struct mutex lock;
   69	struct lock_class_key lock_key;
   70	u8 reload_failed:1;
   71	refcount_t refcount;
   72	struct completion comp;
   73	struct rcu_head rcu;
   74	struct notifier_block netdevice_nb;
   75	char priv[] __aligned(NETDEV_ALIGN);
   76};
   77
   78struct devlink_linecard_ops;
   79struct devlink_linecard_type;
   80
   81struct devlink_linecard {
   82	struct list_head list;
   83	struct devlink *devlink;
   84	unsigned int index;
   85	refcount_t refcount;
   86	const struct devlink_linecard_ops *ops;
   87	void *priv;
   88	enum devlink_linecard_state state;
   89	struct mutex state_lock; /* Protects state */
   90	const char *type;
   91	struct devlink_linecard_type *types;
   92	unsigned int types_count;
   93	struct devlink *nested_devlink;
   94};
   95
   96/**
   97 * struct devlink_resource - devlink resource
   98 * @name: name of the resource
   99 * @id: id, per devlink instance
  100 * @size: size of the resource
  101 * @size_new: updated size of the resource, reload is needed
  102 * @size_valid: valid in case the total size of the resource is valid
  103 *              including its children
  104 * @parent: parent resource
  105 * @size_params: size parameters
  106 * @list: parent list
  107 * @resource_list: list of child resources
  108 * @occ_get: occupancy getter callback
  109 * @occ_get_priv: occupancy getter callback priv
  110 */
  111struct devlink_resource {
  112	const char *name;
  113	u64 id;
  114	u64 size;
  115	u64 size_new;
  116	bool size_valid;
  117	struct devlink_resource *parent;
  118	struct devlink_resource_size_params size_params;
  119	struct list_head list;
  120	struct list_head resource_list;
  121	devlink_resource_occ_get_t *occ_get;
  122	void *occ_get_priv;
  123};
  124
  125void *devlink_priv(struct devlink *devlink)
  126{
  127	return &devlink->priv;
  128}
  129EXPORT_SYMBOL_GPL(devlink_priv);
  130
  131struct devlink *priv_to_devlink(void *priv)
  132{
  133	return container_of(priv, struct devlink, priv);
  134}
  135EXPORT_SYMBOL_GPL(priv_to_devlink);
  136
  137struct device *devlink_to_dev(const struct devlink *devlink)
  138{
  139	return devlink->dev;
  140}
  141EXPORT_SYMBOL_GPL(devlink_to_dev);
  142
  143static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
  144	{
  145		.name = "destination mac",
  146		.id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
  147		.bitwidth = 48,
  148	},
  149};
  150
  151struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
  152	.name = "ethernet",
  153	.id = DEVLINK_DPIPE_HEADER_ETHERNET,
  154	.fields = devlink_dpipe_fields_ethernet,
  155	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
  156	.global = true,
  157};
  158EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
  159
  160static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
  161	{
  162		.name = "destination ip",
  163		.id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
  164		.bitwidth = 32,
  165	},
  166};
  167
  168struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
  169	.name = "ipv4",
  170	.id = DEVLINK_DPIPE_HEADER_IPV4,
  171	.fields = devlink_dpipe_fields_ipv4,
  172	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
  173	.global = true,
  174};
  175EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
  176
  177static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
  178	{
  179		.name = "destination ip",
  180		.id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
  181		.bitwidth = 128,
  182	},
  183};
  184
  185struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
  186	.name = "ipv6",
  187	.id = DEVLINK_DPIPE_HEADER_IPV6,
  188	.fields = devlink_dpipe_fields_ipv6,
  189	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
  190	.global = true,
  191};
  192EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
  193
  194EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
  195EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
  196EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
  197
  198#define DEVLINK_PORT_FN_CAPS_VALID_MASK \
  199	(_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1)
  200
  201static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
  202	[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
  203	[DEVLINK_PORT_FN_ATTR_STATE] =
  204		NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
  205				 DEVLINK_PORT_FN_STATE_ACTIVE),
  206	[DEVLINK_PORT_FN_ATTR_CAPS] =
  207		NLA_POLICY_BITFIELD32(DEVLINK_PORT_FN_CAPS_VALID_MASK),
  208};
  209
  210static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = {
  211	[DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG },
  212};
  213
  214static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
  215#define DEVLINK_REGISTERED XA_MARK_1
  216#define DEVLINK_UNREGISTERING XA_MARK_2
  217
  218/* devlink instances are open to the access from the user space after
  219 * devlink_register() call. Such logical barrier allows us to have certain
  220 * expectations related to locking.
  221 *
  222 * Before *_register() - we are in initialization stage and no parallel
  223 * access possible to the devlink instance. All drivers perform that phase
  224 * by implicitly holding device_lock.
  225 *
  226 * After *_register() - users and driver can access devlink instance at
  227 * the same time.
  228 */
  229#define ASSERT_DEVLINK_REGISTERED(d)                                           \
  230	WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
  231#define ASSERT_DEVLINK_NOT_REGISTERED(d)                                       \
  232	WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
  233
  234struct net *devlink_net(const struct devlink *devlink)
  235{
  236	return read_pnet(&devlink->_net);
  237}
  238EXPORT_SYMBOL_GPL(devlink_net);
  239
  240static void __devlink_put_rcu(struct rcu_head *head)
  241{
  242	struct devlink *devlink = container_of(head, struct devlink, rcu);
  243
  244	complete(&devlink->comp);
  245}
  246
  247void devlink_put(struct devlink *devlink)
  248{
  249	if (refcount_dec_and_test(&devlink->refcount))
  250		/* Make sure unregister operation that may await the completion
  251		 * is unblocked only after all users are after the end of
  252		 * RCU grace period.
  253		 */
  254		call_rcu(&devlink->rcu, __devlink_put_rcu);
  255}
  256
  257struct devlink *__must_check devlink_try_get(struct devlink *devlink)
  258{
  259	if (refcount_inc_not_zero(&devlink->refcount))
  260		return devlink;
  261	return NULL;
  262}
  263
  264void devl_assert_locked(struct devlink *devlink)
  265{
  266	lockdep_assert_held(&devlink->lock);
  267}
  268EXPORT_SYMBOL_GPL(devl_assert_locked);
  269
  270#ifdef CONFIG_LOCKDEP
  271/* For use in conjunction with LOCKDEP only e.g. rcu_dereference_protected() */
  272bool devl_lock_is_held(struct devlink *devlink)
  273{
  274	return lockdep_is_held(&devlink->lock);
  275}
  276EXPORT_SYMBOL_GPL(devl_lock_is_held);
  277#endif
  278
  279void devl_lock(struct devlink *devlink)
  280{
  281	mutex_lock(&devlink->lock);
  282}
  283EXPORT_SYMBOL_GPL(devl_lock);
  284
  285int devl_trylock(struct devlink *devlink)
  286{
  287	return mutex_trylock(&devlink->lock);
  288}
  289EXPORT_SYMBOL_GPL(devl_trylock);
  290
  291void devl_unlock(struct devlink *devlink)
  292{
  293	mutex_unlock(&devlink->lock);
  294}
  295EXPORT_SYMBOL_GPL(devl_unlock);
  296
  297static struct devlink *
  298devlinks_xa_find_get(struct net *net, unsigned long *indexp, xa_mark_t filter,
  299		     void * (*xa_find_fn)(struct xarray *, unsigned long *,
  300					  unsigned long, xa_mark_t))
  301{
  302	struct devlink *devlink;
  303
  304	rcu_read_lock();
  305retry:
  306	devlink = xa_find_fn(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED);
  307	if (!devlink)
  308		goto unlock;
  309
  310	/* In case devlink_unregister() was already called and "unregistering"
  311	 * mark was set, do not allow to get a devlink reference here.
  312	 * This prevents live-lock of devlink_unregister() wait for completion.
  313	 */
  314	if (xa_get_mark(&devlinks, *indexp, DEVLINK_UNREGISTERING))
  315		goto retry;
  316
  317	/* For a possible retry, the xa_find_after() should be always used */
  318	xa_find_fn = xa_find_after;
  319	if (!devlink_try_get(devlink))
  320		goto retry;
  321	if (!net_eq(devlink_net(devlink), net)) {
  322		devlink_put(devlink);
  323		goto retry;
  324	}
  325unlock:
  326	rcu_read_unlock();
  327	return devlink;
  328}
  329
  330static struct devlink *devlinks_xa_find_get_first(struct net *net,
  331						  unsigned long *indexp,
  332						  xa_mark_t filter)
  333{
  334	return devlinks_xa_find_get(net, indexp, filter, xa_find);
  335}
  336
  337static struct devlink *devlinks_xa_find_get_next(struct net *net,
  338						 unsigned long *indexp,
  339						 xa_mark_t filter)
  340{
  341	return devlinks_xa_find_get(net, indexp, filter, xa_find_after);
  342}
  343
  344/* Iterate over devlink pointers which were possible to get reference to.
  345 * devlink_put() needs to be called for each iterated devlink pointer
  346 * in loop body in order to release the reference.
  347 */
  348#define devlinks_xa_for_each_get(net, index, devlink, filter)			\
  349	for (index = 0,								\
  350	     devlink = devlinks_xa_find_get_first(net, &index, filter);		\
  351	     devlink; devlink = devlinks_xa_find_get_next(net, &index, filter))
  352
  353#define devlinks_xa_for_each_registered_get(net, index, devlink)		\
  354	devlinks_xa_for_each_get(net, index, devlink, DEVLINK_REGISTERED)
  355
  356static struct devlink *devlink_get_from_attrs(struct net *net,
  357					      struct nlattr **attrs)
  358{
  359	struct devlink *devlink;
  360	unsigned long index;
  361	char *busname;
  362	char *devname;
  363
  364	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
  365		return ERR_PTR(-EINVAL);
  366
  367	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
  368	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
  369
  370	devlinks_xa_for_each_registered_get(net, index, devlink) {
  371		if (strcmp(devlink->dev->bus->name, busname) == 0 &&
  372		    strcmp(dev_name(devlink->dev), devname) == 0)
 
  373			return devlink;
  374		devlink_put(devlink);
  375	}
  376
  377	return ERR_PTR(-ENODEV);
  378}
  379
  380#define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port)				\
  381	WARN_ON_ONCE(!(devlink_port)->registered)
  382#define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port)			\
  383	WARN_ON_ONCE((devlink_port)->registered)
  384#define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port)				\
  385	WARN_ON_ONCE(!(devlink_port)->initialized)
  386
  387static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
  388						      unsigned int port_index)
 
 
 
 
 
 
 
 
 
 
 
  389{
  390	return xa_load(&devlink->ports, port_index);
  391}
  392
  393static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
  394							struct nlattr **attrs)
  395{
  396	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
  397		u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
  398		struct devlink_port *devlink_port;
  399
  400		devlink_port = devlink_port_get_by_index(devlink, port_index);
  401		if (!devlink_port)
  402			return ERR_PTR(-ENODEV);
  403		return devlink_port;
  404	}
  405	return ERR_PTR(-EINVAL);
  406}
  407
  408static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
  409						       struct genl_info *info)
  410{
  411	return devlink_port_get_from_attrs(devlink, info->attrs);
  412}
  413
  414static inline bool
  415devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
  416{
  417	return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
  418}
  419
  420static inline bool
  421devlink_rate_is_node(struct devlink_rate *devlink_rate)
  422{
  423	return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
  424}
  425
  426static struct devlink_rate *
  427devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
  428{
  429	struct devlink_rate *devlink_rate;
  430	struct devlink_port *devlink_port;
  431
  432	devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
  433	if (IS_ERR(devlink_port))
  434		return ERR_CAST(devlink_port);
  435	devlink_rate = devlink_port->devlink_rate;
  436	return devlink_rate ?: ERR_PTR(-ENODEV);
  437}
  438
  439static struct devlink_rate *
  440devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
  441{
  442	static struct devlink_rate *devlink_rate;
  443
  444	list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
  445		if (devlink_rate_is_node(devlink_rate) &&
  446		    !strcmp(node_name, devlink_rate->name))
  447			return devlink_rate;
  448	}
  449	return ERR_PTR(-ENODEV);
  450}
  451
  452static struct devlink_rate *
  453devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
  454{
  455	const char *rate_node_name;
  456	size_t len;
  457
  458	if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
  459		return ERR_PTR(-EINVAL);
  460	rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
  461	len = strlen(rate_node_name);
  462	/* Name cannot be empty or decimal number */
  463	if (!len || strspn(rate_node_name, "0123456789") == len)
  464		return ERR_PTR(-EINVAL);
  465
  466	return devlink_rate_node_get_by_name(devlink, rate_node_name);
  467}
  468
  469static struct devlink_rate *
  470devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
  471{
  472	return devlink_rate_node_get_from_attrs(devlink, info->attrs);
  473}
  474
  475static struct devlink_rate *
  476devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
  477{
  478	struct nlattr **attrs = info->attrs;
  479
  480	if (attrs[DEVLINK_ATTR_PORT_INDEX])
  481		return devlink_rate_leaf_get_from_info(devlink, info);
  482	else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
  483		return devlink_rate_node_get_from_info(devlink, info);
  484	else
  485		return ERR_PTR(-EINVAL);
  486}
  487
  488static struct devlink_linecard *
  489devlink_linecard_get_by_index(struct devlink *devlink,
  490			      unsigned int linecard_index)
  491{
  492	struct devlink_linecard *devlink_linecard;
  493
  494	list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
  495		if (devlink_linecard->index == linecard_index)
  496			return devlink_linecard;
  497	}
  498	return NULL;
  499}
  500
  501static bool devlink_linecard_index_exists(struct devlink *devlink,
  502					  unsigned int linecard_index)
  503{
  504	return devlink_linecard_get_by_index(devlink, linecard_index);
  505}
  506
  507static struct devlink_linecard *
  508devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
  509{
  510	if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
  511		u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
  512		struct devlink_linecard *linecard;
  513
  514		mutex_lock(&devlink->linecards_lock);
  515		linecard = devlink_linecard_get_by_index(devlink, linecard_index);
  516		if (linecard)
  517			refcount_inc(&linecard->refcount);
  518		mutex_unlock(&devlink->linecards_lock);
  519		if (!linecard)
  520			return ERR_PTR(-ENODEV);
  521		return linecard;
  522	}
  523	return ERR_PTR(-EINVAL);
  524}
  525
  526static struct devlink_linecard *
  527devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
  528{
  529	return devlink_linecard_get_from_attrs(devlink, info->attrs);
  530}
  531
  532static void devlink_linecard_put(struct devlink_linecard *linecard)
  533{
  534	if (refcount_dec_and_test(&linecard->refcount)) {
  535		mutex_destroy(&linecard->state_lock);
  536		kfree(linecard);
  537	}
  538}
  539
  540struct devlink_sb {
  541	struct list_head list;
  542	unsigned int index;
  543	u32 size;
  544	u16 ingress_pools_count;
  545	u16 egress_pools_count;
  546	u16 ingress_tc_count;
  547	u16 egress_tc_count;
  548};
  549
  550static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
  551{
  552	return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
  553}
  554
  555static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
  556						  unsigned int sb_index)
  557{
  558	struct devlink_sb *devlink_sb;
  559
  560	list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  561		if (devlink_sb->index == sb_index)
  562			return devlink_sb;
  563	}
  564	return NULL;
  565}
  566
  567static bool devlink_sb_index_exists(struct devlink *devlink,
  568				    unsigned int sb_index)
  569{
  570	return devlink_sb_get_by_index(devlink, sb_index);
  571}
  572
  573static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
  574						    struct nlattr **attrs)
  575{
  576	if (attrs[DEVLINK_ATTR_SB_INDEX]) {
  577		u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
  578		struct devlink_sb *devlink_sb;
  579
  580		devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
  581		if (!devlink_sb)
  582			return ERR_PTR(-ENODEV);
  583		return devlink_sb;
  584	}
  585	return ERR_PTR(-EINVAL);
  586}
  587
  588static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
  589						   struct genl_info *info)
  590{
  591	return devlink_sb_get_from_attrs(devlink, info->attrs);
  592}
  593
  594static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
  595						struct nlattr **attrs,
  596						u16 *p_pool_index)
  597{
  598	u16 val;
  599
  600	if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
  601		return -EINVAL;
  602
  603	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
  604	if (val >= devlink_sb_pool_count(devlink_sb))
  605		return -EINVAL;
  606	*p_pool_index = val;
  607	return 0;
  608}
  609
  610static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
  611					       struct genl_info *info,
  612					       u16 *p_pool_index)
  613{
  614	return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
  615						    p_pool_index);
  616}
  617
  618static int
  619devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
  620				    enum devlink_sb_pool_type *p_pool_type)
  621{
  622	u8 val;
  623
  624	if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
  625		return -EINVAL;
  626
  627	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
  628	if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
  629	    val != DEVLINK_SB_POOL_TYPE_EGRESS)
  630		return -EINVAL;
  631	*p_pool_type = val;
  632	return 0;
  633}
  634
  635static int
  636devlink_sb_pool_type_get_from_info(struct genl_info *info,
  637				   enum devlink_sb_pool_type *p_pool_type)
  638{
  639	return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
  640}
  641
  642static int
  643devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
  644				  enum devlink_sb_threshold_type *p_th_type)
  645{
  646	u8 val;
  647
  648	if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
  649		return -EINVAL;
  650
  651	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
  652	if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
  653	    val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
  654		return -EINVAL;
  655	*p_th_type = val;
  656	return 0;
  657}
  658
  659static int
  660devlink_sb_th_type_get_from_info(struct genl_info *info,
  661				 enum devlink_sb_threshold_type *p_th_type)
  662{
  663	return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
  664}
  665
  666static int
  667devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
  668				   struct nlattr **attrs,
  669				   enum devlink_sb_pool_type pool_type,
  670				   u16 *p_tc_index)
  671{
  672	u16 val;
  673
  674	if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
  675		return -EINVAL;
  676
  677	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
  678	if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
  679	    val >= devlink_sb->ingress_tc_count)
  680		return -EINVAL;
  681	if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
  682	    val >= devlink_sb->egress_tc_count)
  683		return -EINVAL;
  684	*p_tc_index = val;
  685	return 0;
  686}
  687
  688static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
  689				     u32 cap, bool is_enable)
  690{
  691	caps->selector |= cap;
  692	if (is_enable)
  693		caps->value |= cap;
  694}
  695
  696static int devlink_port_fn_roce_fill(const struct devlink_ops *ops,
  697				     struct devlink_port *devlink_port,
  698				     struct nla_bitfield32 *caps,
  699				     struct netlink_ext_ack *extack)
  700{
  701	bool is_enable;
  702	int err;
  703
  704	if (!ops->port_fn_roce_get)
  705		return 0;
  706
  707	err = ops->port_fn_roce_get(devlink_port, &is_enable, extack);
  708	if (err) {
  709		if (err == -EOPNOTSUPP)
  710			return 0;
  711		return err;
  712	}
  713
  714	devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable);
  715	return 0;
  716}
  717
  718static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops,
  719					   struct devlink_port *devlink_port,
  720					   struct nla_bitfield32 *caps,
  721					   struct netlink_ext_ack *extack)
  722{
  723	bool is_enable;
  724	int err;
  725
  726	if (!ops->port_fn_migratable_get ||
  727	    devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
  728		return 0;
  729
  730	err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack);
  731	if (err) {
  732		if (err == -EOPNOTSUPP)
  733			return 0;
  734		return err;
  735	}
  736
  737	devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable);
  738	return 0;
  739}
  740
  741static int devlink_port_fn_caps_fill(const struct devlink_ops *ops,
  742				     struct devlink_port *devlink_port,
  743				     struct sk_buff *msg,
  744				     struct netlink_ext_ack *extack,
  745				     bool *msg_updated)
  746{
  747	struct nla_bitfield32 caps = {};
  748	int err;
  749
  750	err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack);
  751	if (err)
  752		return err;
  753
  754	err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack);
  755	if (err)
  756		return err;
  757
  758	if (!caps.selector)
  759		return 0;
  760	err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
  761				 caps.selector);
  762	if (err)
  763		return err;
  764
  765	*msg_updated = true;
  766	return 0;
  767}
  768
  769static int
  770devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
  771				  struct genl_info *info,
  772				  enum devlink_sb_pool_type pool_type,
  773				  u16 *p_tc_index)
  774{
  775	return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
  776						  pool_type, p_tc_index);
  777}
  778
  779struct devlink_region {
  780	struct devlink *devlink;
  781	struct devlink_port *port;
  782	struct list_head list;
  783	union {
  784		const struct devlink_region_ops *ops;
  785		const struct devlink_port_region_ops *port_ops;
  786	};
  787	struct mutex snapshot_lock; /* protects snapshot_list,
  788				     * max_snapshots and cur_snapshots
  789				     * consistency.
  790				     */
  791	struct list_head snapshot_list;
  792	u32 max_snapshots;
  793	u32 cur_snapshots;
  794	u64 size;
  795};
  796
  797struct devlink_snapshot {
  798	struct list_head list;
  799	struct devlink_region *region;
  800	u8 *data;
  801	u32 id;
  802};
  803
  804static struct devlink_region *
  805devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
  806{
  807	struct devlink_region *region;
  808
  809	list_for_each_entry(region, &devlink->region_list, list)
  810		if (!strcmp(region->ops->name, region_name))
  811			return region;
  812
  813	return NULL;
  814}
  815
  816static struct devlink_region *
  817devlink_port_region_get_by_name(struct devlink_port *port,
  818				const char *region_name)
  819{
  820	struct devlink_region *region;
  821
  822	list_for_each_entry(region, &port->region_list, list)
  823		if (!strcmp(region->ops->name, region_name))
  824			return region;
  825
  826	return NULL;
  827}
  828
  829static struct devlink_snapshot *
  830devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
  831{
  832	struct devlink_snapshot *snapshot;
  833
  834	list_for_each_entry(snapshot, &region->snapshot_list, list)
  835		if (snapshot->id == id)
  836			return snapshot;
  837
  838	return NULL;
  839}
  840
  841#define DEVLINK_NL_FLAG_NEED_PORT		BIT(0)
  842#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT	BIT(1)
  843#define DEVLINK_NL_FLAG_NEED_RATE		BIT(2)
  844#define DEVLINK_NL_FLAG_NEED_RATE_NODE		BIT(3)
  845#define DEVLINK_NL_FLAG_NEED_LINECARD		BIT(4)
  846
  847static int devlink_nl_pre_doit(const struct genl_split_ops *ops,
  848			       struct sk_buff *skb, struct genl_info *info)
  849{
  850	struct devlink_linecard *linecard;
  851	struct devlink_port *devlink_port;
  852	struct devlink *devlink;
  853	int err;
  854
  855	devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs);
  856	if (IS_ERR(devlink))
 
 
  857		return PTR_ERR(devlink);
  858	devl_lock(devlink);
  859	info->user_ptr[0] = devlink;
  860	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
 
 
 
  861		devlink_port = devlink_port_get_from_info(devlink, info);
  862		if (IS_ERR(devlink_port)) {
  863			err = PTR_ERR(devlink_port);
  864			goto unlock;
 
  865		}
  866		info->user_ptr[1] = devlink_port;
  867	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
  868		devlink_port = devlink_port_get_from_info(devlink, info);
  869		if (!IS_ERR(devlink_port))
  870			info->user_ptr[1] = devlink_port;
  871	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) {
  872		struct devlink_rate *devlink_rate;
  873
  874		devlink_rate = devlink_rate_get_from_info(devlink, info);
  875		if (IS_ERR(devlink_rate)) {
  876			err = PTR_ERR(devlink_rate);
  877			goto unlock;
  878		}
  879		info->user_ptr[1] = devlink_rate;
  880	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) {
  881		struct devlink_rate *rate_node;
  882
  883		rate_node = devlink_rate_node_get_from_info(devlink, info);
  884		if (IS_ERR(rate_node)) {
  885			err = PTR_ERR(rate_node);
  886			goto unlock;
  887		}
  888		info->user_ptr[1] = rate_node;
  889	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
  890		linecard = devlink_linecard_get_from_info(devlink, info);
  891		if (IS_ERR(linecard)) {
  892			err = PTR_ERR(linecard);
  893			goto unlock;
  894		}
  895		info->user_ptr[1] = linecard;
  896	}
  897	return 0;
  898
  899unlock:
  900	devl_unlock(devlink);
  901	devlink_put(devlink);
  902	return err;
  903}
  904
  905static void devlink_nl_post_doit(const struct genl_split_ops *ops,
  906				 struct sk_buff *skb, struct genl_info *info)
  907{
  908	struct devlink_linecard *linecard;
  909	struct devlink *devlink;
  910
  911	devlink = info->user_ptr[0];
  912	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
  913		linecard = info->user_ptr[1];
  914		devlink_linecard_put(linecard);
  915	}
  916	devl_unlock(devlink);
  917	devlink_put(devlink);
  918}
  919
  920static struct genl_family devlink_nl_family;
 
 
 
 
 
 
 
 
  921
  922enum devlink_multicast_groups {
  923	DEVLINK_MCGRP_CONFIG,
  924};
  925
  926static const struct genl_multicast_group devlink_nl_mcgrps[] = {
  927	[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
  928};
  929
  930static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
  931{
  932	if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
  933		return -EMSGSIZE;
  934	if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
  935		return -EMSGSIZE;
  936	return 0;
  937}
  938
  939static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
  940{
  941	struct nlattr *nested_attr;
  942
  943	nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
  944	if (!nested_attr)
  945		return -EMSGSIZE;
  946	if (devlink_nl_put_handle(msg, devlink))
  947		goto nla_put_failure;
  948
  949	nla_nest_end(msg, nested_attr);
  950	return 0;
  951
  952nla_put_failure:
  953	nla_nest_cancel(msg, nested_attr);
  954	return -EMSGSIZE;
  955}
  956
  957int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port)
  958{
  959	if (devlink_nl_put_handle(msg, devlink_port->devlink))
  960		return -EMSGSIZE;
  961	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  962		return -EMSGSIZE;
  963	return 0;
  964}
  965
  966size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
  967{
  968	struct devlink *devlink = devlink_port->devlink;
  969
  970	return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */
  971	     + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */
  972	     + nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */
  973}
  974
  975struct devlink_reload_combination {
  976	enum devlink_reload_action action;
  977	enum devlink_reload_limit limit;
  978};
  979
  980static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
  981	{
  982		/* can't reinitialize driver with no down time */
  983		.action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
  984		.limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
  985	},
  986};
  987
  988static bool
  989devlink_reload_combination_is_invalid(enum devlink_reload_action action,
  990				      enum devlink_reload_limit limit)
  991{
  992	int i;
  993
  994	for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
  995		if (devlink_reload_invalid_combinations[i].action == action &&
  996		    devlink_reload_invalid_combinations[i].limit == limit)
  997			return true;
  998	return false;
  999}
 1000
 1001static bool
 1002devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
 1003{
 1004	return test_bit(action, &devlink->ops->reload_actions);
 1005}
 1006
 1007static bool
 1008devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
 1009{
 1010	return test_bit(limit, &devlink->ops->reload_limits);
 1011}
 1012
 1013static int devlink_reload_stat_put(struct sk_buff *msg,
 1014				   enum devlink_reload_limit limit, u32 value)
 1015{
 1016	struct nlattr *reload_stats_entry;
 1017
 1018	reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
 1019	if (!reload_stats_entry)
 1020		return -EMSGSIZE;
 1021
 1022	if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
 1023	    nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
 1024		goto nla_put_failure;
 1025	nla_nest_end(msg, reload_stats_entry);
 1026	return 0;
 1027
 1028nla_put_failure:
 1029	nla_nest_cancel(msg, reload_stats_entry);
 1030	return -EMSGSIZE;
 1031}
 1032
 1033static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
 1034{
 1035	struct nlattr *reload_stats_attr, *act_info, *act_stats;
 1036	int i, j, stat_idx;
 1037	u32 value;
 1038
 1039	if (!is_remote)
 1040		reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
 1041	else
 1042		reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
 1043
 1044	if (!reload_stats_attr)
 1045		return -EMSGSIZE;
 1046
 1047	for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
 1048		if ((!is_remote &&
 1049		     !devlink_reload_action_is_supported(devlink, i)) ||
 1050		    i == DEVLINK_RELOAD_ACTION_UNSPEC)
 1051			continue;
 1052		act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
 1053		if (!act_info)
 1054			goto nla_put_failure;
 1055
 1056		if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
 1057			goto action_info_nest_cancel;
 1058		act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
 1059		if (!act_stats)
 1060			goto action_info_nest_cancel;
 1061
 1062		for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
 1063			/* Remote stats are shown even if not locally supported.
 1064			 * Stats of actions with unspecified limit are shown
 1065			 * though drivers don't need to register unspecified
 1066			 * limit.
 1067			 */
 1068			if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
 1069			     !devlink_reload_limit_is_supported(devlink, j)) ||
 1070			    devlink_reload_combination_is_invalid(i, j))
 1071				continue;
 1072
 1073			stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
 1074			if (!is_remote)
 1075				value = devlink->stats.reload_stats[stat_idx];
 1076			else
 1077				value = devlink->stats.remote_reload_stats[stat_idx];
 1078			if (devlink_reload_stat_put(msg, j, value))
 1079				goto action_stats_nest_cancel;
 1080		}
 1081		nla_nest_end(msg, act_stats);
 1082		nla_nest_end(msg, act_info);
 1083	}
 1084	nla_nest_end(msg, reload_stats_attr);
 1085	return 0;
 1086
 1087action_stats_nest_cancel:
 1088	nla_nest_cancel(msg, act_stats);
 1089action_info_nest_cancel:
 1090	nla_nest_cancel(msg, act_info);
 1091nla_put_failure:
 1092	nla_nest_cancel(msg, reload_stats_attr);
 1093	return -EMSGSIZE;
 1094}
 1095
 1096static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
 1097			   enum devlink_command cmd, u32 portid,
 1098			   u32 seq, int flags)
 1099{
 1100	struct nlattr *dev_stats;
 1101	void *hdr;
 1102
 1103	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 1104	if (!hdr)
 1105		return -EMSGSIZE;
 1106
 1107	if (devlink_nl_put_handle(msg, devlink))
 1108		goto nla_put_failure;
 1109	if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
 1110		goto nla_put_failure;
 1111
 1112	dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
 1113	if (!dev_stats)
 1114		goto nla_put_failure;
 1115
 1116	if (devlink_reload_stats_put(msg, devlink, false))
 1117		goto dev_stats_nest_cancel;
 1118	if (devlink_reload_stats_put(msg, devlink, true))
 1119		goto dev_stats_nest_cancel;
 1120
 1121	nla_nest_end(msg, dev_stats);
 1122	genlmsg_end(msg, hdr);
 1123	return 0;
 1124
 1125dev_stats_nest_cancel:
 1126	nla_nest_cancel(msg, dev_stats);
 1127nla_put_failure:
 1128	genlmsg_cancel(msg, hdr);
 1129	return -EMSGSIZE;
 1130}
 1131
 1132static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
 1133{
 1134	struct sk_buff *msg;
 1135	int err;
 1136
 1137	WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
 1138	WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
 1139
 1140	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1141	if (!msg)
 1142		return;
 1143
 1144	err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
 1145	if (err) {
 1146		nlmsg_free(msg);
 1147		return;
 1148	}
 1149
 1150	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 1151				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 1152}
 1153
 1154static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 1155				     struct devlink_port *devlink_port)
 1156{
 1157	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 1158
 1159	if (!devlink_port->attrs_set)
 1160		return 0;
 1161	if (attrs->lanes) {
 1162		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
 1163			return -EMSGSIZE;
 1164	}
 1165	if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
 1166		return -EMSGSIZE;
 1167	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
 1168		return -EMSGSIZE;
 1169	switch (devlink_port->attrs.flavour) {
 1170	case DEVLINK_PORT_FLAVOUR_PCI_PF:
 1171		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
 1172				attrs->pci_pf.controller) ||
 1173		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
 1174			return -EMSGSIZE;
 1175		if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
 1176			return -EMSGSIZE;
 1177		break;
 1178	case DEVLINK_PORT_FLAVOUR_PCI_VF:
 1179		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
 1180				attrs->pci_vf.controller) ||
 1181		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
 1182		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
 1183			return -EMSGSIZE;
 1184		if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
 1185			return -EMSGSIZE;
 1186		break;
 1187	case DEVLINK_PORT_FLAVOUR_PCI_SF:
 1188		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
 1189				attrs->pci_sf.controller) ||
 1190		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
 1191				attrs->pci_sf.pf) ||
 1192		    nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
 1193				attrs->pci_sf.sf))
 1194			return -EMSGSIZE;
 1195		break;
 1196	case DEVLINK_PORT_FLAVOUR_PHYSICAL:
 1197	case DEVLINK_PORT_FLAVOUR_CPU:
 1198	case DEVLINK_PORT_FLAVOUR_DSA:
 1199		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
 1200				attrs->phys.port_number))
 1201			return -EMSGSIZE;
 1202		if (!attrs->split)
 1203			return 0;
 1204		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
 1205				attrs->phys.port_number))
 1206			return -EMSGSIZE;
 1207		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
 1208				attrs->phys.split_subport_number))
 1209			return -EMSGSIZE;
 1210		break;
 1211	default:
 1212		break;
 1213	}
 1214	return 0;
 1215}
 1216
 1217static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
 1218					struct devlink_port *port,
 1219					struct sk_buff *msg,
 1220					struct netlink_ext_ack *extack,
 1221					bool *msg_updated)
 1222{
 1223	u8 hw_addr[MAX_ADDR_LEN];
 1224	int hw_addr_len;
 1225	int err;
 1226
 1227	if (!ops->port_function_hw_addr_get)
 1228		return 0;
 1229
 1230	err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
 1231					     extack);
 1232	if (err) {
 1233		if (err == -EOPNOTSUPP)
 1234			return 0;
 1235		return err;
 1236	}
 1237	err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
 1238	if (err)
 1239		return err;
 1240	*msg_updated = true;
 1241	return 0;
 1242}
 1243
 1244static int devlink_nl_rate_fill(struct sk_buff *msg,
 1245				struct devlink_rate *devlink_rate,
 1246				enum devlink_command cmd, u32 portid, u32 seq,
 1247				int flags, struct netlink_ext_ack *extack)
 1248{
 1249	struct devlink *devlink = devlink_rate->devlink;
 1250	void *hdr;
 1251
 1252	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 1253	if (!hdr)
 1254		return -EMSGSIZE;
 1255
 1256	if (devlink_nl_put_handle(msg, devlink))
 1257		goto nla_put_failure;
 1258
 1259	if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
 1260		goto nla_put_failure;
 1261
 1262	if (devlink_rate_is_leaf(devlink_rate)) {
 1263		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
 1264				devlink_rate->devlink_port->index))
 1265			goto nla_put_failure;
 1266	} else if (devlink_rate_is_node(devlink_rate)) {
 1267		if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
 1268				   devlink_rate->name))
 1269			goto nla_put_failure;
 1270	}
 1271
 1272	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
 1273			      devlink_rate->tx_share, DEVLINK_ATTR_PAD))
 1274		goto nla_put_failure;
 1275
 1276	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
 1277			      devlink_rate->tx_max, DEVLINK_ATTR_PAD))
 1278		goto nla_put_failure;
 1279
 1280	if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
 1281			devlink_rate->tx_priority))
 1282		goto nla_put_failure;
 1283
 1284	if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
 1285			devlink_rate->tx_weight))
 1286		goto nla_put_failure;
 1287
 1288	if (devlink_rate->parent)
 1289		if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
 1290				   devlink_rate->parent->name))
 1291			goto nla_put_failure;
 1292
 1293	genlmsg_end(msg, hdr);
 1294	return 0;
 1295
 1296nla_put_failure:
 1297	genlmsg_cancel(msg, hdr);
 1298	return -EMSGSIZE;
 1299}
 1300
 1301static bool
 1302devlink_port_fn_state_valid(enum devlink_port_fn_state state)
 1303{
 1304	return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
 1305	       state == DEVLINK_PORT_FN_STATE_ACTIVE;
 1306}
 1307
 1308static bool
 1309devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
 1310{
 1311	return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
 1312	       opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
 1313}
 1314
 1315static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
 1316				      struct devlink_port *port,
 1317				      struct sk_buff *msg,
 1318				      struct netlink_ext_ack *extack,
 1319				      bool *msg_updated)
 1320{
 1321	enum devlink_port_fn_opstate opstate;
 1322	enum devlink_port_fn_state state;
 1323	int err;
 1324
 1325	if (!ops->port_fn_state_get)
 1326		return 0;
 1327
 1328	err = ops->port_fn_state_get(port, &state, &opstate, extack);
 1329	if (err) {
 1330		if (err == -EOPNOTSUPP)
 1331			return 0;
 1332		return err;
 1333	}
 1334	if (!devlink_port_fn_state_valid(state)) {
 1335		WARN_ON_ONCE(1);
 1336		NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
 1337		return -EINVAL;
 1338	}
 1339	if (!devlink_port_fn_opstate_valid(opstate)) {
 1340		WARN_ON_ONCE(1);
 1341		NL_SET_ERR_MSG_MOD(extack,
 1342				   "Invalid operational state read from driver");
 1343		return -EINVAL;
 1344	}
 1345	if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
 1346	    nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
 1347		return -EMSGSIZE;
 1348	*msg_updated = true;
 1349	return 0;
 1350}
 1351
 1352static int
 1353devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
 1354			struct netlink_ext_ack *extack)
 1355{
 1356	const struct devlink_ops *ops = devlink_port->devlink->ops;
 1357
 1358	return ops->port_fn_migratable_set(devlink_port, enable, extack);
 1359}
 1360
 1361static int
 1362devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
 1363			 struct netlink_ext_ack *extack)
 1364{
 1365	const struct devlink_ops *ops = devlink_port->devlink->ops;
 1366
 1367	return ops->port_fn_roce_set(devlink_port, enable, extack);
 1368}
 1369
 1370static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
 1371				    const struct nlattr *attr,
 1372				    struct netlink_ext_ack *extack)
 1373{
 1374	struct nla_bitfield32 caps;
 1375	u32 caps_value;
 1376	int err;
 1377
 1378	caps = nla_get_bitfield32(attr);
 1379	caps_value = caps.value & caps.selector;
 1380	if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE) {
 1381		err = devlink_port_fn_roce_set(devlink_port,
 1382					       caps_value & DEVLINK_PORT_FN_CAP_ROCE,
 1383					       extack);
 1384		if (err)
 1385			return err;
 1386	}
 1387	if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
 1388		err = devlink_port_fn_mig_set(devlink_port, caps_value &
 1389					      DEVLINK_PORT_FN_CAP_MIGRATABLE,
 1390					      extack);
 1391		if (err)
 1392			return err;
 1393	}
 1394	return 0;
 1395}
 1396
 1397static int
 1398devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
 1399				   struct netlink_ext_ack *extack)
 1400{
 1401	const struct devlink_ops *ops;
 1402	struct nlattr *function_attr;
 1403	bool msg_updated = false;
 1404	int err;
 1405
 1406	function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
 1407	if (!function_attr)
 1408		return -EMSGSIZE;
 1409
 1410	ops = port->devlink->ops;
 1411	err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
 1412					   &msg_updated);
 1413	if (err)
 1414		goto out;
 1415	err = devlink_port_fn_caps_fill(ops, port, msg, extack,
 1416					&msg_updated);
 1417	if (err)
 1418		goto out;
 1419	err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
 1420out:
 1421	if (err || !msg_updated)
 1422		nla_nest_cancel(msg, function_attr);
 1423	else
 1424		nla_nest_end(msg, function_attr);
 1425	return err;
 1426}
 1427
 1428static int devlink_nl_port_fill(struct sk_buff *msg,
 1429				struct devlink_port *devlink_port,
 1430				enum devlink_command cmd, u32 portid, u32 seq,
 1431				int flags, struct netlink_ext_ack *extack)
 1432{
 1433	struct devlink *devlink = devlink_port->devlink;
 1434	void *hdr;
 1435
 1436	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 1437	if (!hdr)
 1438		return -EMSGSIZE;
 1439
 1440	if (devlink_nl_put_handle(msg, devlink))
 1441		goto nla_put_failure;
 1442	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 1443		goto nla_put_failure;
 1444
 1445	spin_lock_bh(&devlink_port->type_lock);
 1446	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
 1447		goto nla_put_failure_type_locked;
 1448	if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
 1449	    nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
 1450			devlink_port->desired_type))
 1451		goto nla_put_failure_type_locked;
 1452	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
 1453		if (devlink_port->type_eth.netdev &&
 
 
 1454		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
 1455				 devlink_port->type_eth.ifindex) ||
 1456		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
 1457				    devlink_port->type_eth.ifname)))
 1458			goto nla_put_failure_type_locked;
 1459	}
 1460	if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
 1461		struct ib_device *ibdev = devlink_port->type_ib.ibdev;
 1462
 1463		if (ibdev &&
 1464		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
 1465				   ibdev->name))
 1466			goto nla_put_failure_type_locked;
 1467	}
 1468	spin_unlock_bh(&devlink_port->type_lock);
 1469	if (devlink_nl_port_attrs_put(msg, devlink_port))
 1470		goto nla_put_failure;
 1471	if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
 1472		goto nla_put_failure;
 1473	if (devlink_port->linecard &&
 1474	    nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
 1475			devlink_port->linecard->index))
 1476		goto nla_put_failure;
 1477
 1478	genlmsg_end(msg, hdr);
 1479	return 0;
 1480
 1481nla_put_failure_type_locked:
 1482	spin_unlock_bh(&devlink_port->type_lock);
 1483nla_put_failure:
 1484	genlmsg_cancel(msg, hdr);
 1485	return -EMSGSIZE;
 1486}
 1487
 1488static void devlink_port_notify(struct devlink_port *devlink_port,
 1489				enum devlink_command cmd)
 1490{
 1491	struct devlink *devlink = devlink_port->devlink;
 1492	struct sk_buff *msg;
 1493	int err;
 1494
 1495	WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
 1496
 1497	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
 1498		return;
 1499
 1500	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1501	if (!msg)
 1502		return;
 1503
 1504	err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
 1505	if (err) {
 1506		nlmsg_free(msg);
 1507		return;
 1508	}
 1509
 1510	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
 1511				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 1512}
 1513
 1514static void devlink_rate_notify(struct devlink_rate *devlink_rate,
 1515				enum devlink_command cmd)
 1516{
 1517	struct devlink *devlink = devlink_rate->devlink;
 1518	struct sk_buff *msg;
 1519	int err;
 1520
 1521	WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
 1522
 1523	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
 1524		return;
 1525
 1526	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1527	if (!msg)
 1528		return;
 1529
 1530	err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
 1531	if (err) {
 1532		nlmsg_free(msg);
 1533		return;
 1534	}
 1535
 1536	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
 1537				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 1538}
 1539
 1540static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
 1541					  struct netlink_callback *cb)
 1542{
 1543	struct devlink_rate *devlink_rate;
 1544	struct devlink *devlink;
 1545	int start = cb->args[0];
 1546	unsigned long index;
 1547	int idx = 0;
 1548	int err = 0;
 1549
 1550	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 1551		devl_lock(devlink);
 1552		list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
 1553			enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
 1554			u32 id = NETLINK_CB(cb->skb).portid;
 1555
 1556			if (idx < start) {
 1557				idx++;
 1558				continue;
 1559			}
 1560			err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
 1561						   cb->nlh->nlmsg_seq,
 1562						   NLM_F_MULTI, NULL);
 1563			if (err) {
 1564				devl_unlock(devlink);
 1565				devlink_put(devlink);
 1566				goto out;
 1567			}
 1568			idx++;
 1569		}
 1570		devl_unlock(devlink);
 1571		devlink_put(devlink);
 1572	}
 1573out:
 1574	if (err != -EMSGSIZE)
 1575		return err;
 1576
 1577	cb->args[0] = idx;
 1578	return msg->len;
 1579}
 1580
 1581static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
 1582					struct genl_info *info)
 1583{
 1584	struct devlink_rate *devlink_rate = info->user_ptr[1];
 1585	struct sk_buff *msg;
 1586	int err;
 1587
 1588	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1589	if (!msg)
 1590		return -ENOMEM;
 1591
 1592	err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
 1593				   info->snd_portid, info->snd_seq, 0,
 1594				   info->extack);
 1595	if (err) {
 1596		nlmsg_free(msg);
 1597		return err;
 1598	}
 1599
 1600	return genlmsg_reply(msg, info);
 1601}
 1602
 1603static bool
 1604devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
 1605			    struct devlink_rate *parent)
 1606{
 1607	while (parent) {
 1608		if (parent == devlink_rate)
 1609			return true;
 1610		parent = parent->parent;
 1611	}
 1612	return false;
 1613}
 1614
 1615static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
 1616{
 1617	struct devlink *devlink = info->user_ptr[0];
 1618	struct sk_buff *msg;
 1619	int err;
 1620
 1621	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1622	if (!msg)
 1623		return -ENOMEM;
 1624
 1625	err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 1626			      info->snd_portid, info->snd_seq, 0);
 1627	if (err) {
 1628		nlmsg_free(msg);
 1629		return err;
 1630	}
 1631
 1632	return genlmsg_reply(msg, info);
 1633}
 1634
 1635static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
 1636				     struct netlink_callback *cb)
 1637{
 1638	struct devlink *devlink;
 1639	int start = cb->args[0];
 1640	unsigned long index;
 1641	int idx = 0;
 1642	int err;
 1643
 1644	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 
 
 
 1645		if (idx < start) {
 1646			idx++;
 1647			devlink_put(devlink);
 1648			continue;
 1649		}
 1650
 1651		devl_lock(devlink);
 1652		err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 1653				      NETLINK_CB(cb->skb).portid,
 1654				      cb->nlh->nlmsg_seq, NLM_F_MULTI);
 1655		devl_unlock(devlink);
 1656		devlink_put(devlink);
 1657
 1658		if (err)
 1659			goto out;
 1660		idx++;
 1661	}
 1662out:
 
 
 1663	cb->args[0] = idx;
 1664	return msg->len;
 1665}
 1666
 1667static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
 1668					struct genl_info *info)
 1669{
 
 1670	struct devlink_port *devlink_port = info->user_ptr[1];
 1671	struct sk_buff *msg;
 1672	int err;
 1673
 1674	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1675	if (!msg)
 1676		return -ENOMEM;
 1677
 1678	err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
 1679				   info->snd_portid, info->snd_seq, 0,
 1680				   info->extack);
 1681	if (err) {
 1682		nlmsg_free(msg);
 1683		return err;
 1684	}
 1685
 1686	return genlmsg_reply(msg, info);
 1687}
 1688
 1689static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
 1690					  struct netlink_callback *cb)
 1691{
 1692	struct devlink *devlink;
 1693	struct devlink_port *devlink_port;
 1694	unsigned long index, port_index;
 1695	int start = cb->args[0];
 1696	int idx = 0;
 1697	int err;
 1698
 1699	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 1700		devl_lock(devlink);
 1701		xa_for_each(&devlink->ports, port_index, devlink_port) {
 
 
 
 1702			if (idx < start) {
 1703				idx++;
 1704				continue;
 1705			}
 1706			err = devlink_nl_port_fill(msg, devlink_port,
 1707						   DEVLINK_CMD_NEW,
 1708						   NETLINK_CB(cb->skb).portid,
 1709						   cb->nlh->nlmsg_seq,
 1710						   NLM_F_MULTI, cb->extack);
 1711			if (err) {
 1712				devl_unlock(devlink);
 1713				devlink_put(devlink);
 1714				goto out;
 1715			}
 1716			idx++;
 1717		}
 1718		devl_unlock(devlink);
 1719		devlink_put(devlink);
 1720	}
 1721out:
 
 
 
 1722	cb->args[0] = idx;
 1723	return msg->len;
 1724}
 1725
 1726static int devlink_port_type_set(struct devlink_port *devlink_port,
 
 1727				 enum devlink_port_type port_type)
 1728
 1729{
 1730	int err;
 1731
 1732	if (!devlink_port->devlink->ops->port_type_set)
 1733		return -EOPNOTSUPP;
 1734
 1735	if (port_type == devlink_port->type)
 1736		return 0;
 1737
 1738	err = devlink_port->devlink->ops->port_type_set(devlink_port,
 1739							port_type);
 1740	if (err)
 1741		return err;
 1742
 1743	devlink_port->desired_type = port_type;
 1744	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
 1745	return 0;
 1746}
 1747
 1748static int devlink_port_function_hw_addr_set(struct devlink_port *port,
 1749					     const struct nlattr *attr,
 1750					     struct netlink_ext_ack *extack)
 1751{
 1752	const struct devlink_ops *ops = port->devlink->ops;
 1753	const u8 *hw_addr;
 1754	int hw_addr_len;
 1755
 1756	hw_addr = nla_data(attr);
 1757	hw_addr_len = nla_len(attr);
 1758	if (hw_addr_len > MAX_ADDR_LEN) {
 1759		NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
 1760		return -EINVAL;
 1761	}
 1762	if (port->type == DEVLINK_PORT_TYPE_ETH) {
 1763		if (hw_addr_len != ETH_ALEN) {
 1764			NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
 1765			return -EINVAL;
 1766		}
 1767		if (!is_unicast_ether_addr(hw_addr)) {
 1768			NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
 1769			return -EINVAL;
 1770		}
 1771	}
 1772
 1773	return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
 1774					      extack);
 1775}
 1776
 1777static int devlink_port_fn_state_set(struct devlink_port *port,
 1778				     const struct nlattr *attr,
 1779				     struct netlink_ext_ack *extack)
 1780{
 1781	enum devlink_port_fn_state state;
 1782	const struct devlink_ops *ops;
 1783
 1784	state = nla_get_u8(attr);
 1785	ops = port->devlink->ops;
 1786	return ops->port_fn_state_set(port, state, extack);
 1787}
 1788
 1789static int devlink_port_function_validate(struct devlink_port *devlink_port,
 1790					  struct nlattr **tb,
 1791					  struct netlink_ext_ack *extack)
 1792{
 1793	const struct devlink_ops *ops = devlink_port->devlink->ops;
 1794	struct nlattr *attr;
 1795
 1796	if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
 1797	    !ops->port_function_hw_addr_set) {
 1798		NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
 1799				    "Port doesn't support function attributes");
 1800		return -EOPNOTSUPP;
 1801	}
 1802	if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
 1803		NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
 1804				    "Function does not support state setting");
 1805		return -EOPNOTSUPP;
 1806	}
 1807	attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
 1808	if (attr) {
 1809		struct nla_bitfield32 caps;
 1810
 1811		caps = nla_get_bitfield32(attr);
 1812		if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE &&
 1813		    !ops->port_fn_roce_set) {
 1814			NL_SET_ERR_MSG_ATTR(extack, attr,
 1815					    "Port doesn't support RoCE function attribute");
 1816			return -EOPNOTSUPP;
 1817		}
 1818		if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
 1819			if (!ops->port_fn_migratable_set) {
 1820				NL_SET_ERR_MSG_ATTR(extack, attr,
 1821						    "Port doesn't support migratable function attribute");
 1822				return -EOPNOTSUPP;
 1823			}
 1824			if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) {
 1825				NL_SET_ERR_MSG_ATTR(extack, attr,
 1826						    "migratable function attribute supported for VFs only");
 1827				return -EOPNOTSUPP;
 1828			}
 1829		}
 1830	}
 1831	return 0;
 1832}
 1833
 1834static int devlink_port_function_set(struct devlink_port *port,
 1835				     const struct nlattr *attr,
 1836				     struct netlink_ext_ack *extack)
 1837{
 1838	struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
 1839	int err;
 1840
 1841	err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
 1842			       devlink_function_nl_policy, extack);
 1843	if (err < 0) {
 1844		NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
 1845		return err;
 1846	}
 1847
 1848	err = devlink_port_function_validate(port, tb, extack);
 1849	if (err)
 1850		return err;
 1851
 1852	attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
 1853	if (attr) {
 1854		err = devlink_port_function_hw_addr_set(port, attr, extack);
 1855		if (err)
 1856			return err;
 
 
 
 1857	}
 1858
 1859	attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
 1860	if (attr) {
 1861		err = devlink_port_fn_caps_set(port, attr, extack);
 1862		if (err)
 1863			return err;
 1864	}
 1865
 1866	/* Keep this as the last function attribute set, so that when
 1867	 * multiple port function attributes are set along with state,
 1868	 * Those can be applied first before activating the state.
 1869	 */
 1870	attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
 1871	if (attr)
 1872		err = devlink_port_fn_state_set(port, attr, extack);
 1873
 1874	if (!err)
 1875		devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
 1876	return err;
 1877}
 1878
 1879static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
 1880					struct genl_info *info)
 1881{
 
 1882	struct devlink_port *devlink_port = info->user_ptr[1];
 1883	int err;
 1884
 1885	if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
 1886		enum devlink_port_type port_type;
 1887
 1888		port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
 1889		err = devlink_port_type_set(devlink_port, port_type);
 1890		if (err)
 1891			return err;
 1892	}
 
 
 1893
 1894	if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
 1895		struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
 1896		struct netlink_ext_ack *extack = info->extack;
 1897
 1898		err = devlink_port_function_set(devlink_port, attr, extack);
 1899		if (err)
 1900			return err;
 1901	}
 1902
 1903	return 0;
 1904}
 1905
 1906static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
 1907					  struct genl_info *info)
 1908{
 1909	struct devlink_port *devlink_port = info->user_ptr[1];
 1910	struct devlink *devlink = info->user_ptr[0];
 
 1911	u32 count;
 1912
 1913	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
 
 1914		return -EINVAL;
 1915	if (!devlink->ops->port_split)
 1916		return -EOPNOTSUPP;
 1917
 
 1918	count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
 1919
 1920	if (!devlink_port->attrs.splittable) {
 1921		/* Split ports cannot be split. */
 1922		if (devlink_port->attrs.split)
 1923			NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
 1924		else
 1925			NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
 1926		return -EINVAL;
 1927	}
 1928
 1929	if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
 1930		NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
 1931		return -EINVAL;
 1932	}
 1933
 1934	return devlink->ops->port_split(devlink, devlink_port, count,
 1935					info->extack);
 1936}
 1937
 1938static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
 1939					    struct genl_info *info)
 1940{
 1941	struct devlink_port *devlink_port = info->user_ptr[1];
 1942	struct devlink *devlink = info->user_ptr[0];
 1943
 1944	if (!devlink->ops->port_unsplit)
 1945		return -EOPNOTSUPP;
 1946	return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
 1947}
 1948
 1949static int devlink_port_new_notify(struct devlink *devlink,
 1950				   unsigned int port_index,
 1951				   struct genl_info *info)
 1952{
 1953	struct devlink_port *devlink_port;
 1954	struct sk_buff *msg;
 1955	int err;
 1956
 1957	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 1958	if (!msg)
 1959		return -ENOMEM;
 1960
 1961	lockdep_assert_held(&devlink->lock);
 1962	devlink_port = devlink_port_get_by_index(devlink, port_index);
 1963	if (!devlink_port) {
 1964		err = -ENODEV;
 1965		goto out;
 1966	}
 1967
 1968	err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
 1969				   info->snd_portid, info->snd_seq, 0, NULL);
 1970	if (err)
 1971		goto out;
 1972
 1973	return genlmsg_reply(msg, info);
 1974
 1975out:
 1976	nlmsg_free(msg);
 1977	return err;
 1978}
 1979
 1980static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
 1981					struct genl_info *info)
 1982{
 1983	struct netlink_ext_ack *extack = info->extack;
 1984	struct devlink_port_new_attrs new_attrs = {};
 1985	struct devlink *devlink = info->user_ptr[0];
 1986	unsigned int new_port_index;
 1987	int err;
 1988
 1989	if (!devlink->ops->port_new || !devlink->ops->port_del)
 1990		return -EOPNOTSUPP;
 1991
 1992	if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
 1993	    !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
 1994		NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified");
 1995		return -EINVAL;
 1996	}
 1997	new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
 1998	new_attrs.pfnum =
 1999		nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
 2000
 2001	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
 2002		/* Port index of the new port being created by driver. */
 2003		new_attrs.port_index =
 2004			nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 2005		new_attrs.port_index_valid = true;
 2006	}
 2007	if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
 2008		new_attrs.controller =
 2009			nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
 2010		new_attrs.controller_valid = true;
 2011	}
 2012	if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
 2013	    info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
 2014		new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
 2015		new_attrs.sfnum_valid = true;
 2016	}
 2017
 2018	err = devlink->ops->port_new(devlink, &new_attrs, extack,
 2019				     &new_port_index);
 2020	if (err)
 2021		return err;
 2022
 2023	err = devlink_port_new_notify(devlink, new_port_index, info);
 2024	if (err && err != -ENODEV) {
 2025		/* Fail to send the response; destroy newly created port. */
 2026		devlink->ops->port_del(devlink, new_port_index, extack);
 2027	}
 2028	return err;
 2029}
 2030
 2031static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
 2032					struct genl_info *info)
 2033{
 2034	struct netlink_ext_ack *extack = info->extack;
 2035	struct devlink *devlink = info->user_ptr[0];
 2036	unsigned int port_index;
 2037
 2038	if (!devlink->ops->port_del)
 2039		return -EOPNOTSUPP;
 2040
 2041	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) {
 2042		NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
 2043		return -EINVAL;
 2044	}
 2045	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 2046
 2047	return devlink->ops->port_del(devlink, port_index, extack);
 2048}
 2049
 2050static int
 2051devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
 2052				struct genl_info *info,
 2053				struct nlattr *nla_parent)
 2054{
 2055	struct devlink *devlink = devlink_rate->devlink;
 2056	const char *parent_name = nla_data(nla_parent);
 2057	const struct devlink_ops *ops = devlink->ops;
 2058	size_t len = strlen(parent_name);
 2059	struct devlink_rate *parent;
 2060	int err = -EOPNOTSUPP;
 2061
 2062	parent = devlink_rate->parent;
 2063
 2064	if (parent && !len) {
 2065		if (devlink_rate_is_leaf(devlink_rate))
 2066			err = ops->rate_leaf_parent_set(devlink_rate, NULL,
 2067							devlink_rate->priv, NULL,
 2068							info->extack);
 2069		else if (devlink_rate_is_node(devlink_rate))
 2070			err = ops->rate_node_parent_set(devlink_rate, NULL,
 2071							devlink_rate->priv, NULL,
 2072							info->extack);
 2073		if (err)
 2074			return err;
 2075
 2076		refcount_dec(&parent->refcnt);
 2077		devlink_rate->parent = NULL;
 2078	} else if (len) {
 2079		parent = devlink_rate_node_get_by_name(devlink, parent_name);
 2080		if (IS_ERR(parent))
 2081			return -ENODEV;
 2082
 2083		if (parent == devlink_rate) {
 2084			NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
 2085			return -EINVAL;
 2086		}
 2087
 2088		if (devlink_rate_is_node(devlink_rate) &&
 2089		    devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
 2090			NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node.");
 2091			return -EEXIST;
 2092		}
 2093
 2094		if (devlink_rate_is_leaf(devlink_rate))
 2095			err = ops->rate_leaf_parent_set(devlink_rate, parent,
 2096							devlink_rate->priv, parent->priv,
 2097							info->extack);
 2098		else if (devlink_rate_is_node(devlink_rate))
 2099			err = ops->rate_node_parent_set(devlink_rate, parent,
 2100							devlink_rate->priv, parent->priv,
 2101							info->extack);
 2102		if (err)
 2103			return err;
 2104
 2105		if (devlink_rate->parent)
 2106			/* we're reassigning to other parent in this case */
 2107			refcount_dec(&devlink_rate->parent->refcnt);
 2108
 2109		refcount_inc(&parent->refcnt);
 2110		devlink_rate->parent = parent;
 2111	}
 2112
 2113	return 0;
 2114}
 2115
 2116static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
 2117			       const struct devlink_ops *ops,
 2118			       struct genl_info *info)
 2119{
 2120	struct nlattr *nla_parent, **attrs = info->attrs;
 2121	int err = -EOPNOTSUPP;
 2122	u32 priority;
 2123	u32 weight;
 2124	u64 rate;
 2125
 2126	if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
 2127		rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
 2128		if (devlink_rate_is_leaf(devlink_rate))
 2129			err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
 2130							  rate, info->extack);
 2131		else if (devlink_rate_is_node(devlink_rate))
 2132			err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
 2133							  rate, info->extack);
 2134		if (err)
 2135			return err;
 2136		devlink_rate->tx_share = rate;
 2137	}
 2138
 2139	if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
 2140		rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
 2141		if (devlink_rate_is_leaf(devlink_rate))
 2142			err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
 2143							rate, info->extack);
 2144		else if (devlink_rate_is_node(devlink_rate))
 2145			err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
 2146							rate, info->extack);
 2147		if (err)
 2148			return err;
 2149		devlink_rate->tx_max = rate;
 2150	}
 2151
 2152	if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
 2153		priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
 2154		if (devlink_rate_is_leaf(devlink_rate))
 2155			err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
 2156							     priority, info->extack);
 2157		else if (devlink_rate_is_node(devlink_rate))
 2158			err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
 2159							     priority, info->extack);
 2160
 2161		if (err)
 2162			return err;
 2163		devlink_rate->tx_priority = priority;
 2164	}
 2165
 2166	if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
 2167		weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
 2168		if (devlink_rate_is_leaf(devlink_rate))
 2169			err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
 2170							   weight, info->extack);
 2171		else if (devlink_rate_is_node(devlink_rate))
 2172			err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
 2173							   weight, info->extack);
 2174
 2175		if (err)
 2176			return err;
 2177		devlink_rate->tx_weight = weight;
 2178	}
 2179
 2180	nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
 2181	if (nla_parent) {
 2182		err = devlink_nl_rate_parent_node_set(devlink_rate, info,
 2183						      nla_parent);
 2184		if (err)
 2185			return err;
 2186	}
 2187
 2188	return 0;
 2189}
 2190
 2191static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
 2192					   struct genl_info *info,
 2193					   enum devlink_rate_type type)
 2194{
 2195	struct nlattr **attrs = info->attrs;
 2196
 2197	if (type == DEVLINK_RATE_TYPE_LEAF) {
 2198		if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
 2199			NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs");
 2200			return false;
 2201		}
 2202		if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
 2203			NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs");
 2204			return false;
 2205		}
 2206		if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
 2207		    !ops->rate_leaf_parent_set) {
 2208			NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
 2209			return false;
 2210		}
 2211		if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
 2212			NL_SET_ERR_MSG_ATTR(info->extack,
 2213					    attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
 2214					    "TX priority set isn't supported for the leafs");
 2215			return false;
 2216		}
 2217		if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
 2218			NL_SET_ERR_MSG_ATTR(info->extack,
 2219					    attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
 2220					    "TX weight set isn't supported for the leafs");
 2221			return false;
 2222		}
 2223	} else if (type == DEVLINK_RATE_TYPE_NODE) {
 2224		if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
 2225			NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
 2226			return false;
 2227		}
 2228		if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
 2229			NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes");
 2230			return false;
 2231		}
 2232		if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
 2233		    !ops->rate_node_parent_set) {
 2234			NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
 2235			return false;
 2236		}
 2237		if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) {
 2238			NL_SET_ERR_MSG_ATTR(info->extack,
 2239					    attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
 2240					    "TX priority set isn't supported for the nodes");
 2241			return false;
 2242		}
 2243		if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) {
 2244			NL_SET_ERR_MSG_ATTR(info->extack,
 2245					    attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
 2246					    "TX weight set isn't supported for the nodes");
 2247			return false;
 2248		}
 2249	} else {
 2250		WARN(1, "Unknown type of rate object");
 2251		return false;
 2252	}
 2253
 2254	return true;
 2255}
 2256
 2257static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
 2258					struct genl_info *info)
 2259{
 2260	struct devlink_rate *devlink_rate = info->user_ptr[1];
 2261	struct devlink *devlink = devlink_rate->devlink;
 2262	const struct devlink_ops *ops = devlink->ops;
 2263	int err;
 2264
 2265	if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
 2266		return -EOPNOTSUPP;
 2267
 2268	err = devlink_nl_rate_set(devlink_rate, ops, info);
 2269
 2270	if (!err)
 2271		devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
 2272	return err;
 2273}
 2274
 2275static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
 2276					struct genl_info *info)
 2277{
 2278	struct devlink *devlink = info->user_ptr[0];
 2279	struct devlink_rate *rate_node;
 2280	const struct devlink_ops *ops;
 2281	int err;
 2282
 2283	ops = devlink->ops;
 2284	if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
 2285		NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported");
 2286		return -EOPNOTSUPP;
 2287	}
 2288
 2289	if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
 2290		return -EOPNOTSUPP;
 2291
 2292	rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
 2293	if (!IS_ERR(rate_node))
 2294		return -EEXIST;
 2295	else if (rate_node == ERR_PTR(-EINVAL))
 2296		return -EINVAL;
 2297
 2298	rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
 2299	if (!rate_node)
 2300		return -ENOMEM;
 2301
 2302	rate_node->devlink = devlink;
 2303	rate_node->type = DEVLINK_RATE_TYPE_NODE;
 2304	rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
 2305	if (!rate_node->name) {
 2306		err = -ENOMEM;
 2307		goto err_strdup;
 2308	}
 2309
 2310	err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
 2311	if (err)
 2312		goto err_node_new;
 2313
 2314	err = devlink_nl_rate_set(rate_node, ops, info);
 2315	if (err)
 2316		goto err_rate_set;
 2317
 2318	refcount_set(&rate_node->refcnt, 1);
 2319	list_add(&rate_node->list, &devlink->rate_list);
 2320	devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
 2321	return 0;
 2322
 2323err_rate_set:
 2324	ops->rate_node_del(rate_node, rate_node->priv, info->extack);
 2325err_node_new:
 2326	kfree(rate_node->name);
 2327err_strdup:
 2328	kfree(rate_node);
 2329	return err;
 2330}
 2331
 2332static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
 2333					struct genl_info *info)
 2334{
 2335	struct devlink_rate *rate_node = info->user_ptr[1];
 2336	struct devlink *devlink = rate_node->devlink;
 2337	const struct devlink_ops *ops = devlink->ops;
 2338	int err;
 2339
 2340	if (refcount_read(&rate_node->refcnt) > 1) {
 2341		NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
 2342		return -EBUSY;
 2343	}
 2344
 2345	devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
 2346	err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
 2347	if (rate_node->parent)
 2348		refcount_dec(&rate_node->parent->refcnt);
 2349	list_del(&rate_node->list);
 2350	kfree(rate_node->name);
 2351	kfree(rate_node);
 2352	return err;
 2353}
 2354
 2355struct devlink_linecard_type {
 2356	const char *type;
 2357	const void *priv;
 2358};
 2359
 2360static int devlink_nl_linecard_fill(struct sk_buff *msg,
 2361				    struct devlink *devlink,
 2362				    struct devlink_linecard *linecard,
 2363				    enum devlink_command cmd, u32 portid,
 2364				    u32 seq, int flags,
 2365				    struct netlink_ext_ack *extack)
 2366{
 2367	struct devlink_linecard_type *linecard_type;
 2368	struct nlattr *attr;
 2369	void *hdr;
 2370	int i;
 2371
 2372	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 2373	if (!hdr)
 2374		return -EMSGSIZE;
 2375
 2376	if (devlink_nl_put_handle(msg, devlink))
 2377		goto nla_put_failure;
 2378	if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
 2379		goto nla_put_failure;
 2380	if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
 2381		goto nla_put_failure;
 2382	if (linecard->type &&
 2383	    nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
 2384		goto nla_put_failure;
 2385
 2386	if (linecard->types_count) {
 2387		attr = nla_nest_start(msg,
 2388				      DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
 2389		if (!attr)
 2390			goto nla_put_failure;
 2391		for (i = 0; i < linecard->types_count; i++) {
 2392			linecard_type = &linecard->types[i];
 2393			if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
 2394					   linecard_type->type)) {
 2395				nla_nest_cancel(msg, attr);
 2396				goto nla_put_failure;
 2397			}
 2398		}
 2399		nla_nest_end(msg, attr);
 2400	}
 2401
 2402	if (linecard->nested_devlink &&
 2403	    devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
 2404		goto nla_put_failure;
 2405
 2406	genlmsg_end(msg, hdr);
 2407	return 0;
 2408
 2409nla_put_failure:
 2410	genlmsg_cancel(msg, hdr);
 2411	return -EMSGSIZE;
 2412}
 2413
 2414static void devlink_linecard_notify(struct devlink_linecard *linecard,
 2415				    enum devlink_command cmd)
 2416{
 2417	struct devlink *devlink = linecard->devlink;
 2418	struct sk_buff *msg;
 2419	int err;
 2420
 2421	WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
 2422		cmd != DEVLINK_CMD_LINECARD_DEL);
 2423
 2424	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
 2425		return;
 2426
 2427	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 2428	if (!msg)
 2429		return;
 2430
 2431	err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
 2432				       NULL);
 2433	if (err) {
 2434		nlmsg_free(msg);
 2435		return;
 2436	}
 2437
 2438	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 2439				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 2440}
 2441
 2442static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
 2443					    struct genl_info *info)
 2444{
 2445	struct devlink_linecard *linecard = info->user_ptr[1];
 2446	struct devlink *devlink = linecard->devlink;
 2447	struct sk_buff *msg;
 2448	int err;
 2449
 2450	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 2451	if (!msg)
 2452		return -ENOMEM;
 2453
 2454	mutex_lock(&linecard->state_lock);
 2455	err = devlink_nl_linecard_fill(msg, devlink, linecard,
 2456				       DEVLINK_CMD_LINECARD_NEW,
 2457				       info->snd_portid, info->snd_seq, 0,
 2458				       info->extack);
 2459	mutex_unlock(&linecard->state_lock);
 2460	if (err) {
 2461		nlmsg_free(msg);
 2462		return err;
 2463	}
 2464
 2465	return genlmsg_reply(msg, info);
 2466}
 2467
 2468static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
 2469					      struct netlink_callback *cb)
 2470{
 2471	struct devlink_linecard *linecard;
 2472	struct devlink *devlink;
 2473	int start = cb->args[0];
 2474	unsigned long index;
 2475	int idx = 0;
 2476	int err;
 2477
 2478	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 2479		mutex_lock(&devlink->linecards_lock);
 2480		list_for_each_entry(linecard, &devlink->linecard_list, list) {
 2481			if (idx < start) {
 2482				idx++;
 2483				continue;
 2484			}
 2485			mutex_lock(&linecard->state_lock);
 2486			err = devlink_nl_linecard_fill(msg, devlink, linecard,
 2487						       DEVLINK_CMD_LINECARD_NEW,
 2488						       NETLINK_CB(cb->skb).portid,
 2489						       cb->nlh->nlmsg_seq,
 2490						       NLM_F_MULTI,
 2491						       cb->extack);
 2492			mutex_unlock(&linecard->state_lock);
 2493			if (err) {
 2494				mutex_unlock(&devlink->linecards_lock);
 2495				devlink_put(devlink);
 2496				goto out;
 2497			}
 2498			idx++;
 2499		}
 2500		mutex_unlock(&devlink->linecards_lock);
 2501		devlink_put(devlink);
 2502	}
 2503out:
 2504	cb->args[0] = idx;
 2505	return msg->len;
 2506}
 2507
 2508static struct devlink_linecard_type *
 2509devlink_linecard_type_lookup(struct devlink_linecard *linecard,
 2510			     const char *type)
 2511{
 2512	struct devlink_linecard_type *linecard_type;
 2513	int i;
 2514
 2515	for (i = 0; i < linecard->types_count; i++) {
 2516		linecard_type = &linecard->types[i];
 2517		if (!strcmp(type, linecard_type->type))
 2518			return linecard_type;
 2519	}
 2520	return NULL;
 2521}
 2522
 2523static int devlink_linecard_type_set(struct devlink_linecard *linecard,
 2524				     const char *type,
 2525				     struct netlink_ext_ack *extack)
 2526{
 2527	const struct devlink_linecard_ops *ops = linecard->ops;
 2528	struct devlink_linecard_type *linecard_type;
 2529	int err;
 2530
 2531	mutex_lock(&linecard->state_lock);
 2532	if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
 2533		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
 2534		err = -EBUSY;
 2535		goto out;
 2536	}
 2537	if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
 2538		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
 2539		err = -EBUSY;
 2540		goto out;
 2541	}
 2542
 2543	linecard_type = devlink_linecard_type_lookup(linecard, type);
 2544	if (!linecard_type) {
 2545		NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided");
 2546		err = -EINVAL;
 2547		goto out;
 2548	}
 2549
 2550	if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
 2551	    linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
 2552		NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned");
 2553		err = -EBUSY;
 2554		/* Check if the line card is provisioned in the same
 2555		 * way the user asks. In case it is, make the operation
 2556		 * to return success.
 2557		 */
 2558		if (ops->same_provision &&
 2559		    ops->same_provision(linecard, linecard->priv,
 2560					linecard_type->type,
 2561					linecard_type->priv))
 2562			err = 0;
 2563		goto out;
 2564	}
 2565
 2566	linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
 2567	linecard->type = linecard_type->type;
 2568	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
 2569	mutex_unlock(&linecard->state_lock);
 2570	err = ops->provision(linecard, linecard->priv, linecard_type->type,
 2571			     linecard_type->priv, extack);
 2572	if (err) {
 2573		/* Provisioning failed. Assume the linecard is unprovisioned
 2574		 * for future operations.
 2575		 */
 2576		mutex_lock(&linecard->state_lock);
 2577		linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
 2578		linecard->type = NULL;
 2579		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
 2580		mutex_unlock(&linecard->state_lock);
 2581	}
 2582	return err;
 2583
 2584out:
 2585	mutex_unlock(&linecard->state_lock);
 2586	return err;
 2587}
 2588
 2589static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
 2590				       struct netlink_ext_ack *extack)
 2591{
 2592	int err;
 2593
 2594	mutex_lock(&linecard->state_lock);
 2595	if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
 2596		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
 2597		err = -EBUSY;
 2598		goto out;
 2599	}
 2600	if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
 2601		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
 2602		err = -EBUSY;
 2603		goto out;
 2604	}
 2605	if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
 2606		linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
 2607		linecard->type = NULL;
 2608		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
 2609		err = 0;
 2610		goto out;
 2611	}
 2612
 2613	if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
 2614		NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned");
 2615		err = 0;
 2616		goto out;
 2617	}
 2618	linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
 2619	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
 2620	mutex_unlock(&linecard->state_lock);
 2621	err = linecard->ops->unprovision(linecard, linecard->priv,
 2622					 extack);
 2623	if (err) {
 2624		/* Unprovisioning failed. Assume the linecard is unprovisioned
 2625		 * for future operations.
 2626		 */
 2627		mutex_lock(&linecard->state_lock);
 2628		linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
 2629		linecard->type = NULL;
 2630		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
 2631		mutex_unlock(&linecard->state_lock);
 2632	}
 2633	return err;
 2634
 2635out:
 2636	mutex_unlock(&linecard->state_lock);
 2637	return err;
 2638}
 2639
 2640static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
 2641					    struct genl_info *info)
 2642{
 2643	struct devlink_linecard *linecard = info->user_ptr[1];
 2644	struct netlink_ext_ack *extack = info->extack;
 2645	int err;
 2646
 2647	if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
 2648		const char *type;
 2649
 2650		type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
 2651		if (strcmp(type, "")) {
 2652			err = devlink_linecard_type_set(linecard, type, extack);
 2653			if (err)
 2654				return err;
 2655		} else {
 2656			err = devlink_linecard_type_unset(linecard, extack);
 2657			if (err)
 2658				return err;
 2659		}
 2660	}
 2661
 2662	return 0;
 2663}
 2664
 2665static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
 2666			      struct devlink_sb *devlink_sb,
 2667			      enum devlink_command cmd, u32 portid,
 2668			      u32 seq, int flags)
 2669{
 2670	void *hdr;
 2671
 2672	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 2673	if (!hdr)
 2674		return -EMSGSIZE;
 2675
 2676	if (devlink_nl_put_handle(msg, devlink))
 2677		goto nla_put_failure;
 2678	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 2679		goto nla_put_failure;
 2680	if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
 2681		goto nla_put_failure;
 2682	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
 2683			devlink_sb->ingress_pools_count))
 2684		goto nla_put_failure;
 2685	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
 2686			devlink_sb->egress_pools_count))
 2687		goto nla_put_failure;
 2688	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
 2689			devlink_sb->ingress_tc_count))
 2690		goto nla_put_failure;
 2691	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
 2692			devlink_sb->egress_tc_count))
 2693		goto nla_put_failure;
 2694
 2695	genlmsg_end(msg, hdr);
 2696	return 0;
 2697
 2698nla_put_failure:
 2699	genlmsg_cancel(msg, hdr);
 2700	return -EMSGSIZE;
 2701}
 2702
 2703static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
 2704				      struct genl_info *info)
 2705{
 2706	struct devlink *devlink = info->user_ptr[0];
 2707	struct devlink_sb *devlink_sb;
 2708	struct sk_buff *msg;
 2709	int err;
 2710
 2711	devlink_sb = devlink_sb_get_from_info(devlink, info);
 2712	if (IS_ERR(devlink_sb))
 2713		return PTR_ERR(devlink_sb);
 2714
 2715	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 2716	if (!msg)
 2717		return -ENOMEM;
 2718
 2719	err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 2720				 DEVLINK_CMD_SB_NEW,
 2721				 info->snd_portid, info->snd_seq, 0);
 2722	if (err) {
 2723		nlmsg_free(msg);
 2724		return err;
 2725	}
 2726
 2727	return genlmsg_reply(msg, info);
 2728}
 2729
 2730static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
 2731					struct netlink_callback *cb)
 2732{
 2733	struct devlink *devlink;
 2734	struct devlink_sb *devlink_sb;
 2735	int start = cb->args[0];
 2736	unsigned long index;
 2737	int idx = 0;
 2738	int err;
 2739
 2740	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 2741		devl_lock(devlink);
 2742		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 2743			if (idx < start) {
 2744				idx++;
 2745				continue;
 2746			}
 2747			err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 2748						 DEVLINK_CMD_SB_NEW,
 2749						 NETLINK_CB(cb->skb).portid,
 2750						 cb->nlh->nlmsg_seq,
 2751						 NLM_F_MULTI);
 2752			if (err) {
 2753				devl_unlock(devlink);
 2754				devlink_put(devlink);
 2755				goto out;
 2756			}
 2757			idx++;
 2758		}
 2759		devl_unlock(devlink);
 2760		devlink_put(devlink);
 2761	}
 2762out:
 2763	cb->args[0] = idx;
 2764	return msg->len;
 2765}
 2766
 2767static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
 2768				   struct devlink_sb *devlink_sb,
 2769				   u16 pool_index, enum devlink_command cmd,
 2770				   u32 portid, u32 seq, int flags)
 2771{
 2772	struct devlink_sb_pool_info pool_info;
 2773	void *hdr;
 2774	int err;
 2775
 2776	err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
 2777					pool_index, &pool_info);
 2778	if (err)
 2779		return err;
 2780
 2781	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 2782	if (!hdr)
 2783		return -EMSGSIZE;
 2784
 2785	if (devlink_nl_put_handle(msg, devlink))
 2786		goto nla_put_failure;
 2787	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 2788		goto nla_put_failure;
 2789	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 2790		goto nla_put_failure;
 2791	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
 2792		goto nla_put_failure;
 2793	if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
 2794		goto nla_put_failure;
 2795	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
 2796		       pool_info.threshold_type))
 2797		goto nla_put_failure;
 2798	if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
 2799			pool_info.cell_size))
 2800		goto nla_put_failure;
 2801
 2802	genlmsg_end(msg, hdr);
 2803	return 0;
 2804
 2805nla_put_failure:
 2806	genlmsg_cancel(msg, hdr);
 2807	return -EMSGSIZE;
 2808}
 2809
 2810static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
 2811					   struct genl_info *info)
 2812{
 2813	struct devlink *devlink = info->user_ptr[0];
 2814	struct devlink_sb *devlink_sb;
 2815	struct sk_buff *msg;
 2816	u16 pool_index;
 2817	int err;
 2818
 2819	devlink_sb = devlink_sb_get_from_info(devlink, info);
 2820	if (IS_ERR(devlink_sb))
 2821		return PTR_ERR(devlink_sb);
 2822
 2823	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 2824						  &pool_index);
 2825	if (err)
 2826		return err;
 2827
 2828	if (!devlink->ops->sb_pool_get)
 2829		return -EOPNOTSUPP;
 2830
 2831	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 2832	if (!msg)
 2833		return -ENOMEM;
 2834
 2835	err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
 2836				      DEVLINK_CMD_SB_POOL_NEW,
 2837				      info->snd_portid, info->snd_seq, 0);
 2838	if (err) {
 2839		nlmsg_free(msg);
 2840		return err;
 2841	}
 2842
 2843	return genlmsg_reply(msg, info);
 2844}
 2845
 2846static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
 2847				struct devlink *devlink,
 2848				struct devlink_sb *devlink_sb,
 2849				u32 portid, u32 seq)
 2850{
 2851	u16 pool_count = devlink_sb_pool_count(devlink_sb);
 2852	u16 pool_index;
 2853	int err;
 2854
 2855	for (pool_index = 0; pool_index < pool_count; pool_index++) {
 2856		if (*p_idx < start) {
 2857			(*p_idx)++;
 2858			continue;
 2859		}
 2860		err = devlink_nl_sb_pool_fill(msg, devlink,
 2861					      devlink_sb,
 2862					      pool_index,
 2863					      DEVLINK_CMD_SB_POOL_NEW,
 2864					      portid, seq, NLM_F_MULTI);
 2865		if (err)
 2866			return err;
 2867		(*p_idx)++;
 2868	}
 2869	return 0;
 2870}
 2871
 2872static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
 2873					     struct netlink_callback *cb)
 2874{
 2875	struct devlink *devlink;
 2876	struct devlink_sb *devlink_sb;
 2877	int start = cb->args[0];
 2878	unsigned long index;
 2879	int idx = 0;
 2880	int err = 0;
 2881
 2882	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 2883		if (!devlink->ops->sb_pool_get)
 2884			goto retry;
 2885
 2886		devl_lock(devlink);
 2887		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 2888			err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
 2889						   devlink_sb,
 2890						   NETLINK_CB(cb->skb).portid,
 2891						   cb->nlh->nlmsg_seq);
 2892			if (err == -EOPNOTSUPP) {
 2893				err = 0;
 2894			} else if (err) {
 2895				devl_unlock(devlink);
 2896				devlink_put(devlink);
 2897				goto out;
 2898			}
 2899		}
 2900		devl_unlock(devlink);
 2901retry:
 2902		devlink_put(devlink);
 2903	}
 2904out:
 2905	if (err != -EMSGSIZE)
 2906		return err;
 2907
 2908	cb->args[0] = idx;
 2909	return msg->len;
 2910}
 2911
 2912static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
 2913			       u16 pool_index, u32 size,
 2914			       enum devlink_sb_threshold_type threshold_type,
 2915			       struct netlink_ext_ack *extack)
 2916
 2917{
 2918	const struct devlink_ops *ops = devlink->ops;
 2919
 2920	if (ops->sb_pool_set)
 2921		return ops->sb_pool_set(devlink, sb_index, pool_index,
 2922					size, threshold_type, extack);
 2923	return -EOPNOTSUPP;
 2924}
 2925
 2926static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
 2927					   struct genl_info *info)
 2928{
 2929	struct devlink *devlink = info->user_ptr[0];
 2930	enum devlink_sb_threshold_type threshold_type;
 2931	struct devlink_sb *devlink_sb;
 2932	u16 pool_index;
 2933	u32 size;
 2934	int err;
 2935
 2936	devlink_sb = devlink_sb_get_from_info(devlink, info);
 2937	if (IS_ERR(devlink_sb))
 2938		return PTR_ERR(devlink_sb);
 2939
 2940	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 2941						  &pool_index);
 2942	if (err)
 2943		return err;
 2944
 2945	err = devlink_sb_th_type_get_from_info(info, &threshold_type);
 2946	if (err)
 2947		return err;
 2948
 2949	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
 2950		return -EINVAL;
 2951
 2952	size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
 2953	return devlink_sb_pool_set(devlink, devlink_sb->index,
 2954				   pool_index, size, threshold_type,
 2955				   info->extack);
 2956}
 2957
 2958static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
 2959					struct devlink *devlink,
 2960					struct devlink_port *devlink_port,
 2961					struct devlink_sb *devlink_sb,
 2962					u16 pool_index,
 2963					enum devlink_command cmd,
 2964					u32 portid, u32 seq, int flags)
 2965{
 2966	const struct devlink_ops *ops = devlink->ops;
 2967	u32 threshold;
 2968	void *hdr;
 2969	int err;
 2970
 2971	err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
 2972				    pool_index, &threshold);
 2973	if (err)
 2974		return err;
 2975
 2976	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 2977	if (!hdr)
 2978		return -EMSGSIZE;
 2979
 2980	if (devlink_nl_put_handle(msg, devlink))
 2981		goto nla_put_failure;
 2982	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 2983		goto nla_put_failure;
 2984	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 2985		goto nla_put_failure;
 2986	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 2987		goto nla_put_failure;
 2988	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
 2989		goto nla_put_failure;
 2990
 2991	if (ops->sb_occ_port_pool_get) {
 2992		u32 cur;
 2993		u32 max;
 2994
 2995		err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
 2996						pool_index, &cur, &max);
 2997		if (err && err != -EOPNOTSUPP)
 2998			goto sb_occ_get_failure;
 2999		if (!err) {
 3000			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
 3001				goto nla_put_failure;
 3002			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
 3003				goto nla_put_failure;
 3004		}
 3005	}
 3006
 3007	genlmsg_end(msg, hdr);
 3008	return 0;
 3009
 3010nla_put_failure:
 3011	err = -EMSGSIZE;
 3012sb_occ_get_failure:
 3013	genlmsg_cancel(msg, hdr);
 3014	return err;
 3015}
 3016
 3017static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
 3018						struct genl_info *info)
 3019{
 3020	struct devlink_port *devlink_port = info->user_ptr[1];
 3021	struct devlink *devlink = devlink_port->devlink;
 3022	struct devlink_sb *devlink_sb;
 3023	struct sk_buff *msg;
 3024	u16 pool_index;
 3025	int err;
 3026
 3027	devlink_sb = devlink_sb_get_from_info(devlink, info);
 3028	if (IS_ERR(devlink_sb))
 3029		return PTR_ERR(devlink_sb);
 3030
 3031	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 3032						  &pool_index);
 3033	if (err)
 3034		return err;
 3035
 3036	if (!devlink->ops->sb_port_pool_get)
 3037		return -EOPNOTSUPP;
 3038
 3039	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 3040	if (!msg)
 3041		return -ENOMEM;
 3042
 3043	err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
 3044					   devlink_sb, pool_index,
 3045					   DEVLINK_CMD_SB_PORT_POOL_NEW,
 3046					   info->snd_portid, info->snd_seq, 0);
 3047	if (err) {
 3048		nlmsg_free(msg);
 3049		return err;
 3050	}
 3051
 3052	return genlmsg_reply(msg, info);
 3053}
 3054
 3055static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
 3056				     struct devlink *devlink,
 3057				     struct devlink_sb *devlink_sb,
 3058				     u32 portid, u32 seq)
 3059{
 3060	struct devlink_port *devlink_port;
 3061	u16 pool_count = devlink_sb_pool_count(devlink_sb);
 3062	unsigned long port_index;
 3063	u16 pool_index;
 3064	int err;
 3065
 3066	xa_for_each(&devlink->ports, port_index, devlink_port) {
 3067		for (pool_index = 0; pool_index < pool_count; pool_index++) {
 3068			if (*p_idx < start) {
 3069				(*p_idx)++;
 3070				continue;
 3071			}
 3072			err = devlink_nl_sb_port_pool_fill(msg, devlink,
 3073							   devlink_port,
 3074							   devlink_sb,
 3075							   pool_index,
 3076							   DEVLINK_CMD_SB_PORT_POOL_NEW,
 3077							   portid, seq,
 3078							   NLM_F_MULTI);
 3079			if (err)
 3080				return err;
 3081			(*p_idx)++;
 3082		}
 3083	}
 3084	return 0;
 3085}
 3086
 3087static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
 3088						  struct netlink_callback *cb)
 3089{
 3090	struct devlink *devlink;
 3091	struct devlink_sb *devlink_sb;
 3092	int start = cb->args[0];
 3093	unsigned long index;
 3094	int idx = 0;
 3095	int err = 0;
 3096
 3097	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 3098		if (!devlink->ops->sb_port_pool_get)
 3099			goto retry;
 3100
 3101		devl_lock(devlink);
 3102		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 3103			err = __sb_port_pool_get_dumpit(msg, start, &idx,
 3104							devlink, devlink_sb,
 3105							NETLINK_CB(cb->skb).portid,
 3106							cb->nlh->nlmsg_seq);
 3107			if (err == -EOPNOTSUPP) {
 3108				err = 0;
 3109			} else if (err) {
 3110				devl_unlock(devlink);
 3111				devlink_put(devlink);
 3112				goto out;
 3113			}
 3114		}
 3115		devl_unlock(devlink);
 3116retry:
 3117		devlink_put(devlink);
 3118	}
 3119out:
 3120	if (err != -EMSGSIZE)
 3121		return err;
 3122
 3123	cb->args[0] = idx;
 3124	return msg->len;
 3125}
 3126
 3127static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
 3128				    unsigned int sb_index, u16 pool_index,
 3129				    u32 threshold,
 3130				    struct netlink_ext_ack *extack)
 3131
 3132{
 3133	const struct devlink_ops *ops = devlink_port->devlink->ops;
 3134
 3135	if (ops->sb_port_pool_set)
 3136		return ops->sb_port_pool_set(devlink_port, sb_index,
 3137					     pool_index, threshold, extack);
 3138	return -EOPNOTSUPP;
 3139}
 3140
 3141static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
 3142						struct genl_info *info)
 3143{
 3144	struct devlink_port *devlink_port = info->user_ptr[1];
 3145	struct devlink *devlink = info->user_ptr[0];
 3146	struct devlink_sb *devlink_sb;
 3147	u16 pool_index;
 3148	u32 threshold;
 3149	int err;
 3150
 3151	devlink_sb = devlink_sb_get_from_info(devlink, info);
 3152	if (IS_ERR(devlink_sb))
 3153		return PTR_ERR(devlink_sb);
 3154
 3155	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 3156						  &pool_index);
 3157	if (err)
 3158		return err;
 3159
 3160	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
 3161		return -EINVAL;
 3162
 3163	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
 3164	return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
 3165					pool_index, threshold, info->extack);
 3166}
 3167
 3168static int
 3169devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
 3170				struct devlink_port *devlink_port,
 3171				struct devlink_sb *devlink_sb, u16 tc_index,
 3172				enum devlink_sb_pool_type pool_type,
 3173				enum devlink_command cmd,
 3174				u32 portid, u32 seq, int flags)
 3175{
 3176	const struct devlink_ops *ops = devlink->ops;
 3177	u16 pool_index;
 3178	u32 threshold;
 3179	void *hdr;
 3180	int err;
 3181
 3182	err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
 3183				       tc_index, pool_type,
 3184				       &pool_index, &threshold);
 3185	if (err)
 3186		return err;
 3187
 3188	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 3189	if (!hdr)
 3190		return -EMSGSIZE;
 3191
 3192	if (devlink_nl_put_handle(msg, devlink))
 3193		goto nla_put_failure;
 3194	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 3195		goto nla_put_failure;
 3196	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 3197		goto nla_put_failure;
 3198	if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
 3199		goto nla_put_failure;
 3200	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
 3201		goto nla_put_failure;
 3202	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 3203		goto nla_put_failure;
 3204	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
 3205		goto nla_put_failure;
 3206
 3207	if (ops->sb_occ_tc_port_bind_get) {
 3208		u32 cur;
 3209		u32 max;
 3210
 3211		err = ops->sb_occ_tc_port_bind_get(devlink_port,
 3212						   devlink_sb->index,
 3213						   tc_index, pool_type,
 3214						   &cur, &max);
 3215		if (err && err != -EOPNOTSUPP)
 3216			return err;
 3217		if (!err) {
 3218			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
 3219				goto nla_put_failure;
 3220			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
 3221				goto nla_put_failure;
 3222		}
 3223	}
 3224
 3225	genlmsg_end(msg, hdr);
 3226	return 0;
 3227
 3228nla_put_failure:
 3229	genlmsg_cancel(msg, hdr);
 3230	return -EMSGSIZE;
 3231}
 3232
 3233static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
 3234						   struct genl_info *info)
 3235{
 3236	struct devlink_port *devlink_port = info->user_ptr[1];
 3237	struct devlink *devlink = devlink_port->devlink;
 3238	struct devlink_sb *devlink_sb;
 3239	struct sk_buff *msg;
 3240	enum devlink_sb_pool_type pool_type;
 3241	u16 tc_index;
 3242	int err;
 3243
 3244	devlink_sb = devlink_sb_get_from_info(devlink, info);
 3245	if (IS_ERR(devlink_sb))
 3246		return PTR_ERR(devlink_sb);
 3247
 3248	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
 3249	if (err)
 3250		return err;
 3251
 3252	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
 3253						pool_type, &tc_index);
 3254	if (err)
 3255		return err;
 3256
 3257	if (!devlink->ops->sb_tc_pool_bind_get)
 3258		return -EOPNOTSUPP;
 3259
 3260	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 3261	if (!msg)
 3262		return -ENOMEM;
 3263
 3264	err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
 3265					      devlink_sb, tc_index, pool_type,
 3266					      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
 3267					      info->snd_portid,
 3268					      info->snd_seq, 0);
 3269	if (err) {
 3270		nlmsg_free(msg);
 3271		return err;
 3272	}
 3273
 3274	return genlmsg_reply(msg, info);
 3275}
 3276
 3277static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
 3278					int start, int *p_idx,
 3279					struct devlink *devlink,
 3280					struct devlink_sb *devlink_sb,
 3281					u32 portid, u32 seq)
 3282{
 3283	struct devlink_port *devlink_port;
 3284	unsigned long port_index;
 3285	u16 tc_index;
 3286	int err;
 3287
 3288	xa_for_each(&devlink->ports, port_index, devlink_port) {
 3289		for (tc_index = 0;
 3290		     tc_index < devlink_sb->ingress_tc_count; tc_index++) {
 3291			if (*p_idx < start) {
 3292				(*p_idx)++;
 3293				continue;
 3294			}
 3295			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
 3296							      devlink_port,
 3297							      devlink_sb,
 3298							      tc_index,
 3299							      DEVLINK_SB_POOL_TYPE_INGRESS,
 3300							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
 3301							      portid, seq,
 3302							      NLM_F_MULTI);
 3303			if (err)
 3304				return err;
 3305			(*p_idx)++;
 3306		}
 3307		for (tc_index = 0;
 3308		     tc_index < devlink_sb->egress_tc_count; tc_index++) {
 3309			if (*p_idx < start) {
 3310				(*p_idx)++;
 3311				continue;
 3312			}
 3313			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
 3314							      devlink_port,
 3315							      devlink_sb,
 3316							      tc_index,
 3317							      DEVLINK_SB_POOL_TYPE_EGRESS,
 3318							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
 3319							      portid, seq,
 3320							      NLM_F_MULTI);
 3321			if (err)
 3322				return err;
 3323			(*p_idx)++;
 3324		}
 3325	}
 3326	return 0;
 3327}
 3328
 3329static int
 3330devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
 3331					  struct netlink_callback *cb)
 3332{
 3333	struct devlink *devlink;
 3334	struct devlink_sb *devlink_sb;
 3335	int start = cb->args[0];
 3336	unsigned long index;
 3337	int idx = 0;
 3338	int err = 0;
 3339
 3340	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 3341		if (!devlink->ops->sb_tc_pool_bind_get)
 3342			goto retry;
 3343
 3344		devl_lock(devlink);
 3345		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 3346			err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
 3347							   devlink,
 3348							   devlink_sb,
 3349							   NETLINK_CB(cb->skb).portid,
 3350							   cb->nlh->nlmsg_seq);
 3351			if (err == -EOPNOTSUPP) {
 3352				err = 0;
 3353			} else if (err) {
 3354				devl_unlock(devlink);
 3355				devlink_put(devlink);
 3356				goto out;
 3357			}
 3358		}
 3359		devl_unlock(devlink);
 3360retry:
 3361		devlink_put(devlink);
 3362	}
 3363out:
 3364	if (err != -EMSGSIZE)
 3365		return err;
 3366
 3367	cb->args[0] = idx;
 3368	return msg->len;
 3369}
 3370
 3371static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
 3372				       unsigned int sb_index, u16 tc_index,
 3373				       enum devlink_sb_pool_type pool_type,
 3374				       u16 pool_index, u32 threshold,
 3375				       struct netlink_ext_ack *extack)
 3376
 3377{
 3378	const struct devlink_ops *ops = devlink_port->devlink->ops;
 3379
 3380	if (ops->sb_tc_pool_bind_set)
 3381		return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
 3382						tc_index, pool_type,
 3383						pool_index, threshold, extack);
 3384	return -EOPNOTSUPP;
 3385}
 3386
 3387static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
 3388						   struct genl_info *info)
 3389{
 3390	struct devlink_port *devlink_port = info->user_ptr[1];
 3391	struct devlink *devlink = info->user_ptr[0];
 3392	enum devlink_sb_pool_type pool_type;
 3393	struct devlink_sb *devlink_sb;
 3394	u16 tc_index;
 3395	u16 pool_index;
 3396	u32 threshold;
 3397	int err;
 3398
 3399	devlink_sb = devlink_sb_get_from_info(devlink, info);
 3400	if (IS_ERR(devlink_sb))
 3401		return PTR_ERR(devlink_sb);
 3402
 3403	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
 3404	if (err)
 3405		return err;
 3406
 3407	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
 3408						pool_type, &tc_index);
 3409	if (err)
 3410		return err;
 3411
 3412	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 3413						  &pool_index);
 3414	if (err)
 3415		return err;
 3416
 3417	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
 3418		return -EINVAL;
 3419
 3420	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
 3421	return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
 3422					   tc_index, pool_type,
 3423					   pool_index, threshold, info->extack);
 3424}
 3425
 3426static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
 3427					       struct genl_info *info)
 3428{
 3429	struct devlink *devlink = info->user_ptr[0];
 3430	const struct devlink_ops *ops = devlink->ops;
 3431	struct devlink_sb *devlink_sb;
 3432
 3433	devlink_sb = devlink_sb_get_from_info(devlink, info);
 3434	if (IS_ERR(devlink_sb))
 3435		return PTR_ERR(devlink_sb);
 3436
 3437	if (ops->sb_occ_snapshot)
 3438		return ops->sb_occ_snapshot(devlink, devlink_sb->index);
 3439	return -EOPNOTSUPP;
 3440}
 3441
 3442static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
 3443						struct genl_info *info)
 3444{
 3445	struct devlink *devlink = info->user_ptr[0];
 3446	const struct devlink_ops *ops = devlink->ops;
 3447	struct devlink_sb *devlink_sb;
 3448
 3449	devlink_sb = devlink_sb_get_from_info(devlink, info);
 3450	if (IS_ERR(devlink_sb))
 3451		return PTR_ERR(devlink_sb);
 3452
 3453	if (ops->sb_occ_max_clear)
 3454		return ops->sb_occ_max_clear(devlink, devlink_sb->index);
 3455	return -EOPNOTSUPP;
 3456}
 3457
 3458static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
 3459				   enum devlink_command cmd, u32 portid,
 3460				   u32 seq, int flags)
 3461{
 3462	const struct devlink_ops *ops = devlink->ops;
 3463	enum devlink_eswitch_encap_mode encap_mode;
 3464	u8 inline_mode;
 3465	void *hdr;
 3466	int err = 0;
 3467	u16 mode;
 3468
 3469	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 3470	if (!hdr)
 3471		return -EMSGSIZE;
 3472
 3473	err = devlink_nl_put_handle(msg, devlink);
 3474	if (err)
 3475		goto nla_put_failure;
 3476
 3477	if (ops->eswitch_mode_get) {
 3478		err = ops->eswitch_mode_get(devlink, &mode);
 3479		if (err)
 3480			goto nla_put_failure;
 3481		err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
 3482		if (err)
 3483			goto nla_put_failure;
 3484	}
 3485
 3486	if (ops->eswitch_inline_mode_get) {
 3487		err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
 3488		if (err)
 3489			goto nla_put_failure;
 3490		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
 3491				 inline_mode);
 3492		if (err)
 3493			goto nla_put_failure;
 3494	}
 3495
 3496	if (ops->eswitch_encap_mode_get) {
 3497		err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
 3498		if (err)
 3499			goto nla_put_failure;
 3500		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
 3501		if (err)
 3502			goto nla_put_failure;
 3503	}
 3504
 3505	genlmsg_end(msg, hdr);
 3506	return 0;
 3507
 3508nla_put_failure:
 3509	genlmsg_cancel(msg, hdr);
 3510	return err;
 3511}
 3512
 3513static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
 3514					   struct genl_info *info)
 3515{
 3516	struct devlink *devlink = info->user_ptr[0];
 3517	struct sk_buff *msg;
 3518	int err;
 3519
 3520	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 3521	if (!msg)
 3522		return -ENOMEM;
 3523
 3524	err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
 3525				      info->snd_portid, info->snd_seq, 0);
 3526
 3527	if (err) {
 3528		nlmsg_free(msg);
 3529		return err;
 3530	}
 3531
 3532	return genlmsg_reply(msg, info);
 3533}
 3534
 3535static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
 3536				    struct netlink_ext_ack *extack)
 3537{
 3538	struct devlink_rate *devlink_rate;
 3539
 3540	list_for_each_entry(devlink_rate, &devlink->rate_list, list)
 3541		if (devlink_rate_is_node(devlink_rate)) {
 3542			NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
 3543			return -EBUSY;
 3544		}
 3545	return 0;
 3546}
 3547
 3548static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
 3549					   struct genl_info *info)
 3550{
 3551	struct devlink *devlink = info->user_ptr[0];
 3552	const struct devlink_ops *ops = devlink->ops;
 3553	enum devlink_eswitch_encap_mode encap_mode;
 3554	u8 inline_mode;
 3555	int err = 0;
 3556	u16 mode;
 3557
 3558	if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
 3559		if (!ops->eswitch_mode_set)
 3560			return -EOPNOTSUPP;
 3561		mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
 3562		err = devlink_rate_nodes_check(devlink, mode, info->extack);
 3563		if (err)
 3564			return err;
 3565		err = ops->eswitch_mode_set(devlink, mode, info->extack);
 3566		if (err)
 3567			return err;
 3568	}
 3569
 3570	if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
 3571		if (!ops->eswitch_inline_mode_set)
 3572			return -EOPNOTSUPP;
 3573		inline_mode = nla_get_u8(
 3574				info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
 3575		err = ops->eswitch_inline_mode_set(devlink, inline_mode,
 3576						   info->extack);
 3577		if (err)
 3578			return err;
 3579	}
 3580
 3581	if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
 3582		if (!ops->eswitch_encap_mode_set)
 3583			return -EOPNOTSUPP;
 3584		encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
 3585		err = ops->eswitch_encap_mode_set(devlink, encap_mode,
 3586						  info->extack);
 3587		if (err)
 3588			return err;
 3589	}
 3590
 3591	return 0;
 3592}
 3593
 3594int devlink_dpipe_match_put(struct sk_buff *skb,
 3595			    struct devlink_dpipe_match *match)
 3596{
 3597	struct devlink_dpipe_header *header = match->header;
 3598	struct devlink_dpipe_field *field = &header->fields[match->field_id];
 3599	struct nlattr *match_attr;
 3600
 3601	match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
 3602	if (!match_attr)
 3603		return -EMSGSIZE;
 3604
 3605	if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
 3606	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
 3607	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
 3608	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
 3609	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
 3610		goto nla_put_failure;
 3611
 3612	nla_nest_end(skb, match_attr);
 3613	return 0;
 3614
 3615nla_put_failure:
 3616	nla_nest_cancel(skb, match_attr);
 3617	return -EMSGSIZE;
 3618}
 3619EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
 3620
 3621static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
 3622				     struct sk_buff *skb)
 3623{
 3624	struct nlattr *matches_attr;
 3625
 3626	matches_attr = nla_nest_start_noflag(skb,
 3627					     DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
 3628	if (!matches_attr)
 3629		return -EMSGSIZE;
 3630
 3631	if (table->table_ops->matches_dump(table->priv, skb))
 3632		goto nla_put_failure;
 3633
 3634	nla_nest_end(skb, matches_attr);
 3635	return 0;
 3636
 3637nla_put_failure:
 3638	nla_nest_cancel(skb, matches_attr);
 3639	return -EMSGSIZE;
 3640}
 3641
 3642int devlink_dpipe_action_put(struct sk_buff *skb,
 3643			     struct devlink_dpipe_action *action)
 3644{
 3645	struct devlink_dpipe_header *header = action->header;
 3646	struct devlink_dpipe_field *field = &header->fields[action->field_id];
 3647	struct nlattr *action_attr;
 3648
 3649	action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
 3650	if (!action_attr)
 3651		return -EMSGSIZE;
 3652
 3653	if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
 3654	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
 3655	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
 3656	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
 3657	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
 3658		goto nla_put_failure;
 3659
 3660	nla_nest_end(skb, action_attr);
 3661	return 0;
 3662
 3663nla_put_failure:
 3664	nla_nest_cancel(skb, action_attr);
 3665	return -EMSGSIZE;
 3666}
 3667EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
 3668
 3669static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
 3670				     struct sk_buff *skb)
 3671{
 3672	struct nlattr *actions_attr;
 3673
 3674	actions_attr = nla_nest_start_noflag(skb,
 3675					     DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
 3676	if (!actions_attr)
 3677		return -EMSGSIZE;
 3678
 3679	if (table->table_ops->actions_dump(table->priv, skb))
 3680		goto nla_put_failure;
 3681
 3682	nla_nest_end(skb, actions_attr);
 3683	return 0;
 3684
 3685nla_put_failure:
 3686	nla_nest_cancel(skb, actions_attr);
 3687	return -EMSGSIZE;
 3688}
 3689
 3690static int devlink_dpipe_table_put(struct sk_buff *skb,
 3691				   struct devlink_dpipe_table *table)
 3692{
 3693	struct nlattr *table_attr;
 3694	u64 table_size;
 3695
 3696	table_size = table->table_ops->size_get(table->priv);
 3697	table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
 3698	if (!table_attr)
 3699		return -EMSGSIZE;
 3700
 3701	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
 3702	    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
 3703			      DEVLINK_ATTR_PAD))
 3704		goto nla_put_failure;
 3705	if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
 3706		       table->counters_enabled))
 3707		goto nla_put_failure;
 3708
 3709	if (table->resource_valid) {
 3710		if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
 3711				      table->resource_id, DEVLINK_ATTR_PAD) ||
 3712		    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
 3713				      table->resource_units, DEVLINK_ATTR_PAD))
 3714			goto nla_put_failure;
 3715	}
 3716	if (devlink_dpipe_matches_put(table, skb))
 3717		goto nla_put_failure;
 3718
 3719	if (devlink_dpipe_actions_put(table, skb))
 3720		goto nla_put_failure;
 3721
 3722	nla_nest_end(skb, table_attr);
 3723	return 0;
 3724
 3725nla_put_failure:
 3726	nla_nest_cancel(skb, table_attr);
 3727	return -EMSGSIZE;
 3728}
 3729
 3730static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
 3731					    struct genl_info *info)
 3732{
 3733	int err;
 3734
 3735	if (*pskb) {
 3736		err = genlmsg_reply(*pskb, info);
 3737		if (err)
 3738			return err;
 3739	}
 3740	*pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
 3741	if (!*pskb)
 3742		return -ENOMEM;
 3743	return 0;
 3744}
 3745
 3746static int devlink_dpipe_tables_fill(struct genl_info *info,
 3747				     enum devlink_command cmd, int flags,
 3748				     struct list_head *dpipe_tables,
 3749				     const char *table_name)
 3750{
 3751	struct devlink *devlink = info->user_ptr[0];
 3752	struct devlink_dpipe_table *table;
 3753	struct nlattr *tables_attr;
 3754	struct sk_buff *skb = NULL;
 3755	struct nlmsghdr *nlh;
 3756	bool incomplete;
 3757	void *hdr;
 3758	int i;
 3759	int err;
 3760
 3761	table = list_first_entry(dpipe_tables,
 3762				 struct devlink_dpipe_table, list);
 3763start_again:
 3764	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
 3765	if (err)
 3766		return err;
 3767
 3768	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
 3769			  &devlink_nl_family, NLM_F_MULTI, cmd);
 3770	if (!hdr) {
 3771		nlmsg_free(skb);
 3772		return -EMSGSIZE;
 3773	}
 3774
 3775	if (devlink_nl_put_handle(skb, devlink))
 3776		goto nla_put_failure;
 3777	tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
 3778	if (!tables_attr)
 3779		goto nla_put_failure;
 3780
 3781	i = 0;
 3782	incomplete = false;
 3783	list_for_each_entry_from(table, dpipe_tables, list) {
 3784		if (!table_name) {
 3785			err = devlink_dpipe_table_put(skb, table);
 3786			if (err) {
 3787				if (!i)
 3788					goto err_table_put;
 3789				incomplete = true;
 3790				break;
 3791			}
 3792		} else {
 3793			if (!strcmp(table->name, table_name)) {
 3794				err = devlink_dpipe_table_put(skb, table);
 3795				if (err)
 3796					break;
 3797			}
 3798		}
 3799		i++;
 3800	}
 3801
 3802	nla_nest_end(skb, tables_attr);
 3803	genlmsg_end(skb, hdr);
 3804	if (incomplete)
 3805		goto start_again;
 3806
 3807send_done:
 3808	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
 3809			NLMSG_DONE, 0, flags | NLM_F_MULTI);
 3810	if (!nlh) {
 3811		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
 3812		if (err)
 3813			return err;
 3814		goto send_done;
 3815	}
 3816
 3817	return genlmsg_reply(skb, info);
 3818
 3819nla_put_failure:
 3820	err = -EMSGSIZE;
 3821err_table_put:
 3822	nlmsg_free(skb);
 3823	return err;
 3824}
 3825
 3826static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
 3827					  struct genl_info *info)
 3828{
 3829	struct devlink *devlink = info->user_ptr[0];
 3830	const char *table_name =  NULL;
 3831
 3832	if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
 3833		table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
 3834
 3835	return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
 3836					 &devlink->dpipe_table_list,
 3837					 table_name);
 3838}
 3839
 3840static int devlink_dpipe_value_put(struct sk_buff *skb,
 3841				   struct devlink_dpipe_value *value)
 3842{
 3843	if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
 3844		    value->value_size, value->value))
 3845		return -EMSGSIZE;
 3846	if (value->mask)
 3847		if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
 3848			    value->value_size, value->mask))
 3849			return -EMSGSIZE;
 3850	if (value->mapping_valid)
 3851		if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
 3852				value->mapping_value))
 3853			return -EMSGSIZE;
 3854	return 0;
 3855}
 3856
 3857static int devlink_dpipe_action_value_put(struct sk_buff *skb,
 3858					  struct devlink_dpipe_value *value)
 3859{
 3860	if (!value->action)
 3861		return -EINVAL;
 3862	if (devlink_dpipe_action_put(skb, value->action))
 3863		return -EMSGSIZE;
 3864	if (devlink_dpipe_value_put(skb, value))
 3865		return -EMSGSIZE;
 3866	return 0;
 3867}
 3868
 3869static int devlink_dpipe_action_values_put(struct sk_buff *skb,
 3870					   struct devlink_dpipe_value *values,
 3871					   unsigned int values_count)
 3872{
 3873	struct nlattr *action_attr;
 3874	int i;
 3875	int err;
 3876
 3877	for (i = 0; i < values_count; i++) {
 3878		action_attr = nla_nest_start_noflag(skb,
 3879						    DEVLINK_ATTR_DPIPE_ACTION_VALUE);
 3880		if (!action_attr)
 3881			return -EMSGSIZE;
 3882		err = devlink_dpipe_action_value_put(skb, &values[i]);
 3883		if (err)
 3884			goto err_action_value_put;
 3885		nla_nest_end(skb, action_attr);
 3886	}
 3887	return 0;
 3888
 3889err_action_value_put:
 3890	nla_nest_cancel(skb, action_attr);
 3891	return err;
 3892}
 3893
 3894static int devlink_dpipe_match_value_put(struct sk_buff *skb,
 3895					 struct devlink_dpipe_value *value)
 3896{
 3897	if (!value->match)
 3898		return -EINVAL;
 3899	if (devlink_dpipe_match_put(skb, value->match))
 3900		return -EMSGSIZE;
 3901	if (devlink_dpipe_value_put(skb, value))
 3902		return -EMSGSIZE;
 3903	return 0;
 3904}
 3905
 3906static int devlink_dpipe_match_values_put(struct sk_buff *skb,
 3907					  struct devlink_dpipe_value *values,
 3908					  unsigned int values_count)
 3909{
 3910	struct nlattr *match_attr;
 3911	int i;
 3912	int err;
 3913
 3914	for (i = 0; i < values_count; i++) {
 3915		match_attr = nla_nest_start_noflag(skb,
 3916						   DEVLINK_ATTR_DPIPE_MATCH_VALUE);
 3917		if (!match_attr)
 3918			return -EMSGSIZE;
 3919		err = devlink_dpipe_match_value_put(skb, &values[i]);
 3920		if (err)
 3921			goto err_match_value_put;
 3922		nla_nest_end(skb, match_attr);
 3923	}
 3924	return 0;
 3925
 3926err_match_value_put:
 3927	nla_nest_cancel(skb, match_attr);
 3928	return err;
 3929}
 3930
 3931static int devlink_dpipe_entry_put(struct sk_buff *skb,
 3932				   struct devlink_dpipe_entry *entry)
 3933{
 3934	struct nlattr *entry_attr, *matches_attr, *actions_attr;
 3935	int err;
 3936
 3937	entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
 3938	if (!entry_attr)
 3939		return  -EMSGSIZE;
 3940
 3941	if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
 3942			      DEVLINK_ATTR_PAD))
 3943		goto nla_put_failure;
 3944	if (entry->counter_valid)
 3945		if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
 3946				      entry->counter, DEVLINK_ATTR_PAD))
 3947			goto nla_put_failure;
 3948
 3949	matches_attr = nla_nest_start_noflag(skb,
 3950					     DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
 3951	if (!matches_attr)
 3952		goto nla_put_failure;
 3953
 3954	err = devlink_dpipe_match_values_put(skb, entry->match_values,
 3955					     entry->match_values_count);
 3956	if (err) {
 3957		nla_nest_cancel(skb, matches_attr);
 3958		goto err_match_values_put;
 3959	}
 3960	nla_nest_end(skb, matches_attr);
 3961
 3962	actions_attr = nla_nest_start_noflag(skb,
 3963					     DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
 3964	if (!actions_attr)
 3965		goto nla_put_failure;
 3966
 3967	err = devlink_dpipe_action_values_put(skb, entry->action_values,
 3968					      entry->action_values_count);
 3969	if (err) {
 3970		nla_nest_cancel(skb, actions_attr);
 3971		goto err_action_values_put;
 3972	}
 3973	nla_nest_end(skb, actions_attr);
 3974
 3975	nla_nest_end(skb, entry_attr);
 3976	return 0;
 3977
 3978nla_put_failure:
 3979	err = -EMSGSIZE;
 3980err_match_values_put:
 3981err_action_values_put:
 3982	nla_nest_cancel(skb, entry_attr);
 3983	return err;
 3984}
 3985
 3986static struct devlink_dpipe_table *
 3987devlink_dpipe_table_find(struct list_head *dpipe_tables,
 3988			 const char *table_name, struct devlink *devlink)
 3989{
 3990	struct devlink_dpipe_table *table;
 3991	list_for_each_entry_rcu(table, dpipe_tables, list,
 3992				lockdep_is_held(&devlink->lock)) {
 3993		if (!strcmp(table->name, table_name))
 3994			return table;
 3995	}
 3996	return NULL;
 3997}
 3998
 3999int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
 4000{
 4001	struct devlink *devlink;
 4002	int err;
 4003
 4004	err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
 4005					       dump_ctx->info);
 4006	if (err)
 4007		return err;
 4008
 4009	dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
 4010				    dump_ctx->info->snd_portid,
 4011				    dump_ctx->info->snd_seq,
 4012				    &devlink_nl_family, NLM_F_MULTI,
 4013				    dump_ctx->cmd);
 4014	if (!dump_ctx->hdr)
 4015		goto nla_put_failure;
 4016
 4017	devlink = dump_ctx->info->user_ptr[0];
 4018	if (devlink_nl_put_handle(dump_ctx->skb, devlink))
 4019		goto nla_put_failure;
 4020	dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
 4021					       DEVLINK_ATTR_DPIPE_ENTRIES);
 4022	if (!dump_ctx->nest)
 4023		goto nla_put_failure;
 4024	return 0;
 4025
 4026nla_put_failure:
 4027	nlmsg_free(dump_ctx->skb);
 4028	return -EMSGSIZE;
 4029}
 4030EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
 4031
 4032int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
 4033				   struct devlink_dpipe_entry *entry)
 4034{
 4035	return devlink_dpipe_entry_put(dump_ctx->skb, entry);
 4036}
 4037EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
 4038
 4039int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
 4040{
 4041	nla_nest_end(dump_ctx->skb, dump_ctx->nest);
 4042	genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
 4043	return 0;
 4044}
 4045EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
 4046
 4047void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
 4048
 4049{
 4050	unsigned int value_count, value_index;
 4051	struct devlink_dpipe_value *value;
 4052
 4053	value = entry->action_values;
 4054	value_count = entry->action_values_count;
 4055	for (value_index = 0; value_index < value_count; value_index++) {
 4056		kfree(value[value_index].value);
 4057		kfree(value[value_index].mask);
 4058	}
 4059
 4060	value = entry->match_values;
 4061	value_count = entry->match_values_count;
 4062	for (value_index = 0; value_index < value_count; value_index++) {
 4063		kfree(value[value_index].value);
 4064		kfree(value[value_index].mask);
 4065	}
 4066}
 4067EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
 4068
 4069static int devlink_dpipe_entries_fill(struct genl_info *info,
 4070				      enum devlink_command cmd, int flags,
 4071				      struct devlink_dpipe_table *table)
 4072{
 4073	struct devlink_dpipe_dump_ctx dump_ctx;
 4074	struct nlmsghdr *nlh;
 4075	int err;
 4076
 4077	dump_ctx.skb = NULL;
 4078	dump_ctx.cmd = cmd;
 4079	dump_ctx.info = info;
 4080
 4081	err = table->table_ops->entries_dump(table->priv,
 4082					     table->counters_enabled,
 4083					     &dump_ctx);
 4084	if (err)
 4085		return err;
 4086
 4087send_done:
 4088	nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
 4089			NLMSG_DONE, 0, flags | NLM_F_MULTI);
 4090	if (!nlh) {
 4091		err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
 4092		if (err)
 4093			return err;
 4094		goto send_done;
 4095	}
 4096	return genlmsg_reply(dump_ctx.skb, info);
 4097}
 4098
 4099static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
 4100					    struct genl_info *info)
 4101{
 4102	struct devlink *devlink = info->user_ptr[0];
 4103	struct devlink_dpipe_table *table;
 4104	const char *table_name;
 4105
 4106	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
 4107		return -EINVAL;
 4108
 4109	table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
 4110	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
 4111					 table_name, devlink);
 4112	if (!table)
 4113		return -EINVAL;
 4114
 4115	if (!table->table_ops->entries_dump)
 4116		return -EINVAL;
 4117
 4118	return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
 4119					  0, table);
 4120}
 4121
 4122static int devlink_dpipe_fields_put(struct sk_buff *skb,
 4123				    const struct devlink_dpipe_header *header)
 4124{
 4125	struct devlink_dpipe_field *field;
 4126	struct nlattr *field_attr;
 4127	int i;
 4128
 4129	for (i = 0; i < header->fields_count; i++) {
 4130		field = &header->fields[i];
 4131		field_attr = nla_nest_start_noflag(skb,
 4132						   DEVLINK_ATTR_DPIPE_FIELD);
 4133		if (!field_attr)
 4134			return -EMSGSIZE;
 4135		if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
 4136		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
 4137		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
 4138		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
 4139			goto nla_put_failure;
 4140		nla_nest_end(skb, field_attr);
 4141	}
 4142	return 0;
 4143
 4144nla_put_failure:
 4145	nla_nest_cancel(skb, field_attr);
 4146	return -EMSGSIZE;
 4147}
 4148
 4149static int devlink_dpipe_header_put(struct sk_buff *skb,
 4150				    struct devlink_dpipe_header *header)
 4151{
 4152	struct nlattr *fields_attr, *header_attr;
 4153	int err;
 4154
 4155	header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
 4156	if (!header_attr)
 4157		return -EMSGSIZE;
 4158
 4159	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
 4160	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
 4161	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
 4162		goto nla_put_failure;
 4163
 4164	fields_attr = nla_nest_start_noflag(skb,
 4165					    DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
 4166	if (!fields_attr)
 4167		goto nla_put_failure;
 4168
 4169	err = devlink_dpipe_fields_put(skb, header);
 4170	if (err) {
 4171		nla_nest_cancel(skb, fields_attr);
 4172		goto nla_put_failure;
 4173	}
 4174	nla_nest_end(skb, fields_attr);
 4175	nla_nest_end(skb, header_attr);
 4176	return 0;
 4177
 4178nla_put_failure:
 4179	err = -EMSGSIZE;
 4180	nla_nest_cancel(skb, header_attr);
 4181	return err;
 4182}
 4183
 4184static int devlink_dpipe_headers_fill(struct genl_info *info,
 4185				      enum devlink_command cmd, int flags,
 4186				      struct devlink_dpipe_headers *
 4187				      dpipe_headers)
 4188{
 4189	struct devlink *devlink = info->user_ptr[0];
 4190	struct nlattr *headers_attr;
 4191	struct sk_buff *skb = NULL;
 4192	struct nlmsghdr *nlh;
 4193	void *hdr;
 4194	int i, j;
 4195	int err;
 4196
 4197	i = 0;
 4198start_again:
 4199	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
 4200	if (err)
 4201		return err;
 4202
 4203	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
 4204			  &devlink_nl_family, NLM_F_MULTI, cmd);
 4205	if (!hdr) {
 4206		nlmsg_free(skb);
 4207		return -EMSGSIZE;
 4208	}
 4209
 4210	if (devlink_nl_put_handle(skb, devlink))
 4211		goto nla_put_failure;
 4212	headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
 4213	if (!headers_attr)
 4214		goto nla_put_failure;
 4215
 4216	j = 0;
 4217	for (; i < dpipe_headers->headers_count; i++) {
 4218		err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
 4219		if (err) {
 4220			if (!j)
 4221				goto err_table_put;
 4222			break;
 4223		}
 4224		j++;
 4225	}
 4226	nla_nest_end(skb, headers_attr);
 4227	genlmsg_end(skb, hdr);
 4228	if (i != dpipe_headers->headers_count)
 4229		goto start_again;
 4230
 4231send_done:
 4232	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
 4233			NLMSG_DONE, 0, flags | NLM_F_MULTI);
 4234	if (!nlh) {
 4235		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
 4236		if (err)
 4237			return err;
 4238		goto send_done;
 4239	}
 4240	return genlmsg_reply(skb, info);
 4241
 4242nla_put_failure:
 4243	err = -EMSGSIZE;
 4244err_table_put:
 4245	nlmsg_free(skb);
 4246	return err;
 4247}
 4248
 4249static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
 4250					    struct genl_info *info)
 4251{
 4252	struct devlink *devlink = info->user_ptr[0];
 4253
 4254	if (!devlink->dpipe_headers)
 4255		return -EOPNOTSUPP;
 4256	return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
 4257					  0, devlink->dpipe_headers);
 4258}
 4259
 4260static int devlink_dpipe_table_counters_set(struct devlink *devlink,
 4261					    const char *table_name,
 4262					    bool enable)
 4263{
 4264	struct devlink_dpipe_table *table;
 4265
 4266	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
 4267					 table_name, devlink);
 4268	if (!table)
 4269		return -EINVAL;
 4270
 4271	if (table->counter_control_extern)
 4272		return -EOPNOTSUPP;
 4273
 4274	if (!(table->counters_enabled ^ enable))
 4275		return 0;
 4276
 4277	table->counters_enabled = enable;
 4278	if (table->table_ops->counters_set_update)
 4279		table->table_ops->counters_set_update(table->priv, enable);
 4280	return 0;
 4281}
 4282
 4283static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
 4284						   struct genl_info *info)
 4285{
 4286	struct devlink *devlink = info->user_ptr[0];
 4287	const char *table_name;
 4288	bool counters_enable;
 4289
 4290	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
 4291	    GENL_REQ_ATTR_CHECK(info,
 4292				DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
 4293		return -EINVAL;
 4294
 4295	table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
 4296	counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
 4297
 4298	return devlink_dpipe_table_counters_set(devlink, table_name,
 4299						counters_enable);
 4300}
 4301
 4302static struct devlink_resource *
 4303devlink_resource_find(struct devlink *devlink,
 4304		      struct devlink_resource *resource, u64 resource_id)
 4305{
 4306	struct list_head *resource_list;
 4307
 4308	if (resource)
 4309		resource_list = &resource->resource_list;
 4310	else
 4311		resource_list = &devlink->resource_list;
 4312
 4313	list_for_each_entry(resource, resource_list, list) {
 4314		struct devlink_resource *child_resource;
 4315
 4316		if (resource->id == resource_id)
 4317			return resource;
 4318
 4319		child_resource = devlink_resource_find(devlink, resource,
 4320						       resource_id);
 4321		if (child_resource)
 4322			return child_resource;
 4323	}
 4324	return NULL;
 4325}
 4326
 4327static void
 4328devlink_resource_validate_children(struct devlink_resource *resource)
 4329{
 4330	struct devlink_resource *child_resource;
 4331	bool size_valid = true;
 4332	u64 parts_size = 0;
 4333
 4334	if (list_empty(&resource->resource_list))
 4335		goto out;
 4336
 4337	list_for_each_entry(child_resource, &resource->resource_list, list)
 4338		parts_size += child_resource->size_new;
 4339
 4340	if (parts_size > resource->size_new)
 4341		size_valid = false;
 4342out:
 4343	resource->size_valid = size_valid;
 4344}
 4345
 4346static int
 4347devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
 4348			       struct netlink_ext_ack *extack)
 4349{
 4350	u64 reminder;
 4351	int err = 0;
 4352
 4353	if (size > resource->size_params.size_max) {
 4354		NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
 4355		err = -EINVAL;
 4356	}
 4357
 4358	if (size < resource->size_params.size_min) {
 4359		NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
 4360		err = -EINVAL;
 4361	}
 4362
 4363	div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
 4364	if (reminder) {
 4365		NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
 4366		err = -EINVAL;
 4367	}
 4368
 4369	return err;
 4370}
 4371
 4372static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
 4373				       struct genl_info *info)
 4374{
 4375	struct devlink *devlink = info->user_ptr[0];
 4376	struct devlink_resource *resource;
 4377	u64 resource_id;
 4378	u64 size;
 4379	int err;
 4380
 4381	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
 4382	    GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
 4383		return -EINVAL;
 4384	resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
 4385
 4386	resource = devlink_resource_find(devlink, NULL, resource_id);
 4387	if (!resource)
 4388		return -EINVAL;
 4389
 4390	size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
 4391	err = devlink_resource_validate_size(resource, size, info->extack);
 4392	if (err)
 4393		return err;
 4394
 4395	resource->size_new = size;
 4396	devlink_resource_validate_children(resource);
 4397	if (resource->parent)
 4398		devlink_resource_validate_children(resource->parent);
 4399	return 0;
 4400}
 4401
 4402static int
 4403devlink_resource_size_params_put(struct devlink_resource *resource,
 4404				 struct sk_buff *skb)
 4405{
 4406	struct devlink_resource_size_params *size_params;
 4407
 4408	size_params = &resource->size_params;
 4409	if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
 4410			      size_params->size_granularity, DEVLINK_ATTR_PAD) ||
 4411	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
 4412			      size_params->size_max, DEVLINK_ATTR_PAD) ||
 4413	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
 4414			      size_params->size_min, DEVLINK_ATTR_PAD) ||
 4415	    nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
 4416		return -EMSGSIZE;
 4417	return 0;
 4418}
 4419
 4420static int devlink_resource_occ_put(struct devlink_resource *resource,
 4421				    struct sk_buff *skb)
 4422{
 4423	if (!resource->occ_get)
 4424		return 0;
 4425	return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
 4426				 resource->occ_get(resource->occ_get_priv),
 4427				 DEVLINK_ATTR_PAD);
 4428}
 4429
 4430static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
 4431				struct devlink_resource *resource)
 4432{
 4433	struct devlink_resource *child_resource;
 4434	struct nlattr *child_resource_attr;
 4435	struct nlattr *resource_attr;
 4436
 4437	resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
 4438	if (!resource_attr)
 4439		return -EMSGSIZE;
 4440
 4441	if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
 4442	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
 4443			      DEVLINK_ATTR_PAD) ||
 4444	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
 4445			      DEVLINK_ATTR_PAD))
 4446		goto nla_put_failure;
 4447	if (resource->size != resource->size_new &&
 4448	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
 4449			      resource->size_new, DEVLINK_ATTR_PAD))
 4450		goto nla_put_failure;
 4451	if (devlink_resource_occ_put(resource, skb))
 4452		goto nla_put_failure;
 4453	if (devlink_resource_size_params_put(resource, skb))
 4454		goto nla_put_failure;
 4455	if (list_empty(&resource->resource_list))
 4456		goto out;
 4457
 4458	if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
 4459		       resource->size_valid))
 4460		goto nla_put_failure;
 4461
 4462	child_resource_attr = nla_nest_start_noflag(skb,
 4463						    DEVLINK_ATTR_RESOURCE_LIST);
 4464	if (!child_resource_attr)
 4465		goto nla_put_failure;
 4466
 4467	list_for_each_entry(child_resource, &resource->resource_list, list) {
 4468		if (devlink_resource_put(devlink, skb, child_resource))
 4469			goto resource_put_failure;
 4470	}
 4471
 4472	nla_nest_end(skb, child_resource_attr);
 4473out:
 4474	nla_nest_end(skb, resource_attr);
 4475	return 0;
 4476
 4477resource_put_failure:
 4478	nla_nest_cancel(skb, child_resource_attr);
 4479nla_put_failure:
 4480	nla_nest_cancel(skb, resource_attr);
 4481	return -EMSGSIZE;
 4482}
 4483
 4484static int devlink_resource_fill(struct genl_info *info,
 4485				 enum devlink_command cmd, int flags)
 4486{
 4487	struct devlink *devlink = info->user_ptr[0];
 4488	struct devlink_resource *resource;
 4489	struct nlattr *resources_attr;
 4490	struct sk_buff *skb = NULL;
 4491	struct nlmsghdr *nlh;
 4492	bool incomplete;
 4493	void *hdr;
 4494	int i;
 4495	int err;
 4496
 4497	resource = list_first_entry(&devlink->resource_list,
 4498				    struct devlink_resource, list);
 4499start_again:
 4500	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
 4501	if (err)
 4502		return err;
 4503
 4504	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
 4505			  &devlink_nl_family, NLM_F_MULTI, cmd);
 4506	if (!hdr) {
 4507		nlmsg_free(skb);
 4508		return -EMSGSIZE;
 4509	}
 4510
 4511	if (devlink_nl_put_handle(skb, devlink))
 4512		goto nla_put_failure;
 4513
 4514	resources_attr = nla_nest_start_noflag(skb,
 4515					       DEVLINK_ATTR_RESOURCE_LIST);
 4516	if (!resources_attr)
 4517		goto nla_put_failure;
 4518
 4519	incomplete = false;
 4520	i = 0;
 4521	list_for_each_entry_from(resource, &devlink->resource_list, list) {
 4522		err = devlink_resource_put(devlink, skb, resource);
 4523		if (err) {
 4524			if (!i)
 4525				goto err_resource_put;
 4526			incomplete = true;
 4527			break;
 4528		}
 4529		i++;
 4530	}
 4531	nla_nest_end(skb, resources_attr);
 4532	genlmsg_end(skb, hdr);
 4533	if (incomplete)
 4534		goto start_again;
 4535send_done:
 4536	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
 4537			NLMSG_DONE, 0, flags | NLM_F_MULTI);
 4538	if (!nlh) {
 4539		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
 4540		if (err)
 4541			return err;
 4542		goto send_done;
 4543	}
 4544	return genlmsg_reply(skb, info);
 4545
 4546nla_put_failure:
 4547	err = -EMSGSIZE;
 4548err_resource_put:
 4549	nlmsg_free(skb);
 4550	return err;
 4551}
 4552
 4553static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
 4554					struct genl_info *info)
 4555{
 4556	struct devlink *devlink = info->user_ptr[0];
 4557
 4558	if (list_empty(&devlink->resource_list))
 4559		return -EOPNOTSUPP;
 4560
 4561	return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
 4562}
 4563
 4564static int
 4565devlink_resources_validate(struct devlink *devlink,
 4566			   struct devlink_resource *resource,
 4567			   struct genl_info *info)
 4568{
 4569	struct list_head *resource_list;
 4570	int err = 0;
 4571
 4572	if (resource)
 4573		resource_list = &resource->resource_list;
 4574	else
 4575		resource_list = &devlink->resource_list;
 4576
 4577	list_for_each_entry(resource, resource_list, list) {
 4578		if (!resource->size_valid)
 4579			return -EINVAL;
 4580		err = devlink_resources_validate(devlink, resource, info);
 4581		if (err)
 4582			return err;
 4583	}
 4584	return err;
 4585}
 4586
 4587static struct net *devlink_netns_get(struct sk_buff *skb,
 4588				     struct genl_info *info)
 4589{
 4590	struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
 4591	struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
 4592	struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
 4593	struct net *net;
 4594
 4595	if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
 4596		NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
 4597		return ERR_PTR(-EINVAL);
 4598	}
 4599
 4600	if (netns_pid_attr) {
 4601		net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
 4602	} else if (netns_fd_attr) {
 4603		net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
 4604	} else if (netns_id_attr) {
 4605		net = get_net_ns_by_id(sock_net(skb->sk),
 4606				       nla_get_u32(netns_id_attr));
 4607		if (!net)
 4608			net = ERR_PTR(-EINVAL);
 4609	} else {
 4610		WARN_ON(1);
 4611		net = ERR_PTR(-EINVAL);
 4612	}
 4613	if (IS_ERR(net)) {
 4614		NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
 4615		return ERR_PTR(-EINVAL);
 4616	}
 4617	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
 4618		put_net(net);
 4619		return ERR_PTR(-EPERM);
 4620	}
 4621	return net;
 4622}
 4623
 4624static void devlink_param_notify(struct devlink *devlink,
 4625				 unsigned int port_index,
 4626				 struct devlink_param_item *param_item,
 4627				 enum devlink_command cmd);
 4628
 4629static void devlink_ns_change_notify(struct devlink *devlink,
 4630				     struct net *dest_net, struct net *curr_net,
 4631				     bool new)
 4632{
 4633	struct devlink_param_item *param_item;
 4634	enum devlink_command cmd;
 4635
 4636	/* Userspace needs to be notified about devlink objects
 4637	 * removed from original and entering new network namespace.
 4638	 * The rest of the devlink objects are re-created during
 4639	 * reload process so the notifications are generated separatelly.
 4640	 */
 4641
 4642	if (!dest_net || net_eq(dest_net, curr_net))
 4643		return;
 4644
 4645	if (new)
 4646		devlink_notify(devlink, DEVLINK_CMD_NEW);
 4647
 4648	cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
 4649	list_for_each_entry(param_item, &devlink->param_list, list)
 4650		devlink_param_notify(devlink, 0, param_item, cmd);
 4651
 4652	if (!new)
 4653		devlink_notify(devlink, DEVLINK_CMD_DEL);
 4654}
 4655
 4656static bool devlink_reload_supported(const struct devlink_ops *ops)
 4657{
 4658	return ops->reload_down && ops->reload_up;
 4659}
 4660
 4661static void devlink_reload_failed_set(struct devlink *devlink,
 4662				      bool reload_failed)
 4663{
 4664	if (devlink->reload_failed == reload_failed)
 4665		return;
 4666	devlink->reload_failed = reload_failed;
 4667	devlink_notify(devlink, DEVLINK_CMD_NEW);
 4668}
 4669
 4670bool devlink_is_reload_failed(const struct devlink *devlink)
 4671{
 4672	return devlink->reload_failed;
 4673}
 4674EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
 4675
 4676static void
 4677__devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
 4678			      enum devlink_reload_limit limit, u32 actions_performed)
 4679{
 4680	unsigned long actions = actions_performed;
 4681	int stat_idx;
 4682	int action;
 4683
 4684	for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
 4685		stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
 4686		reload_stats[stat_idx]++;
 4687	}
 4688	devlink_notify(devlink, DEVLINK_CMD_NEW);
 4689}
 4690
 4691static void
 4692devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
 4693			    u32 actions_performed)
 4694{
 4695	__devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
 4696				      actions_performed);
 4697}
 4698
 4699/**
 4700 *	devlink_remote_reload_actions_performed - Update devlink on reload actions
 4701 *	  performed which are not a direct result of devlink reload call.
 4702 *
 4703 *	This should be called by a driver after performing reload actions in case it was not
 4704 *	a result of devlink reload call. For example fw_activate was performed as a result
 4705 *	of devlink reload triggered fw_activate on another host.
 4706 *	The motivation for this function is to keep data on reload actions performed on this
 4707 *	function whether it was done due to direct devlink reload call or not.
 4708 *
 4709 *	@devlink: devlink
 4710 *	@limit: reload limit
 4711 *	@actions_performed: bitmask of actions performed
 4712 */
 4713void devlink_remote_reload_actions_performed(struct devlink *devlink,
 4714					     enum devlink_reload_limit limit,
 4715					     u32 actions_performed)
 4716{
 4717	if (WARN_ON(!actions_performed ||
 4718		    actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
 4719		    actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
 4720		    limit > DEVLINK_RELOAD_LIMIT_MAX))
 4721		return;
 4722
 4723	__devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
 4724				      actions_performed);
 4725}
 4726EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
 4727
 4728static int devlink_reload(struct devlink *devlink, struct net *dest_net,
 4729			  enum devlink_reload_action action, enum devlink_reload_limit limit,
 4730			  u32 *actions_performed, struct netlink_ext_ack *extack)
 4731{
 4732	u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
 4733	struct net *curr_net;
 4734	int err;
 4735
 4736	memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
 4737	       sizeof(remote_reload_stats));
 4738
 4739	curr_net = devlink_net(devlink);
 4740	devlink_ns_change_notify(devlink, dest_net, curr_net, false);
 4741	err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
 4742	if (err)
 4743		return err;
 4744
 4745	if (dest_net && !net_eq(dest_net, curr_net))
 4746		write_pnet(&devlink->_net, dest_net);
 4747
 4748	err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
 4749	devlink_reload_failed_set(devlink, !!err);
 4750	if (err)
 4751		return err;
 4752
 4753	devlink_ns_change_notify(devlink, dest_net, curr_net, true);
 4754	WARN_ON(!(*actions_performed & BIT(action)));
 4755	/* Catch driver on updating the remote action within devlink reload */
 4756	WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
 4757		       sizeof(remote_reload_stats)));
 4758	devlink_reload_stats_update(devlink, limit, *actions_performed);
 4759	return 0;
 4760}
 4761
 4762static int
 4763devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
 4764					enum devlink_command cmd, struct genl_info *info)
 4765{
 4766	struct sk_buff *msg;
 4767	void *hdr;
 4768
 4769	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 4770	if (!msg)
 4771		return -ENOMEM;
 4772
 4773	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
 4774	if (!hdr)
 4775		goto free_msg;
 4776
 4777	if (devlink_nl_put_handle(msg, devlink))
 4778		goto nla_put_failure;
 4779
 4780	if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
 4781			       actions_performed))
 4782		goto nla_put_failure;
 4783	genlmsg_end(msg, hdr);
 4784
 4785	return genlmsg_reply(msg, info);
 4786
 4787nla_put_failure:
 4788	genlmsg_cancel(msg, hdr);
 4789free_msg:
 4790	nlmsg_free(msg);
 4791	return -EMSGSIZE;
 4792}
 4793
 4794static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
 4795{
 4796	struct devlink *devlink = info->user_ptr[0];
 4797	enum devlink_reload_action action;
 4798	enum devlink_reload_limit limit;
 4799	struct net *dest_net = NULL;
 4800	u32 actions_performed;
 4801	int err;
 4802
 4803	if (!(devlink->features & DEVLINK_F_RELOAD))
 4804		return -EOPNOTSUPP;
 4805
 4806	err = devlink_resources_validate(devlink, NULL, info);
 4807	if (err) {
 4808		NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
 4809		return err;
 4810	}
 4811
 4812	if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
 4813		action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
 4814	else
 4815		action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
 4816
 4817	if (!devlink_reload_action_is_supported(devlink, action)) {
 4818		NL_SET_ERR_MSG_MOD(info->extack,
 4819				   "Requested reload action is not supported by the driver");
 4820		return -EOPNOTSUPP;
 4821	}
 4822
 4823	limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
 4824	if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
 4825		struct nla_bitfield32 limits;
 4826		u32 limits_selected;
 4827
 4828		limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
 4829		limits_selected = limits.value & limits.selector;
 4830		if (!limits_selected) {
 4831			NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
 4832			return -EINVAL;
 4833		}
 4834		for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
 4835			if (limits_selected & BIT(limit))
 4836				break;
 4837		/* UAPI enables multiselection, but currently it is not used */
 4838		if (limits_selected != BIT(limit)) {
 4839			NL_SET_ERR_MSG_MOD(info->extack,
 4840					   "Multiselection of limit is not supported");
 4841			return -EOPNOTSUPP;
 4842		}
 4843		if (!devlink_reload_limit_is_supported(devlink, limit)) {
 4844			NL_SET_ERR_MSG_MOD(info->extack,
 4845					   "Requested limit is not supported by the driver");
 4846			return -EOPNOTSUPP;
 4847		}
 4848		if (devlink_reload_combination_is_invalid(action, limit)) {
 4849			NL_SET_ERR_MSG_MOD(info->extack,
 4850					   "Requested limit is invalid for this action");
 4851			return -EINVAL;
 4852		}
 4853	}
 4854	if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
 4855	    info->attrs[DEVLINK_ATTR_NETNS_FD] ||
 4856	    info->attrs[DEVLINK_ATTR_NETNS_ID]) {
 4857		dest_net = devlink_netns_get(skb, info);
 4858		if (IS_ERR(dest_net))
 4859			return PTR_ERR(dest_net);
 4860	}
 4861
 4862	err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
 4863
 4864	if (dest_net)
 4865		put_net(dest_net);
 4866
 4867	if (err)
 4868		return err;
 4869	/* For backward compatibility generate reply only if attributes used by user */
 4870	if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
 4871		return 0;
 4872
 4873	return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
 4874						       DEVLINK_CMD_RELOAD, info);
 4875}
 4876
 4877static int devlink_nl_flash_update_fill(struct sk_buff *msg,
 4878					struct devlink *devlink,
 4879					enum devlink_command cmd,
 4880					struct devlink_flash_notify *params)
 4881{
 4882	void *hdr;
 4883
 4884	hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
 4885	if (!hdr)
 4886		return -EMSGSIZE;
 4887
 4888	if (devlink_nl_put_handle(msg, devlink))
 4889		goto nla_put_failure;
 4890
 4891	if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
 4892		goto out;
 4893
 4894	if (params->status_msg &&
 4895	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
 4896			   params->status_msg))
 4897		goto nla_put_failure;
 4898	if (params->component &&
 4899	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
 4900			   params->component))
 4901		goto nla_put_failure;
 4902	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
 4903			      params->done, DEVLINK_ATTR_PAD))
 4904		goto nla_put_failure;
 4905	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
 4906			      params->total, DEVLINK_ATTR_PAD))
 4907		goto nla_put_failure;
 4908	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
 4909			      params->timeout, DEVLINK_ATTR_PAD))
 4910		goto nla_put_failure;
 4911
 4912out:
 4913	genlmsg_end(msg, hdr);
 4914	return 0;
 4915
 4916nla_put_failure:
 4917	genlmsg_cancel(msg, hdr);
 4918	return -EMSGSIZE;
 4919}
 4920
 4921static void __devlink_flash_update_notify(struct devlink *devlink,
 4922					  enum devlink_command cmd,
 4923					  struct devlink_flash_notify *params)
 4924{
 4925	struct sk_buff *msg;
 4926	int err;
 4927
 4928	WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
 4929		cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
 4930		cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
 4931
 4932	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
 4933		return;
 4934
 4935	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 4936	if (!msg)
 4937		return;
 4938
 4939	err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
 4940	if (err)
 4941		goto out_free_msg;
 4942
 4943	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 4944				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 4945	return;
 4946
 4947out_free_msg:
 4948	nlmsg_free(msg);
 4949}
 4950
 4951static void devlink_flash_update_begin_notify(struct devlink *devlink)
 4952{
 4953	struct devlink_flash_notify params = {};
 4954
 4955	__devlink_flash_update_notify(devlink,
 4956				      DEVLINK_CMD_FLASH_UPDATE,
 4957				      &params);
 4958}
 4959
 4960static void devlink_flash_update_end_notify(struct devlink *devlink)
 4961{
 4962	struct devlink_flash_notify params = {};
 4963
 4964	__devlink_flash_update_notify(devlink,
 4965				      DEVLINK_CMD_FLASH_UPDATE_END,
 4966				      &params);
 4967}
 4968
 4969void devlink_flash_update_status_notify(struct devlink *devlink,
 4970					const char *status_msg,
 4971					const char *component,
 4972					unsigned long done,
 4973					unsigned long total)
 4974{
 4975	struct devlink_flash_notify params = {
 4976		.status_msg = status_msg,
 4977		.component = component,
 4978		.done = done,
 4979		.total = total,
 4980	};
 4981
 4982	__devlink_flash_update_notify(devlink,
 4983				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
 4984				      &params);
 4985}
 4986EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
 4987
 4988void devlink_flash_update_timeout_notify(struct devlink *devlink,
 4989					 const char *status_msg,
 4990					 const char *component,
 4991					 unsigned long timeout)
 4992{
 4993	struct devlink_flash_notify params = {
 4994		.status_msg = status_msg,
 4995		.component = component,
 4996		.timeout = timeout,
 4997	};
 4998
 4999	__devlink_flash_update_notify(devlink,
 5000				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
 5001				      &params);
 5002}
 5003EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
 5004
 5005struct devlink_info_req {
 5006	struct sk_buff *msg;
 5007	void (*version_cb)(const char *version_name,
 5008			   enum devlink_info_version_type version_type,
 5009			   void *version_cb_priv);
 5010	void *version_cb_priv;
 5011};
 5012
 5013struct devlink_flash_component_lookup_ctx {
 5014	const char *lookup_name;
 5015	bool lookup_name_found;
 5016};
 5017
 5018static void
 5019devlink_flash_component_lookup_cb(const char *version_name,
 5020				  enum devlink_info_version_type version_type,
 5021				  void *version_cb_priv)
 5022{
 5023	struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
 5024
 5025	if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
 5026	    lookup_ctx->lookup_name_found)
 5027		return;
 5028
 5029	lookup_ctx->lookup_name_found =
 5030		!strcmp(lookup_ctx->lookup_name, version_name);
 5031}
 5032
 5033static int devlink_flash_component_get(struct devlink *devlink,
 5034				       struct nlattr *nla_component,
 5035				       const char **p_component,
 5036				       struct netlink_ext_ack *extack)
 5037{
 5038	struct devlink_flash_component_lookup_ctx lookup_ctx = {};
 5039	struct devlink_info_req req = {};
 5040	const char *component;
 5041	int ret;
 5042
 5043	if (!nla_component)
 5044		return 0;
 5045
 5046	component = nla_data(nla_component);
 5047
 5048	if (!devlink->ops->info_get) {
 5049		NL_SET_ERR_MSG_ATTR(extack, nla_component,
 5050				    "component update is not supported by this device");
 5051		return -EOPNOTSUPP;
 5052	}
 5053
 5054	lookup_ctx.lookup_name = component;
 5055	req.version_cb = devlink_flash_component_lookup_cb;
 5056	req.version_cb_priv = &lookup_ctx;
 5057
 5058	ret = devlink->ops->info_get(devlink, &req, NULL);
 5059	if (ret)
 5060		return ret;
 5061
 5062	if (!lookup_ctx.lookup_name_found) {
 5063		NL_SET_ERR_MSG_ATTR(extack, nla_component,
 5064				    "selected component is not supported by this device");
 5065		return -EINVAL;
 5066	}
 5067	*p_component = component;
 5068	return 0;
 5069}
 5070
 5071static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 5072				       struct genl_info *info)
 5073{
 5074	struct nlattr *nla_overwrite_mask, *nla_file_name;
 5075	struct devlink_flash_update_params params = {};
 5076	struct devlink *devlink = info->user_ptr[0];
 5077	const char *file_name;
 5078	u32 supported_params;
 5079	int ret;
 5080
 5081	if (!devlink->ops->flash_update)
 5082		return -EOPNOTSUPP;
 5083
 5084	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME))
 5085		return -EINVAL;
 5086
 5087	ret = devlink_flash_component_get(devlink,
 5088					  info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
 5089					  &params.component, info->extack);
 5090	if (ret)
 5091		return ret;
 5092
 5093	supported_params = devlink->ops->supported_flash_update_params;
 5094
 5095	nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
 5096	if (nla_overwrite_mask) {
 5097		struct nla_bitfield32 sections;
 5098
 5099		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
 5100			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
 5101					    "overwrite settings are not supported by this device");
 5102			return -EOPNOTSUPP;
 5103		}
 5104		sections = nla_get_bitfield32(nla_overwrite_mask);
 5105		params.overwrite_mask = sections.value & sections.selector;
 5106	}
 5107
 5108	nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
 5109	file_name = nla_data(nla_file_name);
 5110	ret = request_firmware(&params.fw, file_name, devlink->dev);
 5111	if (ret) {
 5112		NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file");
 5113		return ret;
 5114	}
 5115
 5116	devlink_flash_update_begin_notify(devlink);
 5117	ret = devlink->ops->flash_update(devlink, &params, info->extack);
 5118	devlink_flash_update_end_notify(devlink);
 5119
 5120	release_firmware(params.fw);
 5121
 5122	return ret;
 5123}
 5124
 5125static int
 5126devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
 5127			  u32 portid, u32 seq, int flags,
 5128			  struct netlink_ext_ack *extack)
 5129{
 5130	struct nlattr *selftests;
 5131	void *hdr;
 5132	int err;
 5133	int i;
 5134
 5135	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
 5136			  DEVLINK_CMD_SELFTESTS_GET);
 5137	if (!hdr)
 5138		return -EMSGSIZE;
 5139
 5140	err = -EMSGSIZE;
 5141	if (devlink_nl_put_handle(msg, devlink))
 5142		goto err_cancel_msg;
 5143
 5144	selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
 5145	if (!selftests)
 5146		goto err_cancel_msg;
 5147
 5148	for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
 5149	     i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
 5150		if (devlink->ops->selftest_check(devlink, i, extack)) {
 5151			err = nla_put_flag(msg, i);
 5152			if (err)
 5153				goto err_cancel_msg;
 5154		}
 5155	}
 5156
 5157	nla_nest_end(msg, selftests);
 5158	genlmsg_end(msg, hdr);
 5159	return 0;
 5160
 5161err_cancel_msg:
 5162	genlmsg_cancel(msg, hdr);
 5163	return err;
 5164}
 5165
 5166static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
 5167					     struct genl_info *info)
 5168{
 5169	struct devlink *devlink = info->user_ptr[0];
 5170	struct sk_buff *msg;
 5171	int err;
 5172
 5173	if (!devlink->ops->selftest_check)
 5174		return -EOPNOTSUPP;
 5175
 5176	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 5177	if (!msg)
 5178		return -ENOMEM;
 5179
 5180	err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
 5181					info->snd_seq, 0, info->extack);
 5182	if (err) {
 5183		nlmsg_free(msg);
 5184		return err;
 5185	}
 5186
 5187	return genlmsg_reply(msg, info);
 5188}
 5189
 5190static int devlink_nl_cmd_selftests_get_dumpit(struct sk_buff *msg,
 5191					       struct netlink_callback *cb)
 5192{
 5193	struct devlink *devlink;
 5194	int start = cb->args[0];
 5195	unsigned long index;
 5196	int idx = 0;
 5197	int err = 0;
 5198
 5199	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 5200		if (idx < start || !devlink->ops->selftest_check)
 5201			goto inc;
 5202
 5203		devl_lock(devlink);
 5204		err = devlink_nl_selftests_fill(msg, devlink,
 5205						NETLINK_CB(cb->skb).portid,
 5206						cb->nlh->nlmsg_seq, NLM_F_MULTI,
 5207						cb->extack);
 5208		devl_unlock(devlink);
 5209		if (err) {
 5210			devlink_put(devlink);
 5211			break;
 5212		}
 5213inc:
 5214		idx++;
 5215		devlink_put(devlink);
 5216	}
 5217
 5218	if (err != -EMSGSIZE)
 5219		return err;
 5220
 5221	cb->args[0] = idx;
 5222	return msg->len;
 5223}
 5224
 5225static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
 5226				       enum devlink_selftest_status test_status)
 5227{
 5228	struct nlattr *result_attr;
 5229
 5230	result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT);
 5231	if (!result_attr)
 5232		return -EMSGSIZE;
 5233
 5234	if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) ||
 5235	    nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
 5236		       test_status))
 5237		goto nla_put_failure;
 5238
 5239	nla_nest_end(skb, result_attr);
 5240	return 0;
 5241
 5242nla_put_failure:
 5243	nla_nest_cancel(skb, result_attr);
 5244	return -EMSGSIZE;
 5245}
 5246
 5247static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
 5248					struct genl_info *info)
 5249{
 5250	struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1];
 5251	struct devlink *devlink = info->user_ptr[0];
 5252	struct nlattr *attrs, *selftests;
 5253	struct sk_buff *msg;
 5254	void *hdr;
 5255	int err;
 5256	int i;
 5257
 5258	if (!devlink->ops->selftest_run || !devlink->ops->selftest_check)
 5259		return -EOPNOTSUPP;
 5260
 5261	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS))
 5262		return -EINVAL;
 5263
 5264	attrs = info->attrs[DEVLINK_ATTR_SELFTESTS];
 5265
 5266	err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs,
 5267			       devlink_selftest_nl_policy, info->extack);
 5268	if (err < 0)
 5269		return err;
 5270
 5271	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 5272	if (!msg)
 5273		return -ENOMEM;
 5274
 5275	err = -EMSGSIZE;
 5276	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
 5277			  &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
 5278	if (!hdr)
 5279		goto free_msg;
 5280
 5281	if (devlink_nl_put_handle(msg, devlink))
 5282		goto genlmsg_cancel;
 5283
 5284	selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
 5285	if (!selftests)
 5286		goto genlmsg_cancel;
 5287
 5288	for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
 5289	     i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
 5290		enum devlink_selftest_status test_status;
 5291
 5292		if (nla_get_flag(tb[i])) {
 5293			if (!devlink->ops->selftest_check(devlink, i,
 5294							  info->extack)) {
 5295				if (devlink_selftest_result_put(msg, i,
 5296								DEVLINK_SELFTEST_STATUS_SKIP))
 5297					goto selftests_nest_cancel;
 5298				continue;
 5299			}
 5300
 5301			test_status = devlink->ops->selftest_run(devlink, i,
 5302								 info->extack);
 5303			if (devlink_selftest_result_put(msg, i, test_status))
 5304				goto selftests_nest_cancel;
 5305		}
 5306	}
 5307
 5308	nla_nest_end(msg, selftests);
 5309	genlmsg_end(msg, hdr);
 5310	return genlmsg_reply(msg, info);
 5311
 5312selftests_nest_cancel:
 5313	nla_nest_cancel(msg, selftests);
 5314genlmsg_cancel:
 5315	genlmsg_cancel(msg, hdr);
 5316free_msg:
 5317	nlmsg_free(msg);
 5318	return err;
 5319}
 5320
 5321static const struct devlink_param devlink_param_generic[] = {
 5322	{
 5323		.id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
 5324		.name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
 5325		.type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
 5326	},
 5327	{
 5328		.id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
 5329		.name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
 5330		.type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
 5331	},
 5332	{
 5333		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
 5334		.name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
 5335		.type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
 5336	},
 5337	{
 5338		.id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
 5339		.name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
 5340		.type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
 5341	},
 5342	{
 5343		.id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
 5344		.name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
 5345		.type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
 5346	},
 5347	{
 5348		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
 5349		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
 5350		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
 5351	},
 5352	{
 5353		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
 5354		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
 5355		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
 5356	},
 5357	{
 5358		.id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
 5359		.name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
 5360		.type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
 5361	},
 5362	{
 5363		.id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
 5364		.name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
 5365		.type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
 5366	},
 5367	{
 5368		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
 5369		.name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
 5370		.type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
 5371	},
 5372	{
 5373		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
 5374		.name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
 5375		.type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
 5376	},
 5377	{
 5378		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
 5379		.name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
 5380		.type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
 5381	},
 5382	{
 5383		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
 5384		.name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
 5385		.type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
 5386	},
 5387	{
 5388		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
 5389		.name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
 5390		.type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
 5391	},
 5392	{
 5393		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
 5394		.name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
 5395		.type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
 5396	},
 5397	{
 5398		.id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
 5399		.name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
 5400		.type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
 5401	},
 5402	{
 5403		.id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
 5404		.name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
 5405		.type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
 5406	},
 5407};
 5408
 5409static int devlink_param_generic_verify(const struct devlink_param *param)
 5410{
 5411	/* verify it match generic parameter by id and name */
 5412	if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
 5413		return -EINVAL;
 5414	if (strcmp(param->name, devlink_param_generic[param->id].name))
 5415		return -ENOENT;
 5416
 5417	WARN_ON(param->type != devlink_param_generic[param->id].type);
 5418
 5419	return 0;
 5420}
 5421
 5422static int devlink_param_driver_verify(const struct devlink_param *param)
 5423{
 5424	int i;
 5425
 5426	if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
 5427		return -EINVAL;
 5428	/* verify no such name in generic params */
 5429	for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
 5430		if (!strcmp(param->name, devlink_param_generic[i].name))
 5431			return -EEXIST;
 5432
 5433	return 0;
 5434}
 5435
 5436static struct devlink_param_item *
 5437devlink_param_find_by_name(struct list_head *param_list,
 5438			   const char *param_name)
 5439{
 5440	struct devlink_param_item *param_item;
 5441
 5442	list_for_each_entry(param_item, param_list, list)
 5443		if (!strcmp(param_item->param->name, param_name))
 5444			return param_item;
 5445	return NULL;
 5446}
 5447
 5448static struct devlink_param_item *
 5449devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
 5450{
 5451	struct devlink_param_item *param_item;
 5452
 5453	list_for_each_entry(param_item, param_list, list)
 5454		if (param_item->param->id == param_id)
 5455			return param_item;
 5456	return NULL;
 5457}
 5458
 5459static bool
 5460devlink_param_cmode_is_supported(const struct devlink_param *param,
 5461				 enum devlink_param_cmode cmode)
 5462{
 5463	return test_bit(cmode, &param->supported_cmodes);
 5464}
 5465
 5466static int devlink_param_get(struct devlink *devlink,
 5467			     const struct devlink_param *param,
 5468			     struct devlink_param_gset_ctx *ctx)
 5469{
 5470	if (!param->get || devlink->reload_failed)
 5471		return -EOPNOTSUPP;
 5472	return param->get(devlink, param->id, ctx);
 5473}
 5474
 5475static int devlink_param_set(struct devlink *devlink,
 5476			     const struct devlink_param *param,
 5477			     struct devlink_param_gset_ctx *ctx)
 5478{
 5479	if (!param->set || devlink->reload_failed)
 5480		return -EOPNOTSUPP;
 5481	return param->set(devlink, param->id, ctx);
 5482}
 5483
 5484static int
 5485devlink_param_type_to_nla_type(enum devlink_param_type param_type)
 5486{
 5487	switch (param_type) {
 5488	case DEVLINK_PARAM_TYPE_U8:
 5489		return NLA_U8;
 5490	case DEVLINK_PARAM_TYPE_U16:
 5491		return NLA_U16;
 5492	case DEVLINK_PARAM_TYPE_U32:
 5493		return NLA_U32;
 5494	case DEVLINK_PARAM_TYPE_STRING:
 5495		return NLA_STRING;
 5496	case DEVLINK_PARAM_TYPE_BOOL:
 5497		return NLA_FLAG;
 5498	default:
 5499		return -EINVAL;
 5500	}
 5501}
 5502
 5503static int
 5504devlink_nl_param_value_fill_one(struct sk_buff *msg,
 5505				enum devlink_param_type type,
 5506				enum devlink_param_cmode cmode,
 5507				union devlink_param_value val)
 5508{
 5509	struct nlattr *param_value_attr;
 5510
 5511	param_value_attr = nla_nest_start_noflag(msg,
 5512						 DEVLINK_ATTR_PARAM_VALUE);
 5513	if (!param_value_attr)
 5514		goto nla_put_failure;
 5515
 5516	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
 5517		goto value_nest_cancel;
 5518
 5519	switch (type) {
 5520	case DEVLINK_PARAM_TYPE_U8:
 5521		if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
 5522			goto value_nest_cancel;
 5523		break;
 5524	case DEVLINK_PARAM_TYPE_U16:
 5525		if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
 5526			goto value_nest_cancel;
 5527		break;
 5528	case DEVLINK_PARAM_TYPE_U32:
 5529		if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
 5530			goto value_nest_cancel;
 5531		break;
 5532	case DEVLINK_PARAM_TYPE_STRING:
 5533		if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
 5534				   val.vstr))
 5535			goto value_nest_cancel;
 5536		break;
 5537	case DEVLINK_PARAM_TYPE_BOOL:
 5538		if (val.vbool &&
 5539		    nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
 5540			goto value_nest_cancel;
 5541		break;
 5542	}
 5543
 5544	nla_nest_end(msg, param_value_attr);
 5545	return 0;
 5546
 5547value_nest_cancel:
 5548	nla_nest_cancel(msg, param_value_attr);
 5549nla_put_failure:
 5550	return -EMSGSIZE;
 5551}
 5552
 5553static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
 5554				 unsigned int port_index,
 5555				 struct devlink_param_item *param_item,
 5556				 enum devlink_command cmd,
 5557				 u32 portid, u32 seq, int flags)
 5558{
 5559	union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
 5560	bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
 5561	const struct devlink_param *param = param_item->param;
 5562	struct devlink_param_gset_ctx ctx;
 5563	struct nlattr *param_values_list;
 5564	struct nlattr *param_attr;
 5565	int nla_type;
 5566	void *hdr;
 5567	int err;
 5568	int i;
 5569
 5570	/* Get value from driver part to driverinit configuration mode */
 5571	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
 5572		if (!devlink_param_cmode_is_supported(param, i))
 5573			continue;
 5574		if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
 5575			if (!param_item->driverinit_value_valid)
 5576				return -EOPNOTSUPP;
 5577			param_value[i] = param_item->driverinit_value;
 5578		} else {
 5579			ctx.cmode = i;
 5580			err = devlink_param_get(devlink, param, &ctx);
 5581			if (err)
 5582				return err;
 5583			param_value[i] = ctx.val;
 5584		}
 5585		param_value_set[i] = true;
 5586	}
 5587
 5588	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 5589	if (!hdr)
 5590		return -EMSGSIZE;
 5591
 5592	if (devlink_nl_put_handle(msg, devlink))
 5593		goto genlmsg_cancel;
 5594
 5595	if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
 5596	    cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
 5597	    cmd == DEVLINK_CMD_PORT_PARAM_DEL)
 5598		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
 5599			goto genlmsg_cancel;
 5600
 5601	param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
 5602	if (!param_attr)
 5603		goto genlmsg_cancel;
 5604	if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
 5605		goto param_nest_cancel;
 5606	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
 5607		goto param_nest_cancel;
 5608
 5609	nla_type = devlink_param_type_to_nla_type(param->type);
 5610	if (nla_type < 0)
 5611		goto param_nest_cancel;
 5612	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
 5613		goto param_nest_cancel;
 5614
 5615	param_values_list = nla_nest_start_noflag(msg,
 5616						  DEVLINK_ATTR_PARAM_VALUES_LIST);
 5617	if (!param_values_list)
 5618		goto param_nest_cancel;
 5619
 5620	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
 5621		if (!param_value_set[i])
 5622			continue;
 5623		err = devlink_nl_param_value_fill_one(msg, param->type,
 5624						      i, param_value[i]);
 5625		if (err)
 5626			goto values_list_nest_cancel;
 5627	}
 5628
 5629	nla_nest_end(msg, param_values_list);
 5630	nla_nest_end(msg, param_attr);
 5631	genlmsg_end(msg, hdr);
 5632	return 0;
 5633
 5634values_list_nest_cancel:
 5635	nla_nest_end(msg, param_values_list);
 5636param_nest_cancel:
 5637	nla_nest_cancel(msg, param_attr);
 5638genlmsg_cancel:
 5639	genlmsg_cancel(msg, hdr);
 5640	return -EMSGSIZE;
 5641}
 5642
 5643static void devlink_param_notify(struct devlink *devlink,
 5644				 unsigned int port_index,
 5645				 struct devlink_param_item *param_item,
 5646				 enum devlink_command cmd)
 5647{
 5648	struct sk_buff *msg;
 5649	int err;
 5650
 5651	WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
 5652		cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
 5653		cmd != DEVLINK_CMD_PORT_PARAM_DEL);
 5654	ASSERT_DEVLINK_REGISTERED(devlink);
 5655
 5656	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 5657	if (!msg)
 5658		return;
 5659	err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
 5660				    0, 0, 0);
 5661	if (err) {
 5662		nlmsg_free(msg);
 5663		return;
 5664	}
 5665
 5666	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 5667				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 5668}
 5669
 5670static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
 5671					   struct netlink_callback *cb)
 5672{
 5673	struct devlink_param_item *param_item;
 5674	struct devlink *devlink;
 5675	int start = cb->args[0];
 5676	unsigned long index;
 5677	int idx = 0;
 5678	int err = 0;
 5679
 5680	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 5681		devl_lock(devlink);
 5682		list_for_each_entry(param_item, &devlink->param_list, list) {
 5683			if (idx < start) {
 5684				idx++;
 5685				continue;
 5686			}
 5687			err = devlink_nl_param_fill(msg, devlink, 0, param_item,
 5688						    DEVLINK_CMD_PARAM_GET,
 5689						    NETLINK_CB(cb->skb).portid,
 5690						    cb->nlh->nlmsg_seq,
 5691						    NLM_F_MULTI);
 5692			if (err == -EOPNOTSUPP) {
 5693				err = 0;
 5694			} else if (err) {
 5695				devl_unlock(devlink);
 5696				devlink_put(devlink);
 5697				goto out;
 5698			}
 5699			idx++;
 5700		}
 5701		devl_unlock(devlink);
 5702		devlink_put(devlink);
 5703	}
 5704out:
 5705	if (err != -EMSGSIZE)
 5706		return err;
 5707
 5708	cb->args[0] = idx;
 5709	return msg->len;
 5710}
 5711
 5712static int
 5713devlink_param_type_get_from_info(struct genl_info *info,
 5714				 enum devlink_param_type *param_type)
 5715{
 5716	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
 5717		return -EINVAL;
 5718
 5719	switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
 5720	case NLA_U8:
 5721		*param_type = DEVLINK_PARAM_TYPE_U8;
 5722		break;
 5723	case NLA_U16:
 5724		*param_type = DEVLINK_PARAM_TYPE_U16;
 5725		break;
 5726	case NLA_U32:
 5727		*param_type = DEVLINK_PARAM_TYPE_U32;
 5728		break;
 5729	case NLA_STRING:
 5730		*param_type = DEVLINK_PARAM_TYPE_STRING;
 5731		break;
 5732	case NLA_FLAG:
 5733		*param_type = DEVLINK_PARAM_TYPE_BOOL;
 5734		break;
 5735	default:
 5736		return -EINVAL;
 5737	}
 5738
 5739	return 0;
 5740}
 5741
 5742static int
 5743devlink_param_value_get_from_info(const struct devlink_param *param,
 5744				  struct genl_info *info,
 5745				  union devlink_param_value *value)
 5746{
 5747	struct nlattr *param_data;
 5748	int len;
 5749
 5750	param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
 5751
 5752	if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
 5753		return -EINVAL;
 5754
 5755	switch (param->type) {
 5756	case DEVLINK_PARAM_TYPE_U8:
 5757		if (nla_len(param_data) != sizeof(u8))
 5758			return -EINVAL;
 5759		value->vu8 = nla_get_u8(param_data);
 5760		break;
 5761	case DEVLINK_PARAM_TYPE_U16:
 5762		if (nla_len(param_data) != sizeof(u16))
 5763			return -EINVAL;
 5764		value->vu16 = nla_get_u16(param_data);
 5765		break;
 5766	case DEVLINK_PARAM_TYPE_U32:
 5767		if (nla_len(param_data) != sizeof(u32))
 5768			return -EINVAL;
 5769		value->vu32 = nla_get_u32(param_data);
 5770		break;
 5771	case DEVLINK_PARAM_TYPE_STRING:
 5772		len = strnlen(nla_data(param_data), nla_len(param_data));
 5773		if (len == nla_len(param_data) ||
 5774		    len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
 5775			return -EINVAL;
 5776		strcpy(value->vstr, nla_data(param_data));
 5777		break;
 5778	case DEVLINK_PARAM_TYPE_BOOL:
 5779		if (param_data && nla_len(param_data))
 5780			return -EINVAL;
 5781		value->vbool = nla_get_flag(param_data);
 5782		break;
 5783	}
 5784	return 0;
 5785}
 5786
 5787static struct devlink_param_item *
 5788devlink_param_get_from_info(struct list_head *param_list,
 5789			    struct genl_info *info)
 5790{
 5791	char *param_name;
 5792
 5793	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
 5794		return NULL;
 5795
 5796	param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
 5797	return devlink_param_find_by_name(param_list, param_name);
 5798}
 5799
 5800static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
 5801					 struct genl_info *info)
 5802{
 5803	struct devlink *devlink = info->user_ptr[0];
 5804	struct devlink_param_item *param_item;
 5805	struct sk_buff *msg;
 5806	int err;
 5807
 5808	param_item = devlink_param_get_from_info(&devlink->param_list, info);
 5809	if (!param_item)
 5810		return -EINVAL;
 5811
 5812	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 5813	if (!msg)
 5814		return -ENOMEM;
 5815
 5816	err = devlink_nl_param_fill(msg, devlink, 0, param_item,
 5817				    DEVLINK_CMD_PARAM_GET,
 5818				    info->snd_portid, info->snd_seq, 0);
 5819	if (err) {
 5820		nlmsg_free(msg);
 5821		return err;
 5822	}
 5823
 5824	return genlmsg_reply(msg, info);
 5825}
 5826
 5827static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
 5828					   unsigned int port_index,
 5829					   struct list_head *param_list,
 5830					   struct genl_info *info,
 5831					   enum devlink_command cmd)
 5832{
 5833	enum devlink_param_type param_type;
 5834	struct devlink_param_gset_ctx ctx;
 5835	enum devlink_param_cmode cmode;
 5836	struct devlink_param_item *param_item;
 5837	const struct devlink_param *param;
 5838	union devlink_param_value value;
 5839	int err = 0;
 5840
 5841	param_item = devlink_param_get_from_info(param_list, info);
 5842	if (!param_item)
 5843		return -EINVAL;
 5844	param = param_item->param;
 5845	err = devlink_param_type_get_from_info(info, &param_type);
 5846	if (err)
 5847		return err;
 5848	if (param_type != param->type)
 5849		return -EINVAL;
 5850	err = devlink_param_value_get_from_info(param, info, &value);
 5851	if (err)
 5852		return err;
 5853	if (param->validate) {
 5854		err = param->validate(devlink, param->id, value, info->extack);
 5855		if (err)
 5856			return err;
 5857	}
 5858
 5859	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
 5860		return -EINVAL;
 5861	cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
 5862	if (!devlink_param_cmode_is_supported(param, cmode))
 5863		return -EOPNOTSUPP;
 5864
 5865	if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
 5866		if (param->type == DEVLINK_PARAM_TYPE_STRING)
 5867			strcpy(param_item->driverinit_value.vstr, value.vstr);
 5868		else
 5869			param_item->driverinit_value = value;
 5870		param_item->driverinit_value_valid = true;
 5871	} else {
 5872		if (!param->set)
 5873			return -EOPNOTSUPP;
 5874		ctx.val = value;
 5875		ctx.cmode = cmode;
 5876		err = devlink_param_set(devlink, param, &ctx);
 5877		if (err)
 5878			return err;
 5879	}
 5880
 5881	devlink_param_notify(devlink, port_index, param_item, cmd);
 5882	return 0;
 5883}
 5884
 5885static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
 5886					 struct genl_info *info)
 5887{
 5888	struct devlink *devlink = info->user_ptr[0];
 5889
 5890	return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
 5891					       info, DEVLINK_CMD_PARAM_NEW);
 5892}
 5893
 5894static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
 5895						struct netlink_callback *cb)
 5896{
 5897	NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported");
 5898	return msg->len;
 5899}
 5900
 5901static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
 5902					      struct genl_info *info)
 5903{
 5904	NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
 5905	return -EINVAL;
 5906}
 5907
 5908static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
 5909					      struct genl_info *info)
 5910{
 5911	NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
 5912	return -EINVAL;
 5913}
 5914
 5915static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
 5916					     struct devlink *devlink,
 5917					     struct devlink_snapshot *snapshot)
 5918{
 5919	struct nlattr *snap_attr;
 5920	int err;
 5921
 5922	snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
 5923	if (!snap_attr)
 5924		return -EINVAL;
 5925
 5926	err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
 5927	if (err)
 5928		goto nla_put_failure;
 5929
 5930	nla_nest_end(msg, snap_attr);
 5931	return 0;
 5932
 5933nla_put_failure:
 5934	nla_nest_cancel(msg, snap_attr);
 5935	return err;
 5936}
 5937
 5938static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
 5939					      struct devlink *devlink,
 5940					      struct devlink_region *region)
 5941{
 5942	struct devlink_snapshot *snapshot;
 5943	struct nlattr *snapshots_attr;
 5944	int err;
 5945
 5946	snapshots_attr = nla_nest_start_noflag(msg,
 5947					       DEVLINK_ATTR_REGION_SNAPSHOTS);
 5948	if (!snapshots_attr)
 5949		return -EINVAL;
 5950
 5951	list_for_each_entry(snapshot, &region->snapshot_list, list) {
 5952		err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
 5953		if (err)
 5954			goto nla_put_failure;
 5955	}
 5956
 5957	nla_nest_end(msg, snapshots_attr);
 5958	return 0;
 5959
 5960nla_put_failure:
 5961	nla_nest_cancel(msg, snapshots_attr);
 5962	return err;
 5963}
 5964
 5965static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
 5966				  enum devlink_command cmd, u32 portid,
 5967				  u32 seq, int flags,
 5968				  struct devlink_region *region)
 5969{
 5970	void *hdr;
 5971	int err;
 5972
 5973	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 5974	if (!hdr)
 5975		return -EMSGSIZE;
 5976
 5977	err = devlink_nl_put_handle(msg, devlink);
 5978	if (err)
 5979		goto nla_put_failure;
 5980
 5981	if (region->port) {
 5982		err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
 5983				  region->port->index);
 5984		if (err)
 5985			goto nla_put_failure;
 5986	}
 5987
 5988	err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
 5989	if (err)
 5990		goto nla_put_failure;
 5991
 5992	err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
 5993				region->size,
 5994				DEVLINK_ATTR_PAD);
 5995	if (err)
 5996		goto nla_put_failure;
 5997
 5998	err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
 5999			  region->max_snapshots);
 6000	if (err)
 6001		goto nla_put_failure;
 6002
 6003	err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
 6004	if (err)
 6005		goto nla_put_failure;
 6006
 6007	genlmsg_end(msg, hdr);
 6008	return 0;
 6009
 6010nla_put_failure:
 6011	genlmsg_cancel(msg, hdr);
 6012	return err;
 6013}
 6014
 6015static struct sk_buff *
 6016devlink_nl_region_notify_build(struct devlink_region *region,
 6017			       struct devlink_snapshot *snapshot,
 6018			       enum devlink_command cmd, u32 portid, u32 seq)
 6019{
 6020	struct devlink *devlink = region->devlink;
 6021	struct sk_buff *msg;
 6022	void *hdr;
 6023	int err;
 6024
 6025
 6026	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 6027	if (!msg)
 6028		return ERR_PTR(-ENOMEM);
 6029
 6030	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
 6031	if (!hdr) {
 6032		err = -EMSGSIZE;
 6033		goto out_free_msg;
 6034	}
 6035
 6036	err = devlink_nl_put_handle(msg, devlink);
 6037	if (err)
 6038		goto out_cancel_msg;
 6039
 6040	if (region->port) {
 6041		err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
 6042				  region->port->index);
 6043		if (err)
 6044			goto out_cancel_msg;
 6045	}
 6046
 6047	err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
 6048			     region->ops->name);
 6049	if (err)
 6050		goto out_cancel_msg;
 6051
 6052	if (snapshot) {
 6053		err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
 6054				  snapshot->id);
 6055		if (err)
 6056			goto out_cancel_msg;
 6057	} else {
 6058		err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
 6059					region->size, DEVLINK_ATTR_PAD);
 6060		if (err)
 6061			goto out_cancel_msg;
 6062	}
 6063	genlmsg_end(msg, hdr);
 6064
 6065	return msg;
 6066
 6067out_cancel_msg:
 6068	genlmsg_cancel(msg, hdr);
 6069out_free_msg:
 6070	nlmsg_free(msg);
 6071	return ERR_PTR(err);
 6072}
 6073
 6074static void devlink_nl_region_notify(struct devlink_region *region,
 6075				     struct devlink_snapshot *snapshot,
 6076				     enum devlink_command cmd)
 6077{
 6078	struct devlink *devlink = region->devlink;
 6079	struct sk_buff *msg;
 6080
 6081	WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
 6082	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
 6083		return;
 6084
 6085	msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
 6086	if (IS_ERR(msg))
 6087		return;
 6088
 6089	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
 6090				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 6091}
 6092
 6093/**
 6094 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
 6095 *	@devlink: devlink instance
 6096 *	@id: the snapshot id
 6097 *
 6098 *	Track when a new snapshot begins using an id. Load the count for the
 6099 *	given id from the snapshot xarray, increment it, and store it back.
 6100 *
 6101 *	Called when a new snapshot is created with the given id.
 6102 *
 6103 *	The id *must* have been previously allocated by
 6104 *	devlink_region_snapshot_id_get().
 6105 *
 6106 *	Returns 0 on success, or an error on failure.
 6107 */
 6108static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
 6109{
 6110	unsigned long count;
 6111	void *p;
 6112	int err;
 6113
 6114	xa_lock(&devlink->snapshot_ids);
 6115	p = xa_load(&devlink->snapshot_ids, id);
 6116	if (WARN_ON(!p)) {
 6117		err = -EINVAL;
 6118		goto unlock;
 6119	}
 6120
 6121	if (WARN_ON(!xa_is_value(p))) {
 6122		err = -EINVAL;
 6123		goto unlock;
 6124	}
 6125
 6126	count = xa_to_value(p);
 6127	count++;
 6128
 6129	err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
 6130				GFP_ATOMIC));
 6131unlock:
 6132	xa_unlock(&devlink->snapshot_ids);
 6133	return err;
 6134}
 6135
 6136/**
 6137 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
 6138 *	@devlink: devlink instance
 6139 *	@id: the snapshot id
 6140 *
 6141 *	Track when a snapshot is deleted and stops using an id. Load the count
 6142 *	for the given id from the snapshot xarray, decrement it, and store it
 6143 *	back.
 6144 *
 6145 *	If the count reaches zero, erase this id from the xarray, freeing it
 6146 *	up for future re-use by devlink_region_snapshot_id_get().
 6147 *
 6148 *	Called when a snapshot using the given id is deleted, and when the
 6149 *	initial allocator of the id is finished using it.
 6150 */
 6151static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
 6152{
 6153	unsigned long count;
 6154	void *p;
 6155
 6156	xa_lock(&devlink->snapshot_ids);
 6157	p = xa_load(&devlink->snapshot_ids, id);
 6158	if (WARN_ON(!p))
 6159		goto unlock;
 6160
 6161	if (WARN_ON(!xa_is_value(p)))
 6162		goto unlock;
 6163
 6164	count = xa_to_value(p);
 6165
 6166	if (count > 1) {
 6167		count--;
 6168		__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
 6169			   GFP_ATOMIC);
 6170	} else {
 6171		/* If this was the last user, we can erase this id */
 6172		__xa_erase(&devlink->snapshot_ids, id);
 6173	}
 6174unlock:
 6175	xa_unlock(&devlink->snapshot_ids);
 6176}
 6177
 6178/**
 6179 *	__devlink_snapshot_id_insert - Insert a specific snapshot ID
 6180 *	@devlink: devlink instance
 6181 *	@id: the snapshot id
 6182 *
 6183 *	Mark the given snapshot id as used by inserting a zero value into the
 6184 *	snapshot xarray.
 6185 *
 6186 *	This must be called while holding the devlink instance lock. Unlike
 6187 *	devlink_snapshot_id_get, the initial reference count is zero, not one.
 6188 *	It is expected that the id will immediately be used before
 6189 *	releasing the devlink instance lock.
 6190 *
 6191 *	Returns zero on success, or an error code if the snapshot id could not
 6192 *	be inserted.
 6193 */
 6194static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
 6195{
 6196	int err;
 6197
 6198	xa_lock(&devlink->snapshot_ids);
 6199	if (xa_load(&devlink->snapshot_ids, id)) {
 6200		xa_unlock(&devlink->snapshot_ids);
 6201		return -EEXIST;
 6202	}
 6203	err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
 6204				GFP_ATOMIC));
 6205	xa_unlock(&devlink->snapshot_ids);
 6206	return err;
 6207}
 6208
 6209/**
 6210 *	__devlink_region_snapshot_id_get - get snapshot ID
 6211 *	@devlink: devlink instance
 6212 *	@id: storage to return snapshot id
 6213 *
 6214 *	Allocates a new snapshot id. Returns zero on success, or a negative
 6215 *	error on failure. Must be called while holding the devlink instance
 6216 *	lock.
 6217 *
 6218 *	Snapshot IDs are tracked using an xarray which stores the number of
 6219 *	users of the snapshot id.
 6220 *
 6221 *	Note that the caller of this function counts as a 'user', in order to
 6222 *	avoid race conditions. The caller must release its hold on the
 6223 *	snapshot by using devlink_region_snapshot_id_put.
 6224 */
 6225static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
 6226{
 6227	return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
 6228			xa_limit_32b, GFP_KERNEL);
 6229}
 6230
 6231/**
 6232 *	__devlink_region_snapshot_create - create a new snapshot
 6233 *	This will add a new snapshot of a region. The snapshot
 6234 *	will be stored on the region struct and can be accessed
 6235 *	from devlink. This is useful for future analyses of snapshots.
 6236 *	Multiple snapshots can be created on a region.
 6237 *	The @snapshot_id should be obtained using the getter function.
 6238 *
 6239 *	Must be called only while holding the region snapshot lock.
 6240 *
 6241 *	@region: devlink region of the snapshot
 6242 *	@data: snapshot data
 6243 *	@snapshot_id: snapshot id to be created
 6244 */
 6245static int
 6246__devlink_region_snapshot_create(struct devlink_region *region,
 6247				 u8 *data, u32 snapshot_id)
 6248{
 6249	struct devlink *devlink = region->devlink;
 6250	struct devlink_snapshot *snapshot;
 6251	int err;
 6252
 6253	lockdep_assert_held(&region->snapshot_lock);
 6254
 6255	/* check if region can hold one more snapshot */
 6256	if (region->cur_snapshots == region->max_snapshots)
 6257		return -ENOSPC;
 6258
 6259	if (devlink_region_snapshot_get_by_id(region, snapshot_id))
 6260		return -EEXIST;
 6261
 6262	snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
 6263	if (!snapshot)
 6264		return -ENOMEM;
 6265
 6266	err = __devlink_snapshot_id_increment(devlink, snapshot_id);
 6267	if (err)
 6268		goto err_snapshot_id_increment;
 6269
 6270	snapshot->id = snapshot_id;
 6271	snapshot->region = region;
 6272	snapshot->data = data;
 6273
 6274	list_add_tail(&snapshot->list, &region->snapshot_list);
 6275
 6276	region->cur_snapshots++;
 6277
 6278	devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
 6279	return 0;
 6280
 6281err_snapshot_id_increment:
 6282	kfree(snapshot);
 6283	return err;
 6284}
 6285
 6286static void devlink_region_snapshot_del(struct devlink_region *region,
 6287					struct devlink_snapshot *snapshot)
 6288{
 6289	struct devlink *devlink = region->devlink;
 6290
 6291	lockdep_assert_held(&region->snapshot_lock);
 6292
 6293	devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
 6294	region->cur_snapshots--;
 6295	list_del(&snapshot->list);
 6296	region->ops->destructor(snapshot->data);
 6297	__devlink_snapshot_id_decrement(devlink, snapshot->id);
 6298	kfree(snapshot);
 6299}
 6300
 6301static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
 6302					  struct genl_info *info)
 6303{
 6304	struct devlink *devlink = info->user_ptr[0];
 6305	struct devlink_port *port = NULL;
 6306	struct devlink_region *region;
 6307	const char *region_name;
 6308	struct sk_buff *msg;
 6309	unsigned int index;
 6310	int err;
 6311
 6312	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
 6313		return -EINVAL;
 6314
 6315	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
 6316		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 6317
 6318		port = devlink_port_get_by_index(devlink, index);
 6319		if (!port)
 6320			return -ENODEV;
 6321	}
 6322
 6323	region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
 6324	if (port)
 6325		region = devlink_port_region_get_by_name(port, region_name);
 6326	else
 6327		region = devlink_region_get_by_name(devlink, region_name);
 6328
 6329	if (!region)
 6330		return -EINVAL;
 6331
 6332	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 6333	if (!msg)
 6334		return -ENOMEM;
 6335
 6336	err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
 6337				     info->snd_portid, info->snd_seq, 0,
 6338				     region);
 6339	if (err) {
 6340		nlmsg_free(msg);
 6341		return err;
 6342	}
 6343
 6344	return genlmsg_reply(msg, info);
 6345}
 6346
 6347static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
 6348						 struct netlink_callback *cb,
 6349						 struct devlink_port *port,
 6350						 int *idx,
 6351						 int start)
 6352{
 6353	struct devlink_region *region;
 6354	int err = 0;
 6355
 6356	list_for_each_entry(region, &port->region_list, list) {
 6357		if (*idx < start) {
 6358			(*idx)++;
 6359			continue;
 6360		}
 6361		err = devlink_nl_region_fill(msg, port->devlink,
 6362					     DEVLINK_CMD_REGION_GET,
 6363					     NETLINK_CB(cb->skb).portid,
 6364					     cb->nlh->nlmsg_seq,
 6365					     NLM_F_MULTI, region);
 6366		if (err)
 6367			goto out;
 6368		(*idx)++;
 6369	}
 6370
 6371out:
 6372	return err;
 6373}
 6374
 6375static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
 6376						    struct netlink_callback *cb,
 6377						    struct devlink *devlink,
 6378						    int *idx,
 6379						    int start)
 6380{
 6381	struct devlink_region *region;
 6382	struct devlink_port *port;
 6383	unsigned long port_index;
 6384	int err = 0;
 6385
 6386	devl_lock(devlink);
 6387	list_for_each_entry(region, &devlink->region_list, list) {
 6388		if (*idx < start) {
 6389			(*idx)++;
 6390			continue;
 6391		}
 6392		err = devlink_nl_region_fill(msg, devlink,
 6393					     DEVLINK_CMD_REGION_GET,
 6394					     NETLINK_CB(cb->skb).portid,
 6395					     cb->nlh->nlmsg_seq,
 6396					     NLM_F_MULTI, region);
 6397		if (err)
 6398			goto out;
 6399		(*idx)++;
 6400	}
 6401
 6402	xa_for_each(&devlink->ports, port_index, port) {
 6403		err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx,
 6404							    start);
 6405		if (err)
 6406			goto out;
 6407	}
 6408
 6409out:
 6410	devl_unlock(devlink);
 6411	return err;
 6412}
 6413
 6414static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
 6415					    struct netlink_callback *cb)
 6416{
 6417	struct devlink *devlink;
 6418	int start = cb->args[0];
 6419	unsigned long index;
 6420	int idx = 0;
 6421	int err = 0;
 6422
 6423	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 6424		err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
 6425							       &idx, start);
 6426		devlink_put(devlink);
 6427		if (err)
 6428			goto out;
 6429	}
 6430out:
 6431	cb->args[0] = idx;
 6432	return msg->len;
 6433}
 6434
 6435static int devlink_nl_cmd_region_del(struct sk_buff *skb,
 6436				     struct genl_info *info)
 6437{
 6438	struct devlink *devlink = info->user_ptr[0];
 6439	struct devlink_snapshot *snapshot;
 6440	struct devlink_port *port = NULL;
 6441	struct devlink_region *region;
 6442	const char *region_name;
 6443	unsigned int index;
 6444	u32 snapshot_id;
 6445
 6446	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
 6447	    GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
 6448		return -EINVAL;
 6449
 6450	region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
 6451	snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
 6452
 6453	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
 6454		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 6455
 6456		port = devlink_port_get_by_index(devlink, index);
 6457		if (!port)
 6458			return -ENODEV;
 6459	}
 6460
 6461	if (port)
 6462		region = devlink_port_region_get_by_name(port, region_name);
 6463	else
 6464		region = devlink_region_get_by_name(devlink, region_name);
 6465
 6466	if (!region)
 6467		return -EINVAL;
 6468
 6469	mutex_lock(&region->snapshot_lock);
 6470	snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
 6471	if (!snapshot) {
 6472		mutex_unlock(&region->snapshot_lock);
 6473		return -EINVAL;
 6474	}
 6475
 6476	devlink_region_snapshot_del(region, snapshot);
 6477	mutex_unlock(&region->snapshot_lock);
 6478	return 0;
 6479}
 6480
 6481static int
 6482devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
 6483{
 6484	struct devlink *devlink = info->user_ptr[0];
 6485	struct devlink_snapshot *snapshot;
 6486	struct devlink_port *port = NULL;
 6487	struct nlattr *snapshot_id_attr;
 6488	struct devlink_region *region;
 6489	const char *region_name;
 6490	unsigned int index;
 6491	u32 snapshot_id;
 6492	u8 *data;
 6493	int err;
 6494
 6495	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
 6496		NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
 6497		return -EINVAL;
 6498	}
 6499
 6500	region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
 6501
 6502	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
 6503		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 6504
 6505		port = devlink_port_get_by_index(devlink, index);
 6506		if (!port)
 6507			return -ENODEV;
 6508	}
 6509
 6510	if (port)
 6511		region = devlink_port_region_get_by_name(port, region_name);
 6512	else
 6513		region = devlink_region_get_by_name(devlink, region_name);
 6514
 6515	if (!region) {
 6516		NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
 6517		return -EINVAL;
 6518	}
 6519
 6520	if (!region->ops->snapshot) {
 6521		NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
 6522		return -EOPNOTSUPP;
 6523	}
 6524
 6525	mutex_lock(&region->snapshot_lock);
 6526
 6527	if (region->cur_snapshots == region->max_snapshots) {
 6528		NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
 6529		err = -ENOSPC;
 6530		goto unlock;
 6531	}
 6532
 6533	snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
 6534	if (snapshot_id_attr) {
 6535		snapshot_id = nla_get_u32(snapshot_id_attr);
 6536
 6537		if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
 6538			NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
 6539			err = -EEXIST;
 6540			goto unlock;
 6541		}
 6542
 6543		err = __devlink_snapshot_id_insert(devlink, snapshot_id);
 6544		if (err)
 6545			goto unlock;
 6546	} else {
 6547		err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
 6548		if (err) {
 6549			NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
 6550			goto unlock;
 6551		}
 6552	}
 6553
 6554	if (port)
 6555		err = region->port_ops->snapshot(port, region->port_ops,
 6556						 info->extack, &data);
 6557	else
 6558		err = region->ops->snapshot(devlink, region->ops,
 6559					    info->extack, &data);
 6560	if (err)
 6561		goto err_snapshot_capture;
 6562
 6563	err = __devlink_region_snapshot_create(region, data, snapshot_id);
 6564	if (err)
 6565		goto err_snapshot_create;
 6566
 6567	if (!snapshot_id_attr) {
 6568		struct sk_buff *msg;
 6569
 6570		snapshot = devlink_region_snapshot_get_by_id(region,
 6571							     snapshot_id);
 6572		if (WARN_ON(!snapshot)) {
 6573			err = -EINVAL;
 6574			goto unlock;
 6575		}
 6576
 6577		msg = devlink_nl_region_notify_build(region, snapshot,
 6578						     DEVLINK_CMD_REGION_NEW,
 6579						     info->snd_portid,
 6580						     info->snd_seq);
 6581		err = PTR_ERR_OR_ZERO(msg);
 6582		if (err)
 6583			goto err_notify;
 6584
 6585		err = genlmsg_reply(msg, info);
 6586		if (err)
 6587			goto err_notify;
 6588	}
 6589
 6590	mutex_unlock(&region->snapshot_lock);
 6591	return 0;
 6592
 6593err_snapshot_create:
 6594	region->ops->destructor(data);
 6595err_snapshot_capture:
 6596	__devlink_snapshot_id_decrement(devlink, snapshot_id);
 6597	mutex_unlock(&region->snapshot_lock);
 6598	return err;
 6599
 6600err_notify:
 6601	devlink_region_snapshot_del(region, snapshot);
 6602unlock:
 6603	mutex_unlock(&region->snapshot_lock);
 6604	return err;
 6605}
 6606
 6607static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
 6608						 u8 *chunk, u32 chunk_size,
 6609						 u64 addr)
 6610{
 6611	struct nlattr *chunk_attr;
 6612	int err;
 6613
 6614	chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
 6615	if (!chunk_attr)
 6616		return -EINVAL;
 6617
 6618	err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
 6619	if (err)
 6620		goto nla_put_failure;
 6621
 6622	err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
 6623				DEVLINK_ATTR_PAD);
 6624	if (err)
 6625		goto nla_put_failure;
 6626
 6627	nla_nest_end(msg, chunk_attr);
 6628	return 0;
 6629
 6630nla_put_failure:
 6631	nla_nest_cancel(msg, chunk_attr);
 6632	return err;
 6633}
 6634
 6635#define DEVLINK_REGION_READ_CHUNK_SIZE 256
 6636
 6637typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
 6638				 u64 curr_offset,
 6639				 struct netlink_ext_ack *extack);
 6640
 6641static int
 6642devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
 6643			    void *cb_priv, u64 start_offset, u64 end_offset,
 6644			    u64 *new_offset, struct netlink_ext_ack *extack)
 6645{
 6646	u64 curr_offset = start_offset;
 6647	int err = 0;
 6648	u8 *data;
 6649
 6650	/* Allocate and re-use a single buffer */
 6651	data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
 6652	if (!data)
 6653		return -ENOMEM;
 6654
 6655	*new_offset = start_offset;
 6656
 6657	while (curr_offset < end_offset) {
 6658		u32 data_size;
 6659
 6660		data_size = min_t(u32, end_offset - curr_offset,
 6661				  DEVLINK_REGION_READ_CHUNK_SIZE);
 6662
 6663		err = cb(cb_priv, data, data_size, curr_offset, extack);
 6664		if (err)
 6665			break;
 6666
 6667		err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
 6668		if (err)
 6669			break;
 6670
 6671		curr_offset += data_size;
 6672	}
 6673	*new_offset = curr_offset;
 6674
 6675	kfree(data);
 6676
 6677	return err;
 6678}
 6679
 6680static int
 6681devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
 6682			     u64 curr_offset,
 6683			     struct netlink_ext_ack __always_unused *extack)
 6684{
 6685	struct devlink_snapshot *snapshot = cb_priv;
 6686
 6687	memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
 6688
 6689	return 0;
 6690}
 6691
 6692static int
 6693devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
 6694				u64 curr_offset, struct netlink_ext_ack *extack)
 6695{
 6696	struct devlink_region *region = cb_priv;
 6697
 6698	return region->port_ops->read(region->port, region->port_ops, extack,
 6699				      curr_offset, chunk_size, chunk);
 6700}
 6701
 6702static int
 6703devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
 6704			   u64 curr_offset, struct netlink_ext_ack *extack)
 6705{
 6706	struct devlink_region *region = cb_priv;
 6707
 6708	return region->ops->read(region->devlink, region->ops, extack,
 6709				 curr_offset, chunk_size, chunk);
 6710}
 6711
 6712static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
 6713					     struct netlink_callback *cb)
 6714{
 6715	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
 6716	struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
 6717	u64 ret_offset, start_offset, end_offset = U64_MAX;
 6718	struct nlattr **attrs = info->attrs;
 6719	struct devlink_port *port = NULL;
 6720	devlink_chunk_fill_t *region_cb;
 6721	struct devlink_region *region;
 6722	const char *region_name;
 6723	struct devlink *devlink;
 6724	unsigned int index;
 6725	void *region_cb_priv;
 6726	void *hdr;
 6727	int err;
 6728
 6729	start_offset = *((u64 *)&cb->args[0]);
 6730
 6731	devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
 6732	if (IS_ERR(devlink))
 6733		return PTR_ERR(devlink);
 6734
 6735	devl_lock(devlink);
 6736
 6737	if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
 6738		NL_SET_ERR_MSG(cb->extack, "No region name provided");
 6739		err = -EINVAL;
 6740		goto out_unlock;
 6741	}
 6742
 6743	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
 6744		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 6745
 6746		port = devlink_port_get_by_index(devlink, index);
 6747		if (!port) {
 6748			err = -ENODEV;
 6749			goto out_unlock;
 6750		}
 6751	}
 6752
 6753	region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
 6754	region_name = nla_data(region_attr);
 6755
 6756	if (port)
 6757		region = devlink_port_region_get_by_name(port, region_name);
 6758	else
 6759		region = devlink_region_get_by_name(devlink, region_name);
 6760
 6761	if (!region) {
 6762		NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
 6763		err = -EINVAL;
 6764		goto out_unlock;
 6765	}
 6766
 6767	snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
 6768	if (!snapshot_attr) {
 6769		if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
 6770			NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
 6771			err = -EINVAL;
 6772			goto out_unlock;
 6773		}
 6774
 6775		if (!region->ops->read) {
 6776			NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
 6777			err = -EOPNOTSUPP;
 6778			goto out_unlock;
 6779		}
 6780
 6781		if (port)
 6782			region_cb = &devlink_region_port_direct_fill;
 6783		else
 6784			region_cb = &devlink_region_direct_fill;
 6785		region_cb_priv = region;
 6786	} else {
 6787		struct devlink_snapshot *snapshot;
 6788		u32 snapshot_id;
 6789
 6790		if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
 6791			NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
 6792			err = -EINVAL;
 6793			goto out_unlock;
 6794		}
 6795
 6796		snapshot_id = nla_get_u32(snapshot_attr);
 6797		snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
 6798		if (!snapshot) {
 6799			NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
 6800			err = -EINVAL;
 6801			goto out_unlock;
 6802		}
 6803		region_cb = &devlink_region_snapshot_fill;
 6804		region_cb_priv = snapshot;
 6805	}
 6806
 6807	if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
 6808	    attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
 6809		if (!start_offset)
 6810			start_offset =
 6811				nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
 6812
 6813		end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
 6814		end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
 6815	}
 6816
 6817	if (end_offset > region->size)
 6818		end_offset = region->size;
 6819
 6820	/* return 0 if there is no further data to read */
 6821	if (start_offset == end_offset) {
 6822		err = 0;
 6823		goto out_unlock;
 6824	}
 6825
 6826	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
 6827			  &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
 6828			  DEVLINK_CMD_REGION_READ);
 6829	if (!hdr) {
 6830		err = -EMSGSIZE;
 6831		goto out_unlock;
 6832	}
 6833
 6834	err = devlink_nl_put_handle(skb, devlink);
 6835	if (err)
 6836		goto nla_put_failure;
 6837
 6838	if (region->port) {
 6839		err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
 6840				  region->port->index);
 6841		if (err)
 6842			goto nla_put_failure;
 6843	}
 6844
 6845	err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
 6846	if (err)
 6847		goto nla_put_failure;
 6848
 6849	chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
 6850	if (!chunks_attr) {
 6851		err = -EMSGSIZE;
 6852		goto nla_put_failure;
 6853	}
 6854
 6855	err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
 6856					  start_offset, end_offset, &ret_offset,
 6857					  cb->extack);
 6858
 6859	if (err && err != -EMSGSIZE)
 6860		goto nla_put_failure;
 6861
 6862	/* Check if there was any progress done to prevent infinite loop */
 6863	if (ret_offset == start_offset) {
 6864		err = -EINVAL;
 6865		goto nla_put_failure;
 6866	}
 6867
 6868	*((u64 *)&cb->args[0]) = ret_offset;
 6869
 6870	nla_nest_end(skb, chunks_attr);
 6871	genlmsg_end(skb, hdr);
 6872	devl_unlock(devlink);
 6873	devlink_put(devlink);
 6874	return skb->len;
 6875
 6876nla_put_failure:
 6877	genlmsg_cancel(skb, hdr);
 6878out_unlock:
 6879	devl_unlock(devlink);
 6880	devlink_put(devlink);
 6881	return err;
 6882}
 6883
 6884int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
 6885{
 6886	if (!req->msg)
 6887		return 0;
 6888	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
 6889}
 6890EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
 6891
 6892int devlink_info_board_serial_number_put(struct devlink_info_req *req,
 6893					 const char *bsn)
 6894{
 6895	if (!req->msg)
 6896		return 0;
 6897	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
 6898			      bsn);
 6899}
 6900EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
 6901
 6902static int devlink_info_version_put(struct devlink_info_req *req, int attr,
 6903				    const char *version_name,
 6904				    const char *version_value,
 6905				    enum devlink_info_version_type version_type)
 6906{
 6907	struct nlattr *nest;
 6908	int err;
 6909
 6910	if (req->version_cb)
 6911		req->version_cb(version_name, version_type,
 6912				req->version_cb_priv);
 6913
 6914	if (!req->msg)
 6915		return 0;
 6916
 6917	nest = nla_nest_start_noflag(req->msg, attr);
 6918	if (!nest)
 6919		return -EMSGSIZE;
 6920
 6921	err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
 6922			     version_name);
 6923	if (err)
 6924		goto nla_put_failure;
 6925
 6926	err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
 6927			     version_value);
 6928	if (err)
 6929		goto nla_put_failure;
 6930
 6931	nla_nest_end(req->msg, nest);
 6932
 6933	return 0;
 6934
 6935nla_put_failure:
 6936	nla_nest_cancel(req->msg, nest);
 6937	return err;
 6938}
 6939
 6940int devlink_info_version_fixed_put(struct devlink_info_req *req,
 6941				   const char *version_name,
 6942				   const char *version_value)
 6943{
 6944	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
 6945					version_name, version_value,
 6946					DEVLINK_INFO_VERSION_TYPE_NONE);
 6947}
 6948EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
 6949
 6950int devlink_info_version_stored_put(struct devlink_info_req *req,
 6951				    const char *version_name,
 6952				    const char *version_value)
 6953{
 6954	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
 6955					version_name, version_value,
 6956					DEVLINK_INFO_VERSION_TYPE_NONE);
 6957}
 6958EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
 6959
 6960int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
 6961					const char *version_name,
 6962					const char *version_value,
 6963					enum devlink_info_version_type version_type)
 6964{
 6965	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
 6966					version_name, version_value,
 6967					version_type);
 6968}
 6969EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
 6970
 6971int devlink_info_version_running_put(struct devlink_info_req *req,
 6972				     const char *version_name,
 6973				     const char *version_value)
 6974{
 6975	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
 6976					version_name, version_value,
 6977					DEVLINK_INFO_VERSION_TYPE_NONE);
 6978}
 6979EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
 6980
 6981int devlink_info_version_running_put_ext(struct devlink_info_req *req,
 6982					 const char *version_name,
 6983					 const char *version_value,
 6984					 enum devlink_info_version_type version_type)
 6985{
 6986	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
 6987					version_name, version_value,
 6988					version_type);
 6989}
 6990EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
 6991
 6992static int devlink_nl_driver_info_get(struct device_driver *drv,
 6993				      struct devlink_info_req *req)
 6994{
 6995	if (!drv)
 6996		return 0;
 6997
 6998	if (drv->name[0])
 6999		return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME,
 7000				      drv->name);
 7001
 7002	return 0;
 7003}
 7004
 7005static int
 7006devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
 7007		     enum devlink_command cmd, u32 portid,
 7008		     u32 seq, int flags, struct netlink_ext_ack *extack)
 7009{
 7010	struct device *dev = devlink_to_dev(devlink);
 7011	struct devlink_info_req req = {};
 7012	void *hdr;
 7013	int err;
 7014
 7015	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 7016	if (!hdr)
 7017		return -EMSGSIZE;
 7018
 7019	err = -EMSGSIZE;
 7020	if (devlink_nl_put_handle(msg, devlink))
 7021		goto err_cancel_msg;
 7022
 7023	req.msg = msg;
 7024	if (devlink->ops->info_get) {
 7025		err = devlink->ops->info_get(devlink, &req, extack);
 7026		if (err)
 7027			goto err_cancel_msg;
 7028	}
 7029
 7030	err = devlink_nl_driver_info_get(dev->driver, &req);
 7031	if (err)
 7032		goto err_cancel_msg;
 7033
 7034	genlmsg_end(msg, hdr);
 7035	return 0;
 7036
 7037err_cancel_msg:
 7038	genlmsg_cancel(msg, hdr);
 7039	return err;
 7040}
 7041
 7042static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
 7043					struct genl_info *info)
 7044{
 7045	struct devlink *devlink = info->user_ptr[0];
 7046	struct sk_buff *msg;
 7047	int err;
 7048
 7049	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 7050	if (!msg)
 7051		return -ENOMEM;
 7052
 7053	err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
 7054				   info->snd_portid, info->snd_seq, 0,
 7055				   info->extack);
 7056	if (err) {
 7057		nlmsg_free(msg);
 7058		return err;
 7059	}
 7060
 7061	return genlmsg_reply(msg, info);
 7062}
 7063
 7064static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
 7065					  struct netlink_callback *cb)
 7066{
 7067	struct devlink *devlink;
 7068	int start = cb->args[0];
 7069	unsigned long index;
 7070	int idx = 0;
 7071	int err = 0;
 7072
 7073	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 7074		if (idx < start)
 7075			goto inc;
 7076
 7077		devl_lock(devlink);
 7078		err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
 7079					   NETLINK_CB(cb->skb).portid,
 7080					   cb->nlh->nlmsg_seq, NLM_F_MULTI,
 7081					   cb->extack);
 7082		devl_unlock(devlink);
 7083		if (err == -EOPNOTSUPP)
 7084			err = 0;
 7085		else if (err) {
 7086			devlink_put(devlink);
 7087			break;
 7088		}
 7089inc:
 7090		idx++;
 7091		devlink_put(devlink);
 7092	}
 7093
 7094	if (err != -EMSGSIZE)
 7095		return err;
 7096
 7097	cb->args[0] = idx;
 7098	return msg->len;
 7099}
 7100
 7101struct devlink_fmsg_item {
 7102	struct list_head list;
 7103	int attrtype;
 7104	u8 nla_type;
 7105	u16 len;
 7106	int value[];
 7107};
 7108
 7109struct devlink_fmsg {
 7110	struct list_head item_list;
 7111	bool putting_binary; /* This flag forces enclosing of binary data
 7112			      * in an array brackets. It forces using
 7113			      * of designated API:
 7114			      * devlink_fmsg_binary_pair_nest_start()
 7115			      * devlink_fmsg_binary_pair_nest_end()
 7116			      */
 7117};
 7118
 7119static struct devlink_fmsg *devlink_fmsg_alloc(void)
 7120{
 7121	struct devlink_fmsg *fmsg;
 7122
 7123	fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
 7124	if (!fmsg)
 7125		return NULL;
 7126
 7127	INIT_LIST_HEAD(&fmsg->item_list);
 7128
 7129	return fmsg;
 7130}
 7131
 7132static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
 7133{
 7134	struct devlink_fmsg_item *item, *tmp;
 7135
 7136	list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
 7137		list_del(&item->list);
 7138		kfree(item);
 7139	}
 7140	kfree(fmsg);
 7141}
 7142
 7143static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
 7144				    int attrtype)
 7145{
 7146	struct devlink_fmsg_item *item;
 7147
 7148	item = kzalloc(sizeof(*item), GFP_KERNEL);
 7149	if (!item)
 7150		return -ENOMEM;
 7151
 7152	item->attrtype = attrtype;
 7153	list_add_tail(&item->list, &fmsg->item_list);
 7154
 7155	return 0;
 7156}
 7157
 7158int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
 7159{
 7160	if (fmsg->putting_binary)
 7161		return -EINVAL;
 7162
 7163	return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
 7164}
 7165EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
 7166
 7167static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
 7168{
 7169	if (fmsg->putting_binary)
 7170		return -EINVAL;
 7171
 7172	return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
 7173}
 7174
 7175int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
 7176{
 7177	if (fmsg->putting_binary)
 7178		return -EINVAL;
 7179
 7180	return devlink_fmsg_nest_end(fmsg);
 7181}
 7182EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
 7183
 7184#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
 7185
 7186static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
 7187{
 7188	struct devlink_fmsg_item *item;
 7189
 7190	if (fmsg->putting_binary)
 7191		return -EINVAL;
 7192
 7193	if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
 7194		return -EMSGSIZE;
 7195
 7196	item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
 7197	if (!item)
 7198		return -ENOMEM;
 7199
 7200	item->nla_type = NLA_NUL_STRING;
 7201	item->len = strlen(name) + 1;
 7202	item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
 7203	memcpy(&item->value, name, item->len);
 7204	list_add_tail(&item->list, &fmsg->item_list);
 7205
 7206	return 0;
 7207}
 7208
 7209int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
 7210{
 7211	int err;
 7212
 7213	if (fmsg->putting_binary)
 7214		return -EINVAL;
 7215
 7216	err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
 7217	if (err)
 7218		return err;
 7219
 7220	err = devlink_fmsg_put_name(fmsg, name);
 7221	if (err)
 7222		return err;
 7223
 7224	return 0;
 7225}
 7226EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
 7227
 7228int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
 7229{
 7230	if (fmsg->putting_binary)
 7231		return -EINVAL;
 7232
 7233	return devlink_fmsg_nest_end(fmsg);
 7234}
 7235EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
 7236
 7237int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
 7238				     const char *name)
 7239{
 7240	int err;
 7241
 7242	if (fmsg->putting_binary)
 7243		return -EINVAL;
 7244
 7245	err = devlink_fmsg_pair_nest_start(fmsg, name);
 7246	if (err)
 7247		return err;
 7248
 7249	err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
 7250	if (err)
 7251		return err;
 7252
 7253	return 0;
 7254}
 7255EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
 7256
 7257int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
 7258{
 7259	int err;
 7260
 7261	if (fmsg->putting_binary)
 7262		return -EINVAL;
 7263
 7264	err = devlink_fmsg_nest_end(fmsg);
 7265	if (err)
 7266		return err;
 7267
 7268	err = devlink_fmsg_nest_end(fmsg);
 7269	if (err)
 7270		return err;
 7271
 7272	return 0;
 7273}
 7274EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
 7275
 7276int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
 7277					const char *name)
 7278{
 7279	int err;
 7280
 7281	err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
 7282	if (err)
 7283		return err;
 7284
 7285	fmsg->putting_binary = true;
 7286	return err;
 7287}
 7288EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
 7289
 7290int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
 7291{
 7292	if (!fmsg->putting_binary)
 7293		return -EINVAL;
 7294
 7295	fmsg->putting_binary = false;
 7296	return devlink_fmsg_arr_pair_nest_end(fmsg);
 7297}
 7298EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
 7299
 7300static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
 7301				  const void *value, u16 value_len,
 7302				  u8 value_nla_type)
 7303{
 7304	struct devlink_fmsg_item *item;
 7305
 7306	if (value_len > DEVLINK_FMSG_MAX_SIZE)
 7307		return -EMSGSIZE;
 7308
 7309	item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
 7310	if (!item)
 7311		return -ENOMEM;
 7312
 7313	item->nla_type = value_nla_type;
 7314	item->len = value_len;
 7315	item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
 7316	memcpy(&item->value, value, item->len);
 7317	list_add_tail(&item->list, &fmsg->item_list);
 7318
 7319	return 0;
 7320}
 7321
 7322static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
 7323{
 7324	if (fmsg->putting_binary)
 7325		return -EINVAL;
 7326
 7327	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
 7328}
 7329
 7330static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
 7331{
 7332	if (fmsg->putting_binary)
 7333		return -EINVAL;
 7334
 7335	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
 7336}
 7337
 7338int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
 7339{
 7340	if (fmsg->putting_binary)
 7341		return -EINVAL;
 7342
 7343	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
 7344}
 7345EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
 7346
 7347static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
 7348{
 7349	if (fmsg->putting_binary)
 7350		return -EINVAL;
 7351
 7352	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
 7353}
 7354
 7355int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
 7356{
 7357	if (fmsg->putting_binary)
 7358		return -EINVAL;
 7359
 7360	return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
 7361				      NLA_NUL_STRING);
 7362}
 7363EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
 7364
 7365int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
 7366			    u16 value_len)
 7367{
 7368	if (!fmsg->putting_binary)
 7369		return -EINVAL;
 7370
 7371	return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
 7372}
 7373EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
 7374
 7375int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
 7376			       bool value)
 7377{
 7378	int err;
 7379
 7380	err = devlink_fmsg_pair_nest_start(fmsg, name);
 7381	if (err)
 7382		return err;
 7383
 7384	err = devlink_fmsg_bool_put(fmsg, value);
 7385	if (err)
 7386		return err;
 7387
 7388	err = devlink_fmsg_pair_nest_end(fmsg);
 7389	if (err)
 7390		return err;
 7391
 7392	return 0;
 7393}
 7394EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
 7395
 7396int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
 7397			     u8 value)
 7398{
 7399	int err;
 7400
 7401	err = devlink_fmsg_pair_nest_start(fmsg, name);
 7402	if (err)
 7403		return err;
 7404
 7405	err = devlink_fmsg_u8_put(fmsg, value);
 7406	if (err)
 7407		return err;
 7408
 7409	err = devlink_fmsg_pair_nest_end(fmsg);
 7410	if (err)
 7411		return err;
 7412
 7413	return 0;
 7414}
 7415EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
 7416
 7417int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
 7418			      u32 value)
 7419{
 7420	int err;
 7421
 7422	err = devlink_fmsg_pair_nest_start(fmsg, name);
 7423	if (err)
 7424		return err;
 7425
 7426	err = devlink_fmsg_u32_put(fmsg, value);
 7427	if (err)
 7428		return err;
 7429
 7430	err = devlink_fmsg_pair_nest_end(fmsg);
 7431	if (err)
 7432		return err;
 7433
 7434	return 0;
 7435}
 7436EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
 7437
 7438int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
 7439			      u64 value)
 7440{
 7441	int err;
 7442
 7443	err = devlink_fmsg_pair_nest_start(fmsg, name);
 7444	if (err)
 7445		return err;
 7446
 7447	err = devlink_fmsg_u64_put(fmsg, value);
 7448	if (err)
 7449		return err;
 7450
 7451	err = devlink_fmsg_pair_nest_end(fmsg);
 7452	if (err)
 7453		return err;
 7454
 7455	return 0;
 7456}
 7457EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
 7458
 7459int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
 7460				 const char *value)
 7461{
 7462	int err;
 7463
 7464	err = devlink_fmsg_pair_nest_start(fmsg, name);
 7465	if (err)
 7466		return err;
 7467
 7468	err = devlink_fmsg_string_put(fmsg, value);
 7469	if (err)
 7470		return err;
 7471
 7472	err = devlink_fmsg_pair_nest_end(fmsg);
 7473	if (err)
 7474		return err;
 7475
 7476	return 0;
 7477}
 7478EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
 7479
 7480int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
 7481				 const void *value, u32 value_len)
 7482{
 7483	u32 data_size;
 7484	int end_err;
 7485	u32 offset;
 7486	int err;
 7487
 7488	err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
 7489	if (err)
 7490		return err;
 7491
 7492	for (offset = 0; offset < value_len; offset += data_size) {
 7493		data_size = value_len - offset;
 7494		if (data_size > DEVLINK_FMSG_MAX_SIZE)
 7495			data_size = DEVLINK_FMSG_MAX_SIZE;
 7496		err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
 7497		if (err)
 7498			break;
 7499		/* Exit from loop with a break (instead of
 7500		 * return) to make sure putting_binary is turned off in
 7501		 * devlink_fmsg_binary_pair_nest_end
 7502		 */
 7503	}
 7504
 7505	end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
 7506	if (end_err)
 7507		err = end_err;
 7508
 7509	return err;
 7510}
 7511EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
 7512
 7513static int
 7514devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
 7515{
 7516	switch (msg->nla_type) {
 7517	case NLA_FLAG:
 7518	case NLA_U8:
 7519	case NLA_U32:
 7520	case NLA_U64:
 7521	case NLA_NUL_STRING:
 7522	case NLA_BINARY:
 7523		return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
 7524				  msg->nla_type);
 7525	default:
 7526		return -EINVAL;
 7527	}
 7528}
 7529
 7530static int
 7531devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
 7532{
 7533	int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
 7534	u8 tmp;
 7535
 7536	switch (msg->nla_type) {
 7537	case NLA_FLAG:
 7538		/* Always provide flag data, regardless of its value */
 7539		tmp = *(bool *) msg->value;
 7540
 7541		return nla_put_u8(skb, attrtype, tmp);
 7542	case NLA_U8:
 7543		return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
 7544	case NLA_U32:
 7545		return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
 7546	case NLA_U64:
 7547		return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
 7548					 DEVLINK_ATTR_PAD);
 7549	case NLA_NUL_STRING:
 7550		return nla_put_string(skb, attrtype, (char *) &msg->value);
 7551	case NLA_BINARY:
 7552		return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
 7553	default:
 7554		return -EINVAL;
 7555	}
 7556}
 7557
 7558static int
 7559devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
 7560			 int *start)
 7561{
 7562	struct devlink_fmsg_item *item;
 7563	struct nlattr *fmsg_nlattr;
 7564	int i = 0;
 7565	int err;
 7566
 7567	fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
 7568	if (!fmsg_nlattr)
 7569		return -EMSGSIZE;
 7570
 7571	list_for_each_entry(item, &fmsg->item_list, list) {
 7572		if (i < *start) {
 7573			i++;
 7574			continue;
 7575		}
 7576
 7577		switch (item->attrtype) {
 7578		case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
 7579		case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
 7580		case DEVLINK_ATTR_FMSG_ARR_NEST_START:
 7581		case DEVLINK_ATTR_FMSG_NEST_END:
 7582			err = nla_put_flag(skb, item->attrtype);
 7583			break;
 7584		case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
 7585			err = devlink_fmsg_item_fill_type(item, skb);
 7586			if (err)
 7587				break;
 7588			err = devlink_fmsg_item_fill_data(item, skb);
 7589			break;
 7590		case DEVLINK_ATTR_FMSG_OBJ_NAME:
 7591			err = nla_put_string(skb, item->attrtype,
 7592					     (char *) &item->value);
 7593			break;
 7594		default:
 7595			err = -EINVAL;
 7596			break;
 7597		}
 7598		if (!err)
 7599			*start = ++i;
 7600		else
 7601			break;
 7602	}
 7603
 7604	nla_nest_end(skb, fmsg_nlattr);
 7605	return err;
 7606}
 7607
 7608static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
 7609			    struct genl_info *info,
 7610			    enum devlink_command cmd, int flags)
 7611{
 7612	struct nlmsghdr *nlh;
 7613	struct sk_buff *skb;
 7614	bool last = false;
 7615	int index = 0;
 7616	void *hdr;
 7617	int err;
 7618
 7619	while (!last) {
 7620		int tmp_index = index;
 7621
 7622		skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
 7623		if (!skb)
 7624			return -ENOMEM;
 7625
 7626		hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
 7627				  &devlink_nl_family, flags | NLM_F_MULTI, cmd);
 7628		if (!hdr) {
 7629			err = -EMSGSIZE;
 7630			goto nla_put_failure;
 7631		}
 7632
 7633		err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
 7634		if (!err)
 7635			last = true;
 7636		else if (err != -EMSGSIZE || tmp_index == index)
 7637			goto nla_put_failure;
 7638
 7639		genlmsg_end(skb, hdr);
 7640		err = genlmsg_reply(skb, info);
 7641		if (err)
 7642			return err;
 7643	}
 7644
 7645	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
 7646	if (!skb)
 7647		return -ENOMEM;
 7648	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
 7649			NLMSG_DONE, 0, flags | NLM_F_MULTI);
 7650	if (!nlh) {
 7651		err = -EMSGSIZE;
 7652		goto nla_put_failure;
 7653	}
 7654
 7655	return genlmsg_reply(skb, info);
 7656
 7657nla_put_failure:
 7658	nlmsg_free(skb);
 7659	return err;
 7660}
 7661
 7662static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
 7663			       struct netlink_callback *cb,
 7664			       enum devlink_command cmd)
 7665{
 7666	int index = cb->args[0];
 7667	int tmp_index = index;
 7668	void *hdr;
 7669	int err;
 7670
 7671	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
 7672			  &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
 7673	if (!hdr) {
 7674		err = -EMSGSIZE;
 7675		goto nla_put_failure;
 7676	}
 7677
 7678	err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
 7679	if ((err && err != -EMSGSIZE) || tmp_index == index)
 7680		goto nla_put_failure;
 7681
 7682	cb->args[0] = index;
 7683	genlmsg_end(skb, hdr);
 7684	return skb->len;
 7685
 7686nla_put_failure:
 7687	genlmsg_cancel(skb, hdr);
 7688	return err;
 7689}
 7690
 7691struct devlink_health_reporter {
 7692	struct list_head list;
 7693	void *priv;
 7694	const struct devlink_health_reporter_ops *ops;
 7695	struct devlink *devlink;
 7696	struct devlink_port *devlink_port;
 7697	struct devlink_fmsg *dump_fmsg;
 7698	struct mutex dump_lock; /* lock parallel read/write from dump buffers */
 7699	u64 graceful_period;
 7700	bool auto_recover;
 7701	bool auto_dump;
 7702	u8 health_state;
 7703	u64 dump_ts;
 7704	u64 dump_real_ts;
 7705	u64 error_count;
 7706	u64 recovery_count;
 7707	u64 last_recovery_ts;
 7708	refcount_t refcount;
 7709};
 7710
 7711void *
 7712devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
 7713{
 7714	return reporter->priv;
 7715}
 7716EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
 7717
 7718static struct devlink_health_reporter *
 7719__devlink_health_reporter_find_by_name(struct list_head *reporter_list,
 7720				       struct mutex *list_lock,
 7721				       const char *reporter_name)
 7722{
 7723	struct devlink_health_reporter *reporter;
 7724
 7725	lockdep_assert_held(list_lock);
 7726	list_for_each_entry(reporter, reporter_list, list)
 7727		if (!strcmp(reporter->ops->name, reporter_name))
 7728			return reporter;
 7729	return NULL;
 7730}
 7731
 7732static struct devlink_health_reporter *
 7733devlink_health_reporter_find_by_name(struct devlink *devlink,
 7734				     const char *reporter_name)
 7735{
 7736	return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
 7737						      &devlink->reporters_lock,
 7738						      reporter_name);
 7739}
 7740
 7741static struct devlink_health_reporter *
 7742devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
 7743					  const char *reporter_name)
 7744{
 7745	return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
 7746						      &devlink_port->reporters_lock,
 7747						      reporter_name);
 7748}
 7749
 7750static struct devlink_health_reporter *
 7751__devlink_health_reporter_create(struct devlink *devlink,
 7752				 const struct devlink_health_reporter_ops *ops,
 7753				 u64 graceful_period, void *priv)
 7754{
 7755	struct devlink_health_reporter *reporter;
 7756
 7757	if (WARN_ON(graceful_period && !ops->recover))
 7758		return ERR_PTR(-EINVAL);
 7759
 7760	reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
 7761	if (!reporter)
 7762		return ERR_PTR(-ENOMEM);
 7763
 7764	reporter->priv = priv;
 7765	reporter->ops = ops;
 7766	reporter->devlink = devlink;
 7767	reporter->graceful_period = graceful_period;
 7768	reporter->auto_recover = !!ops->recover;
 7769	reporter->auto_dump = !!ops->dump;
 7770	mutex_init(&reporter->dump_lock);
 7771	refcount_set(&reporter->refcount, 1);
 7772	return reporter;
 7773}
 7774
 7775/**
 7776 *	devlink_port_health_reporter_create - create devlink health reporter for
 7777 *	                                      specified port instance
 7778 *
 7779 *	@port: devlink_port which should contain the new reporter
 7780 *	@ops: ops
 7781 *	@graceful_period: to avoid recovery loops, in msecs
 7782 *	@priv: priv
 7783 */
 7784struct devlink_health_reporter *
 7785devlink_port_health_reporter_create(struct devlink_port *port,
 7786				    const struct devlink_health_reporter_ops *ops,
 7787				    u64 graceful_period, void *priv)
 7788{
 7789	struct devlink_health_reporter *reporter;
 7790
 7791	mutex_lock(&port->reporters_lock);
 7792	if (__devlink_health_reporter_find_by_name(&port->reporter_list,
 7793						   &port->reporters_lock, ops->name)) {
 7794		reporter = ERR_PTR(-EEXIST);
 7795		goto unlock;
 7796	}
 7797
 7798	reporter = __devlink_health_reporter_create(port->devlink, ops,
 7799						    graceful_period, priv);
 7800	if (IS_ERR(reporter))
 7801		goto unlock;
 7802
 7803	reporter->devlink_port = port;
 7804	list_add_tail(&reporter->list, &port->reporter_list);
 7805unlock:
 7806	mutex_unlock(&port->reporters_lock);
 7807	return reporter;
 7808}
 7809EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
 7810
 7811/**
 7812 *	devlink_health_reporter_create - create devlink health reporter
 7813 *
 7814 *	@devlink: devlink
 7815 *	@ops: ops
 7816 *	@graceful_period: to avoid recovery loops, in msecs
 7817 *	@priv: priv
 7818 */
 7819struct devlink_health_reporter *
 7820devlink_health_reporter_create(struct devlink *devlink,
 7821			       const struct devlink_health_reporter_ops *ops,
 7822			       u64 graceful_period, void *priv)
 7823{
 7824	struct devlink_health_reporter *reporter;
 7825
 7826	mutex_lock(&devlink->reporters_lock);
 7827	if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
 7828		reporter = ERR_PTR(-EEXIST);
 7829		goto unlock;
 7830	}
 7831
 7832	reporter = __devlink_health_reporter_create(devlink, ops,
 7833						    graceful_period, priv);
 7834	if (IS_ERR(reporter))
 7835		goto unlock;
 7836
 7837	list_add_tail(&reporter->list, &devlink->reporter_list);
 7838unlock:
 7839	mutex_unlock(&devlink->reporters_lock);
 7840	return reporter;
 7841}
 7842EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
 7843
 7844static void
 7845devlink_health_reporter_free(struct devlink_health_reporter *reporter)
 7846{
 7847	mutex_destroy(&reporter->dump_lock);
 7848	if (reporter->dump_fmsg)
 7849		devlink_fmsg_free(reporter->dump_fmsg);
 7850	kfree(reporter);
 7851}
 7852
 7853static void
 7854devlink_health_reporter_put(struct devlink_health_reporter *reporter)
 7855{
 7856	if (refcount_dec_and_test(&reporter->refcount))
 7857		devlink_health_reporter_free(reporter);
 7858}
 7859
 7860static void
 7861__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
 7862{
 7863	list_del(&reporter->list);
 7864	devlink_health_reporter_put(reporter);
 7865}
 7866
 7867/**
 7868 *	devlink_health_reporter_destroy - destroy devlink health reporter
 7869 *
 7870 *	@reporter: devlink health reporter to destroy
 7871 */
 7872void
 7873devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
 7874{
 7875	struct mutex *lock = &reporter->devlink->reporters_lock;
 7876
 7877	mutex_lock(lock);
 7878	__devlink_health_reporter_destroy(reporter);
 7879	mutex_unlock(lock);
 7880}
 7881EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
 7882
 7883/**
 7884 *	devlink_port_health_reporter_destroy - destroy devlink port health reporter
 7885 *
 7886 *	@reporter: devlink health reporter to destroy
 7887 */
 7888void
 7889devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
 7890{
 7891	struct mutex *lock = &reporter->devlink_port->reporters_lock;
 7892
 7893	mutex_lock(lock);
 7894	__devlink_health_reporter_destroy(reporter);
 7895	mutex_unlock(lock);
 7896}
 7897EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
 7898
 7899static int
 7900devlink_nl_health_reporter_fill(struct sk_buff *msg,
 7901				struct devlink_health_reporter *reporter,
 7902				enum devlink_command cmd, u32 portid,
 7903				u32 seq, int flags)
 7904{
 7905	struct devlink *devlink = reporter->devlink;
 7906	struct nlattr *reporter_attr;
 7907	void *hdr;
 7908
 7909	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 7910	if (!hdr)
 7911		return -EMSGSIZE;
 7912
 7913	if (devlink_nl_put_handle(msg, devlink))
 7914		goto genlmsg_cancel;
 7915
 7916	if (reporter->devlink_port) {
 7917		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
 7918			goto genlmsg_cancel;
 7919	}
 7920	reporter_attr = nla_nest_start_noflag(msg,
 7921					      DEVLINK_ATTR_HEALTH_REPORTER);
 7922	if (!reporter_attr)
 7923		goto genlmsg_cancel;
 7924	if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
 7925			   reporter->ops->name))
 7926		goto reporter_nest_cancel;
 7927	if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
 7928		       reporter->health_state))
 7929		goto reporter_nest_cancel;
 7930	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
 7931			      reporter->error_count, DEVLINK_ATTR_PAD))
 7932		goto reporter_nest_cancel;
 7933	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
 7934			      reporter->recovery_count, DEVLINK_ATTR_PAD))
 7935		goto reporter_nest_cancel;
 7936	if (reporter->ops->recover &&
 7937	    nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
 7938			      reporter->graceful_period,
 7939			      DEVLINK_ATTR_PAD))
 7940		goto reporter_nest_cancel;
 7941	if (reporter->ops->recover &&
 7942	    nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
 7943		       reporter->auto_recover))
 7944		goto reporter_nest_cancel;
 7945	if (reporter->dump_fmsg &&
 7946	    nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
 7947			      jiffies_to_msecs(reporter->dump_ts),
 7948			      DEVLINK_ATTR_PAD))
 7949		goto reporter_nest_cancel;
 7950	if (reporter->dump_fmsg &&
 7951	    nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
 7952			      reporter->dump_real_ts, DEVLINK_ATTR_PAD))
 7953		goto reporter_nest_cancel;
 7954	if (reporter->ops->dump &&
 7955	    nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
 7956		       reporter->auto_dump))
 7957		goto reporter_nest_cancel;
 7958
 7959	nla_nest_end(msg, reporter_attr);
 7960	genlmsg_end(msg, hdr);
 7961	return 0;
 7962
 7963reporter_nest_cancel:
 7964	nla_nest_end(msg, reporter_attr);
 7965genlmsg_cancel:
 7966	genlmsg_cancel(msg, hdr);
 7967	return -EMSGSIZE;
 7968}
 7969
 7970static void devlink_recover_notify(struct devlink_health_reporter *reporter,
 7971				   enum devlink_command cmd)
 7972{
 7973	struct devlink *devlink = reporter->devlink;
 7974	struct sk_buff *msg;
 7975	int err;
 7976
 7977	WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
 7978	WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
 7979
 7980	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 7981	if (!msg)
 7982		return;
 7983
 7984	err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
 7985	if (err) {
 7986		nlmsg_free(msg);
 7987		return;
 7988	}
 7989
 7990	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
 7991				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 7992}
 7993
 7994void
 7995devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
 7996{
 7997	reporter->recovery_count++;
 7998	reporter->last_recovery_ts = jiffies;
 7999}
 8000EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
 8001
 8002static int
 8003devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
 8004				void *priv_ctx, struct netlink_ext_ack *extack)
 8005{
 8006	int err;
 8007
 8008	if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
 8009		return 0;
 8010
 8011	if (!reporter->ops->recover)
 8012		return -EOPNOTSUPP;
 8013
 8014	err = reporter->ops->recover(reporter, priv_ctx, extack);
 8015	if (err)
 8016		return err;
 8017
 8018	devlink_health_reporter_recovery_done(reporter);
 8019	reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
 8020	devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
 8021
 8022	return 0;
 8023}
 8024
 8025static void
 8026devlink_health_dump_clear(struct devlink_health_reporter *reporter)
 8027{
 8028	if (!reporter->dump_fmsg)
 8029		return;
 8030	devlink_fmsg_free(reporter->dump_fmsg);
 8031	reporter->dump_fmsg = NULL;
 8032}
 8033
 8034static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
 8035				  void *priv_ctx,
 8036				  struct netlink_ext_ack *extack)
 8037{
 8038	int err;
 8039
 8040	if (!reporter->ops->dump)
 8041		return 0;
 8042
 8043	if (reporter->dump_fmsg)
 8044		return 0;
 8045
 8046	reporter->dump_fmsg = devlink_fmsg_alloc();
 8047	if (!reporter->dump_fmsg) {
 8048		err = -ENOMEM;
 8049		return err;
 8050	}
 8051
 8052	err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
 8053	if (err)
 8054		goto dump_err;
 8055
 8056	err = reporter->ops->dump(reporter, reporter->dump_fmsg,
 8057				  priv_ctx, extack);
 8058	if (err)
 8059		goto dump_err;
 8060
 8061	err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
 8062	if (err)
 8063		goto dump_err;
 8064
 8065	reporter->dump_ts = jiffies;
 8066	reporter->dump_real_ts = ktime_get_real_ns();
 8067
 8068	return 0;
 8069
 8070dump_err:
 8071	devlink_health_dump_clear(reporter);
 8072	return err;
 8073}
 8074
 8075int devlink_health_report(struct devlink_health_reporter *reporter,
 8076			  const char *msg, void *priv_ctx)
 8077{
 8078	enum devlink_health_reporter_state prev_health_state;
 8079	struct devlink *devlink = reporter->devlink;
 8080	unsigned long recover_ts_threshold;
 8081	int ret;
 8082
 8083	/* write a log message of the current error */
 8084	WARN_ON(!msg);
 8085	trace_devlink_health_report(devlink, reporter->ops->name, msg);
 8086	reporter->error_count++;
 8087	prev_health_state = reporter->health_state;
 8088	reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
 8089	devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
 8090
 8091	/* abort if the previous error wasn't recovered */
 8092	recover_ts_threshold = reporter->last_recovery_ts +
 8093			       msecs_to_jiffies(reporter->graceful_period);
 8094	if (reporter->auto_recover &&
 8095	    (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
 8096	     (reporter->last_recovery_ts && reporter->recovery_count &&
 8097	      time_is_after_jiffies(recover_ts_threshold)))) {
 8098		trace_devlink_health_recover_aborted(devlink,
 8099						     reporter->ops->name,
 8100						     reporter->health_state,
 8101						     jiffies -
 8102						     reporter->last_recovery_ts);
 8103		return -ECANCELED;
 8104	}
 8105
 8106	if (reporter->auto_dump) {
 8107		mutex_lock(&reporter->dump_lock);
 8108		/* store current dump of current error, for later analysis */
 8109		devlink_health_do_dump(reporter, priv_ctx, NULL);
 8110		mutex_unlock(&reporter->dump_lock);
 8111	}
 8112
 8113	if (!reporter->auto_recover)
 8114		return 0;
 8115
 8116	devl_lock(devlink);
 8117	ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
 8118	devl_unlock(devlink);
 8119
 8120	return ret;
 8121}
 8122EXPORT_SYMBOL_GPL(devlink_health_report);
 8123
 8124static struct devlink_health_reporter *
 8125devlink_health_reporter_get_from_attrs(struct devlink *devlink,
 8126				       struct nlattr **attrs)
 8127{
 8128	struct devlink_health_reporter *reporter;
 8129	struct devlink_port *devlink_port;
 8130	char *reporter_name;
 8131
 8132	if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
 8133		return NULL;
 8134
 8135	reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
 8136	devlink_port = devlink_port_get_from_attrs(devlink, attrs);
 8137	if (IS_ERR(devlink_port)) {
 8138		mutex_lock(&devlink->reporters_lock);
 8139		reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
 8140		if (reporter)
 8141			refcount_inc(&reporter->refcount);
 8142		mutex_unlock(&devlink->reporters_lock);
 8143	} else {
 8144		mutex_lock(&devlink_port->reporters_lock);
 8145		reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
 8146		if (reporter)
 8147			refcount_inc(&reporter->refcount);
 8148		mutex_unlock(&devlink_port->reporters_lock);
 8149	}
 8150
 8151	return reporter;
 8152}
 8153
 8154static struct devlink_health_reporter *
 8155devlink_health_reporter_get_from_info(struct devlink *devlink,
 8156				      struct genl_info *info)
 8157{
 8158	return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
 8159}
 8160
 8161static struct devlink_health_reporter *
 8162devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
 8163{
 8164	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
 8165	struct devlink_health_reporter *reporter;
 8166	struct nlattr **attrs = info->attrs;
 8167	struct devlink *devlink;
 8168
 8169	devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
 8170	if (IS_ERR(devlink))
 8171		return NULL;
 8172
 8173	reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
 8174	devlink_put(devlink);
 8175	return reporter;
 8176}
 8177
 8178void
 8179devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
 8180				     enum devlink_health_reporter_state state)
 8181{
 8182	if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
 8183		    state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
 8184		return;
 8185
 8186	if (reporter->health_state == state)
 8187		return;
 8188
 8189	reporter->health_state = state;
 8190	trace_devlink_health_reporter_state_update(reporter->devlink,
 8191						   reporter->ops->name, state);
 8192	devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
 8193}
 8194EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
 8195
 8196static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
 8197						   struct genl_info *info)
 8198{
 8199	struct devlink *devlink = info->user_ptr[0];
 8200	struct devlink_health_reporter *reporter;
 8201	struct sk_buff *msg;
 8202	int err;
 8203
 8204	reporter = devlink_health_reporter_get_from_info(devlink, info);
 8205	if (!reporter)
 8206		return -EINVAL;
 8207
 8208	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 8209	if (!msg) {
 8210		err = -ENOMEM;
 8211		goto out;
 8212	}
 8213
 8214	err = devlink_nl_health_reporter_fill(msg, reporter,
 8215					      DEVLINK_CMD_HEALTH_REPORTER_GET,
 8216					      info->snd_portid, info->snd_seq,
 8217					      0);
 8218	if (err) {
 8219		nlmsg_free(msg);
 8220		goto out;
 8221	}
 8222
 8223	err = genlmsg_reply(msg, info);
 8224out:
 8225	devlink_health_reporter_put(reporter);
 8226	return err;
 8227}
 8228
 8229static int
 8230devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
 8231					  struct netlink_callback *cb)
 8232{
 8233	struct devlink_health_reporter *reporter;
 8234	unsigned long index, port_index;
 8235	struct devlink_port *port;
 8236	struct devlink *devlink;
 8237	int start = cb->args[0];
 8238	int idx = 0;
 8239	int err;
 8240
 8241	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 8242		mutex_lock(&devlink->reporters_lock);
 8243		list_for_each_entry(reporter, &devlink->reporter_list,
 8244				    list) {
 8245			if (idx < start) {
 8246				idx++;
 8247				continue;
 8248			}
 8249			err = devlink_nl_health_reporter_fill(
 8250				msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET,
 8251				NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
 8252				NLM_F_MULTI);
 8253			if (err) {
 8254				mutex_unlock(&devlink->reporters_lock);
 8255				devlink_put(devlink);
 8256				goto out;
 8257			}
 8258			idx++;
 8259		}
 8260		mutex_unlock(&devlink->reporters_lock);
 8261		devlink_put(devlink);
 8262	}
 8263
 8264	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 8265		devl_lock(devlink);
 8266		xa_for_each(&devlink->ports, port_index, port) {
 8267			mutex_lock(&port->reporters_lock);
 8268			list_for_each_entry(reporter, &port->reporter_list, list) {
 8269				if (idx < start) {
 8270					idx++;
 8271					continue;
 8272				}
 8273				err = devlink_nl_health_reporter_fill(
 8274					msg, reporter,
 8275					DEVLINK_CMD_HEALTH_REPORTER_GET,
 8276					NETLINK_CB(cb->skb).portid,
 8277					cb->nlh->nlmsg_seq, NLM_F_MULTI);
 8278				if (err) {
 8279					mutex_unlock(&port->reporters_lock);
 8280					devl_unlock(devlink);
 8281					devlink_put(devlink);
 8282					goto out;
 8283				}
 8284				idx++;
 8285			}
 8286			mutex_unlock(&port->reporters_lock);
 8287		}
 8288		devl_unlock(devlink);
 8289		devlink_put(devlink);
 8290	}
 8291out:
 8292	cb->args[0] = idx;
 8293	return msg->len;
 8294}
 8295
 8296static int
 8297devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
 8298					struct genl_info *info)
 8299{
 8300	struct devlink *devlink = info->user_ptr[0];
 8301	struct devlink_health_reporter *reporter;
 8302	int err;
 8303
 8304	reporter = devlink_health_reporter_get_from_info(devlink, info);
 8305	if (!reporter)
 8306		return -EINVAL;
 8307
 8308	if (!reporter->ops->recover &&
 8309	    (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
 8310	     info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
 8311		err = -EOPNOTSUPP;
 8312		goto out;
 8313	}
 8314	if (!reporter->ops->dump &&
 8315	    info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
 8316		err = -EOPNOTSUPP;
 8317		goto out;
 8318	}
 8319
 8320	if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
 8321		reporter->graceful_period =
 8322			nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
 8323
 8324	if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
 8325		reporter->auto_recover =
 8326			nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
 8327
 8328	if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
 8329		reporter->auto_dump =
 8330		nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
 8331
 8332	devlink_health_reporter_put(reporter);
 8333	return 0;
 8334out:
 8335	devlink_health_reporter_put(reporter);
 8336	return err;
 8337}
 8338
 8339static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
 8340						       struct genl_info *info)
 8341{
 8342	struct devlink *devlink = info->user_ptr[0];
 8343	struct devlink_health_reporter *reporter;
 8344	int err;
 8345
 8346	reporter = devlink_health_reporter_get_from_info(devlink, info);
 8347	if (!reporter)
 8348		return -EINVAL;
 8349
 8350	err = devlink_health_reporter_recover(reporter, NULL, info->extack);
 8351
 8352	devlink_health_reporter_put(reporter);
 8353	return err;
 8354}
 8355
 8356static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
 8357							struct genl_info *info)
 8358{
 8359	struct devlink *devlink = info->user_ptr[0];
 8360	struct devlink_health_reporter *reporter;
 8361	struct devlink_fmsg *fmsg;
 8362	int err;
 8363
 8364	reporter = devlink_health_reporter_get_from_info(devlink, info);
 8365	if (!reporter)
 8366		return -EINVAL;
 8367
 8368	if (!reporter->ops->diagnose) {
 8369		devlink_health_reporter_put(reporter);
 8370		return -EOPNOTSUPP;
 8371	}
 8372
 8373	fmsg = devlink_fmsg_alloc();
 8374	if (!fmsg) {
 8375		devlink_health_reporter_put(reporter);
 8376		return -ENOMEM;
 8377	}
 8378
 8379	err = devlink_fmsg_obj_nest_start(fmsg);
 8380	if (err)
 8381		goto out;
 8382
 8383	err = reporter->ops->diagnose(reporter, fmsg, info->extack);
 8384	if (err)
 8385		goto out;
 8386
 8387	err = devlink_fmsg_obj_nest_end(fmsg);
 8388	if (err)
 8389		goto out;
 8390
 8391	err = devlink_fmsg_snd(fmsg, info,
 8392			       DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
 8393
 8394out:
 8395	devlink_fmsg_free(fmsg);
 8396	devlink_health_reporter_put(reporter);
 8397	return err;
 8398}
 8399
 8400static int
 8401devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
 8402					       struct netlink_callback *cb)
 8403{
 8404	struct devlink_health_reporter *reporter;
 8405	u64 start = cb->args[0];
 8406	int err;
 8407
 8408	reporter = devlink_health_reporter_get_from_cb(cb);
 8409	if (!reporter)
 8410		return -EINVAL;
 8411
 8412	if (!reporter->ops->dump) {
 8413		err = -EOPNOTSUPP;
 8414		goto out;
 8415	}
 8416	mutex_lock(&reporter->dump_lock);
 8417	if (!start) {
 8418		err = devlink_health_do_dump(reporter, NULL, cb->extack);
 8419		if (err)
 8420			goto unlock;
 8421		cb->args[1] = reporter->dump_ts;
 8422	}
 8423	if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
 8424		NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
 8425		err = -EAGAIN;
 8426		goto unlock;
 8427	}
 8428
 8429	err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
 8430				  DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
 8431unlock:
 8432	mutex_unlock(&reporter->dump_lock);
 8433out:
 8434	devlink_health_reporter_put(reporter);
 8435	return err;
 8436}
 8437
 8438static int
 8439devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
 8440					       struct genl_info *info)
 8441{
 8442	struct devlink *devlink = info->user_ptr[0];
 8443	struct devlink_health_reporter *reporter;
 8444
 8445	reporter = devlink_health_reporter_get_from_info(devlink, info);
 8446	if (!reporter)
 8447		return -EINVAL;
 8448
 8449	if (!reporter->ops->dump) {
 8450		devlink_health_reporter_put(reporter);
 8451		return -EOPNOTSUPP;
 8452	}
 8453
 8454	mutex_lock(&reporter->dump_lock);
 8455	devlink_health_dump_clear(reporter);
 8456	mutex_unlock(&reporter->dump_lock);
 8457	devlink_health_reporter_put(reporter);
 8458	return 0;
 8459}
 8460
 8461static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
 8462						    struct genl_info *info)
 8463{
 8464	struct devlink *devlink = info->user_ptr[0];
 8465	struct devlink_health_reporter *reporter;
 8466	int err;
 8467
 8468	reporter = devlink_health_reporter_get_from_info(devlink, info);
 8469	if (!reporter)
 8470		return -EINVAL;
 8471
 8472	if (!reporter->ops->test) {
 8473		devlink_health_reporter_put(reporter);
 8474		return -EOPNOTSUPP;
 8475	}
 8476
 8477	err = reporter->ops->test(reporter, info->extack);
 8478
 8479	devlink_health_reporter_put(reporter);
 8480	return err;
 8481}
 8482
 8483struct devlink_stats {
 8484	u64_stats_t rx_bytes;
 8485	u64_stats_t rx_packets;
 8486	struct u64_stats_sync syncp;
 8487};
 8488
 8489/**
 8490 * struct devlink_trap_policer_item - Packet trap policer attributes.
 8491 * @policer: Immutable packet trap policer attributes.
 8492 * @rate: Rate in packets / sec.
 8493 * @burst: Burst size in packets.
 8494 * @list: trap_policer_list member.
 8495 *
 8496 * Describes packet trap policer attributes. Created by devlink during trap
 8497 * policer registration.
 8498 */
 8499struct devlink_trap_policer_item {
 8500	const struct devlink_trap_policer *policer;
 8501	u64 rate;
 8502	u64 burst;
 8503	struct list_head list;
 8504};
 8505
 8506/**
 8507 * struct devlink_trap_group_item - Packet trap group attributes.
 8508 * @group: Immutable packet trap group attributes.
 8509 * @policer_item: Associated policer item. Can be NULL.
 8510 * @list: trap_group_list member.
 8511 * @stats: Trap group statistics.
 8512 *
 8513 * Describes packet trap group attributes. Created by devlink during trap
 8514 * group registration.
 8515 */
 8516struct devlink_trap_group_item {
 8517	const struct devlink_trap_group *group;
 8518	struct devlink_trap_policer_item *policer_item;
 8519	struct list_head list;
 8520	struct devlink_stats __percpu *stats;
 8521};
 8522
 8523/**
 8524 * struct devlink_trap_item - Packet trap attributes.
 8525 * @trap: Immutable packet trap attributes.
 8526 * @group_item: Associated group item.
 8527 * @list: trap_list member.
 8528 * @action: Trap action.
 8529 * @stats: Trap statistics.
 8530 * @priv: Driver private information.
 8531 *
 8532 * Describes both mutable and immutable packet trap attributes. Created by
 8533 * devlink during trap registration and used for all trap related operations.
 8534 */
 8535struct devlink_trap_item {
 8536	const struct devlink_trap *trap;
 8537	struct devlink_trap_group_item *group_item;
 8538	struct list_head list;
 8539	enum devlink_trap_action action;
 8540	struct devlink_stats __percpu *stats;
 8541	void *priv;
 8542};
 8543
 8544static struct devlink_trap_policer_item *
 8545devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
 8546{
 8547	struct devlink_trap_policer_item *policer_item;
 8548
 8549	list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
 8550		if (policer_item->policer->id == id)
 8551			return policer_item;
 8552	}
 8553
 8554	return NULL;
 8555}
 8556
 8557static struct devlink_trap_item *
 8558devlink_trap_item_lookup(struct devlink *devlink, const char *name)
 8559{
 8560	struct devlink_trap_item *trap_item;
 8561
 8562	list_for_each_entry(trap_item, &devlink->trap_list, list) {
 8563		if (!strcmp(trap_item->trap->name, name))
 8564			return trap_item;
 8565	}
 8566
 8567	return NULL;
 8568}
 8569
 8570static struct devlink_trap_item *
 8571devlink_trap_item_get_from_info(struct devlink *devlink,
 8572				struct genl_info *info)
 8573{
 8574	struct nlattr *attr;
 8575
 8576	if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
 8577		return NULL;
 8578	attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
 8579
 8580	return devlink_trap_item_lookup(devlink, nla_data(attr));
 8581}
 8582
 8583static int
 8584devlink_trap_action_get_from_info(struct genl_info *info,
 8585				  enum devlink_trap_action *p_trap_action)
 8586{
 8587	u8 val;
 8588
 8589	val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
 8590	switch (val) {
 8591	case DEVLINK_TRAP_ACTION_DROP:
 8592	case DEVLINK_TRAP_ACTION_TRAP:
 8593	case DEVLINK_TRAP_ACTION_MIRROR:
 8594		*p_trap_action = val;
 8595		break;
 8596	default:
 8597		return -EINVAL;
 8598	}
 8599
 8600	return 0;
 8601}
 8602
 8603static int devlink_trap_metadata_put(struct sk_buff *msg,
 8604				     const struct devlink_trap *trap)
 8605{
 8606	struct nlattr *attr;
 8607
 8608	attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
 8609	if (!attr)
 8610		return -EMSGSIZE;
 8611
 8612	if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
 8613	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
 8614		goto nla_put_failure;
 8615	if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
 8616	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
 8617		goto nla_put_failure;
 8618
 8619	nla_nest_end(msg, attr);
 8620
 8621	return 0;
 8622
 8623nla_put_failure:
 8624	nla_nest_cancel(msg, attr);
 8625	return -EMSGSIZE;
 8626}
 8627
 8628static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
 8629				    struct devlink_stats *stats)
 8630{
 8631	int i;
 8632
 8633	memset(stats, 0, sizeof(*stats));
 8634	for_each_possible_cpu(i) {
 8635		struct devlink_stats *cpu_stats;
 8636		u64 rx_packets, rx_bytes;
 8637		unsigned int start;
 8638
 8639		cpu_stats = per_cpu_ptr(trap_stats, i);
 8640		do {
 8641			start = u64_stats_fetch_begin(&cpu_stats->syncp);
 8642			rx_packets = u64_stats_read(&cpu_stats->rx_packets);
 8643			rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
 8644		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
 8645
 8646		u64_stats_add(&stats->rx_packets, rx_packets);
 8647		u64_stats_add(&stats->rx_bytes, rx_bytes);
 8648	}
 8649}
 8650
 8651static int
 8652devlink_trap_group_stats_put(struct sk_buff *msg,
 8653			     struct devlink_stats __percpu *trap_stats)
 8654{
 8655	struct devlink_stats stats;
 8656	struct nlattr *attr;
 8657
 8658	devlink_trap_stats_read(trap_stats, &stats);
 8659
 8660	attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
 8661	if (!attr)
 8662		return -EMSGSIZE;
 8663
 8664	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
 8665			      u64_stats_read(&stats.rx_packets),
 8666			      DEVLINK_ATTR_PAD))
 8667		goto nla_put_failure;
 8668
 8669	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
 8670			      u64_stats_read(&stats.rx_bytes),
 8671			      DEVLINK_ATTR_PAD))
 8672		goto nla_put_failure;
 8673
 8674	nla_nest_end(msg, attr);
 8675
 8676	return 0;
 8677
 8678nla_put_failure:
 8679	nla_nest_cancel(msg, attr);
 8680	return -EMSGSIZE;
 8681}
 8682
 8683static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
 8684				  const struct devlink_trap_item *trap_item)
 8685{
 8686	struct devlink_stats stats;
 8687	struct nlattr *attr;
 8688	u64 drops = 0;
 8689	int err;
 8690
 8691	if (devlink->ops->trap_drop_counter_get) {
 8692		err = devlink->ops->trap_drop_counter_get(devlink,
 8693							  trap_item->trap,
 8694							  &drops);
 8695		if (err)
 8696			return err;
 8697	}
 8698
 8699	devlink_trap_stats_read(trap_item->stats, &stats);
 8700
 8701	attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
 8702	if (!attr)
 8703		return -EMSGSIZE;
 8704
 8705	if (devlink->ops->trap_drop_counter_get &&
 8706	    nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
 8707			      DEVLINK_ATTR_PAD))
 8708		goto nla_put_failure;
 8709
 8710	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
 8711			      u64_stats_read(&stats.rx_packets),
 8712			      DEVLINK_ATTR_PAD))
 8713		goto nla_put_failure;
 8714
 8715	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
 8716			      u64_stats_read(&stats.rx_bytes),
 8717			      DEVLINK_ATTR_PAD))
 8718		goto nla_put_failure;
 8719
 8720	nla_nest_end(msg, attr);
 8721
 8722	return 0;
 8723
 8724nla_put_failure:
 8725	nla_nest_cancel(msg, attr);
 8726	return -EMSGSIZE;
 8727}
 8728
 8729static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
 8730				const struct devlink_trap_item *trap_item,
 8731				enum devlink_command cmd, u32 portid, u32 seq,
 8732				int flags)
 8733{
 8734	struct devlink_trap_group_item *group_item = trap_item->group_item;
 8735	void *hdr;
 8736	int err;
 8737
 8738	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 8739	if (!hdr)
 8740		return -EMSGSIZE;
 8741
 8742	if (devlink_nl_put_handle(msg, devlink))
 8743		goto nla_put_failure;
 8744
 8745	if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
 8746			   group_item->group->name))
 8747		goto nla_put_failure;
 8748
 8749	if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
 8750		goto nla_put_failure;
 8751
 8752	if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
 8753		goto nla_put_failure;
 8754
 8755	if (trap_item->trap->generic &&
 8756	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
 8757		goto nla_put_failure;
 8758
 8759	if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
 8760		goto nla_put_failure;
 8761
 8762	err = devlink_trap_metadata_put(msg, trap_item->trap);
 8763	if (err)
 8764		goto nla_put_failure;
 8765
 8766	err = devlink_trap_stats_put(msg, devlink, trap_item);
 8767	if (err)
 8768		goto nla_put_failure;
 8769
 8770	genlmsg_end(msg, hdr);
 8771
 8772	return 0;
 8773
 8774nla_put_failure:
 8775	genlmsg_cancel(msg, hdr);
 8776	return -EMSGSIZE;
 8777}
 8778
 8779static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
 8780					struct genl_info *info)
 8781{
 8782	struct netlink_ext_ack *extack = info->extack;
 8783	struct devlink *devlink = info->user_ptr[0];
 8784	struct devlink_trap_item *trap_item;
 8785	struct sk_buff *msg;
 8786	int err;
 8787
 8788	if (list_empty(&devlink->trap_list))
 8789		return -EOPNOTSUPP;
 8790
 8791	trap_item = devlink_trap_item_get_from_info(devlink, info);
 8792	if (!trap_item) {
 8793		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
 8794		return -ENOENT;
 8795	}
 8796
 8797	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 8798	if (!msg)
 8799		return -ENOMEM;
 8800
 8801	err = devlink_nl_trap_fill(msg, devlink, trap_item,
 8802				   DEVLINK_CMD_TRAP_NEW, info->snd_portid,
 8803				   info->snd_seq, 0);
 8804	if (err)
 8805		goto err_trap_fill;
 8806
 8807	return genlmsg_reply(msg, info);
 8808
 8809err_trap_fill:
 8810	nlmsg_free(msg);
 8811	return err;
 8812}
 8813
 8814static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
 8815					  struct netlink_callback *cb)
 8816{
 8817	struct devlink_trap_item *trap_item;
 8818	struct devlink *devlink;
 8819	int start = cb->args[0];
 8820	unsigned long index;
 8821	int idx = 0;
 8822	int err;
 8823
 8824	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 8825		devl_lock(devlink);
 8826		list_for_each_entry(trap_item, &devlink->trap_list, list) {
 8827			if (idx < start) {
 8828				idx++;
 8829				continue;
 8830			}
 8831			err = devlink_nl_trap_fill(msg, devlink, trap_item,
 8832						   DEVLINK_CMD_TRAP_NEW,
 8833						   NETLINK_CB(cb->skb).portid,
 8834						   cb->nlh->nlmsg_seq,
 8835						   NLM_F_MULTI);
 8836			if (err) {
 8837				devl_unlock(devlink);
 8838				devlink_put(devlink);
 8839				goto out;
 8840			}
 8841			idx++;
 8842		}
 8843		devl_unlock(devlink);
 8844		devlink_put(devlink);
 8845	}
 8846out:
 8847	cb->args[0] = idx;
 8848	return msg->len;
 8849}
 8850
 8851static int __devlink_trap_action_set(struct devlink *devlink,
 8852				     struct devlink_trap_item *trap_item,
 8853				     enum devlink_trap_action trap_action,
 8854				     struct netlink_ext_ack *extack)
 8855{
 8856	int err;
 8857
 8858	if (trap_item->action != trap_action &&
 8859	    trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
 8860		NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
 8861		return 0;
 8862	}
 8863
 8864	err = devlink->ops->trap_action_set(devlink, trap_item->trap,
 8865					    trap_action, extack);
 8866	if (err)
 8867		return err;
 8868
 8869	trap_item->action = trap_action;
 8870
 8871	return 0;
 8872}
 8873
 8874static int devlink_trap_action_set(struct devlink *devlink,
 8875				   struct devlink_trap_item *trap_item,
 8876				   struct genl_info *info)
 8877{
 8878	enum devlink_trap_action trap_action;
 8879	int err;
 8880
 8881	if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
 8882		return 0;
 8883
 8884	err = devlink_trap_action_get_from_info(info, &trap_action);
 8885	if (err) {
 8886		NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
 8887		return -EINVAL;
 8888	}
 8889
 8890	return __devlink_trap_action_set(devlink, trap_item, trap_action,
 8891					 info->extack);
 8892}
 8893
 8894static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
 8895					struct genl_info *info)
 8896{
 8897	struct netlink_ext_ack *extack = info->extack;
 8898	struct devlink *devlink = info->user_ptr[0];
 8899	struct devlink_trap_item *trap_item;
 8900
 8901	if (list_empty(&devlink->trap_list))
 8902		return -EOPNOTSUPP;
 8903
 8904	trap_item = devlink_trap_item_get_from_info(devlink, info);
 8905	if (!trap_item) {
 8906		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
 8907		return -ENOENT;
 8908	}
 8909
 8910	return devlink_trap_action_set(devlink, trap_item, info);
 8911}
 8912
 8913static struct devlink_trap_group_item *
 8914devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
 8915{
 8916	struct devlink_trap_group_item *group_item;
 8917
 8918	list_for_each_entry(group_item, &devlink->trap_group_list, list) {
 8919		if (!strcmp(group_item->group->name, name))
 8920			return group_item;
 8921	}
 8922
 8923	return NULL;
 8924}
 8925
 8926static struct devlink_trap_group_item *
 8927devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
 8928{
 8929	struct devlink_trap_group_item *group_item;
 8930
 8931	list_for_each_entry(group_item, &devlink->trap_group_list, list) {
 8932		if (group_item->group->id == id)
 8933			return group_item;
 8934	}
 8935
 8936	return NULL;
 8937}
 8938
 8939static struct devlink_trap_group_item *
 8940devlink_trap_group_item_get_from_info(struct devlink *devlink,
 8941				      struct genl_info *info)
 8942{
 8943	char *name;
 8944
 8945	if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
 8946		return NULL;
 8947	name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
 8948
 8949	return devlink_trap_group_item_lookup(devlink, name);
 8950}
 8951
 8952static int
 8953devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
 8954			   const struct devlink_trap_group_item *group_item,
 8955			   enum devlink_command cmd, u32 portid, u32 seq,
 8956			   int flags)
 8957{
 8958	void *hdr;
 8959	int err;
 8960
 8961	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 8962	if (!hdr)
 8963		return -EMSGSIZE;
 8964
 8965	if (devlink_nl_put_handle(msg, devlink))
 8966		goto nla_put_failure;
 8967
 8968	if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
 8969			   group_item->group->name))
 8970		goto nla_put_failure;
 8971
 8972	if (group_item->group->generic &&
 8973	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
 8974		goto nla_put_failure;
 8975
 8976	if (group_item->policer_item &&
 8977	    nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
 8978			group_item->policer_item->policer->id))
 8979		goto nla_put_failure;
 8980
 8981	err = devlink_trap_group_stats_put(msg, group_item->stats);
 8982	if (err)
 8983		goto nla_put_failure;
 8984
 8985	genlmsg_end(msg, hdr);
 8986
 8987	return 0;
 8988
 8989nla_put_failure:
 8990	genlmsg_cancel(msg, hdr);
 8991	return -EMSGSIZE;
 8992}
 8993
 8994static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
 8995					      struct genl_info *info)
 8996{
 8997	struct netlink_ext_ack *extack = info->extack;
 8998	struct devlink *devlink = info->user_ptr[0];
 8999	struct devlink_trap_group_item *group_item;
 9000	struct sk_buff *msg;
 9001	int err;
 9002
 9003	if (list_empty(&devlink->trap_group_list))
 9004		return -EOPNOTSUPP;
 9005
 9006	group_item = devlink_trap_group_item_get_from_info(devlink, info);
 9007	if (!group_item) {
 9008		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
 9009		return -ENOENT;
 9010	}
 9011
 9012	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 9013	if (!msg)
 9014		return -ENOMEM;
 9015
 9016	err = devlink_nl_trap_group_fill(msg, devlink, group_item,
 9017					 DEVLINK_CMD_TRAP_GROUP_NEW,
 9018					 info->snd_portid, info->snd_seq, 0);
 9019	if (err)
 9020		goto err_trap_group_fill;
 9021
 9022	return genlmsg_reply(msg, info);
 9023
 9024err_trap_group_fill:
 9025	nlmsg_free(msg);
 9026	return err;
 9027}
 9028
 9029static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
 9030						struct netlink_callback *cb)
 9031{
 9032	enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
 9033	struct devlink_trap_group_item *group_item;
 9034	u32 portid = NETLINK_CB(cb->skb).portid;
 9035	struct devlink *devlink;
 9036	int start = cb->args[0];
 9037	unsigned long index;
 9038	int idx = 0;
 9039	int err;
 9040
 9041	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 9042		devl_lock(devlink);
 9043		list_for_each_entry(group_item, &devlink->trap_group_list,
 9044				    list) {
 9045			if (idx < start) {
 9046				idx++;
 9047				continue;
 9048			}
 9049			err = devlink_nl_trap_group_fill(msg, devlink,
 9050							 group_item, cmd,
 9051							 portid,
 9052							 cb->nlh->nlmsg_seq,
 9053							 NLM_F_MULTI);
 9054			if (err) {
 9055				devl_unlock(devlink);
 9056				devlink_put(devlink);
 9057				goto out;
 9058			}
 9059			idx++;
 9060		}
 9061		devl_unlock(devlink);
 9062		devlink_put(devlink);
 9063	}
 9064out:
 9065	cb->args[0] = idx;
 9066	return msg->len;
 9067}
 9068
 9069static int
 9070__devlink_trap_group_action_set(struct devlink *devlink,
 9071				struct devlink_trap_group_item *group_item,
 9072				enum devlink_trap_action trap_action,
 9073				struct netlink_ext_ack *extack)
 9074{
 9075	const char *group_name = group_item->group->name;
 9076	struct devlink_trap_item *trap_item;
 9077	int err;
 9078
 9079	if (devlink->ops->trap_group_action_set) {
 9080		err = devlink->ops->trap_group_action_set(devlink, group_item->group,
 9081							  trap_action, extack);
 9082		if (err)
 9083			return err;
 9084
 9085		list_for_each_entry(trap_item, &devlink->trap_list, list) {
 9086			if (strcmp(trap_item->group_item->group->name, group_name))
 9087				continue;
 9088			if (trap_item->action != trap_action &&
 9089			    trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
 9090				continue;
 9091			trap_item->action = trap_action;
 9092		}
 9093
 9094		return 0;
 9095	}
 9096
 9097	list_for_each_entry(trap_item, &devlink->trap_list, list) {
 9098		if (strcmp(trap_item->group_item->group->name, group_name))
 9099			continue;
 9100		err = __devlink_trap_action_set(devlink, trap_item,
 9101						trap_action, extack);
 9102		if (err)
 9103			return err;
 9104	}
 9105
 9106	return 0;
 9107}
 9108
 9109static int
 9110devlink_trap_group_action_set(struct devlink *devlink,
 9111			      struct devlink_trap_group_item *group_item,
 9112			      struct genl_info *info, bool *p_modified)
 9113{
 9114	enum devlink_trap_action trap_action;
 9115	int err;
 9116
 9117	if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
 9118		return 0;
 9119
 9120	err = devlink_trap_action_get_from_info(info, &trap_action);
 9121	if (err) {
 9122		NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
 9123		return -EINVAL;
 9124	}
 9125
 9126	err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
 9127					      info->extack);
 9128	if (err)
 9129		return err;
 9130
 9131	*p_modified = true;
 9132
 9133	return 0;
 9134}
 9135
 9136static int devlink_trap_group_set(struct devlink *devlink,
 9137				  struct devlink_trap_group_item *group_item,
 9138				  struct genl_info *info)
 9139{
 9140	struct devlink_trap_policer_item *policer_item;
 9141	struct netlink_ext_ack *extack = info->extack;
 9142	const struct devlink_trap_policer *policer;
 9143	struct nlattr **attrs = info->attrs;
 9144	int err;
 9145
 9146	if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
 9147		return 0;
 9148
 9149	if (!devlink->ops->trap_group_set)
 9150		return -EOPNOTSUPP;
 9151
 9152	policer_item = group_item->policer_item;
 9153	if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
 9154		u32 policer_id;
 9155
 9156		policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
 9157		policer_item = devlink_trap_policer_item_lookup(devlink,
 9158								policer_id);
 9159		if (policer_id && !policer_item) {
 9160			NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
 9161			return -ENOENT;
 9162		}
 9163	}
 9164	policer = policer_item ? policer_item->policer : NULL;
 9165
 9166	err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
 9167					   extack);
 9168	if (err)
 9169		return err;
 9170
 9171	group_item->policer_item = policer_item;
 9172
 9173	return 0;
 9174}
 9175
 9176static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
 9177					      struct genl_info *info)
 9178{
 9179	struct netlink_ext_ack *extack = info->extack;
 9180	struct devlink *devlink = info->user_ptr[0];
 9181	struct devlink_trap_group_item *group_item;
 9182	bool modified = false;
 9183	int err;
 9184
 9185	if (list_empty(&devlink->trap_group_list))
 9186		return -EOPNOTSUPP;
 9187
 9188	group_item = devlink_trap_group_item_get_from_info(devlink, info);
 9189	if (!group_item) {
 9190		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
 9191		return -ENOENT;
 9192	}
 9193
 9194	err = devlink_trap_group_action_set(devlink, group_item, info,
 9195					    &modified);
 9196	if (err)
 9197		return err;
 9198
 9199	err = devlink_trap_group_set(devlink, group_item, info);
 9200	if (err)
 9201		goto err_trap_group_set;
 9202
 9203	return 0;
 9204
 9205err_trap_group_set:
 9206	if (modified)
 9207		NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
 9208	return err;
 9209}
 9210
 9211static struct devlink_trap_policer_item *
 9212devlink_trap_policer_item_get_from_info(struct devlink *devlink,
 9213					struct genl_info *info)
 9214{
 9215	u32 id;
 9216
 9217	if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
 9218		return NULL;
 9219	id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
 9220
 9221	return devlink_trap_policer_item_lookup(devlink, id);
 9222}
 9223
 9224static int
 9225devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
 9226			       const struct devlink_trap_policer *policer)
 9227{
 9228	struct nlattr *attr;
 9229	u64 drops;
 9230	int err;
 9231
 9232	if (!devlink->ops->trap_policer_counter_get)
 9233		return 0;
 9234
 9235	err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
 9236	if (err)
 9237		return err;
 9238
 9239	attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
 9240	if (!attr)
 9241		return -EMSGSIZE;
 9242
 9243	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
 9244			      DEVLINK_ATTR_PAD))
 9245		goto nla_put_failure;
 9246
 9247	nla_nest_end(msg, attr);
 9248
 9249	return 0;
 9250
 9251nla_put_failure:
 9252	nla_nest_cancel(msg, attr);
 9253	return -EMSGSIZE;
 9254}
 9255
 9256static int
 9257devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
 9258			     const struct devlink_trap_policer_item *policer_item,
 9259			     enum devlink_command cmd, u32 portid, u32 seq,
 9260			     int flags)
 9261{
 9262	void *hdr;
 9263	int err;
 9264
 9265	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 9266	if (!hdr)
 9267		return -EMSGSIZE;
 9268
 9269	if (devlink_nl_put_handle(msg, devlink))
 9270		goto nla_put_failure;
 9271
 9272	if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
 9273			policer_item->policer->id))
 9274		goto nla_put_failure;
 9275
 9276	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
 9277			      policer_item->rate, DEVLINK_ATTR_PAD))
 9278		goto nla_put_failure;
 9279
 9280	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
 9281			      policer_item->burst, DEVLINK_ATTR_PAD))
 9282		goto nla_put_failure;
 9283
 9284	err = devlink_trap_policer_stats_put(msg, devlink,
 9285					     policer_item->policer);
 9286	if (err)
 9287		goto nla_put_failure;
 9288
 9289	genlmsg_end(msg, hdr);
 9290
 9291	return 0;
 9292
 9293nla_put_failure:
 9294	genlmsg_cancel(msg, hdr);
 9295	return -EMSGSIZE;
 9296}
 9297
 9298static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
 9299						struct genl_info *info)
 9300{
 9301	struct devlink_trap_policer_item *policer_item;
 9302	struct netlink_ext_ack *extack = info->extack;
 9303	struct devlink *devlink = info->user_ptr[0];
 9304	struct sk_buff *msg;
 9305	int err;
 9306
 9307	if (list_empty(&devlink->trap_policer_list))
 9308		return -EOPNOTSUPP;
 9309
 9310	policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
 9311	if (!policer_item) {
 9312		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
 9313		return -ENOENT;
 9314	}
 9315
 9316	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 9317	if (!msg)
 9318		return -ENOMEM;
 9319
 9320	err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
 9321					   DEVLINK_CMD_TRAP_POLICER_NEW,
 9322					   info->snd_portid, info->snd_seq, 0);
 9323	if (err)
 9324		goto err_trap_policer_fill;
 9325
 9326	return genlmsg_reply(msg, info);
 9327
 9328err_trap_policer_fill:
 9329	nlmsg_free(msg);
 9330	return err;
 9331}
 9332
 9333static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
 9334						  struct netlink_callback *cb)
 9335{
 9336	enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
 9337	struct devlink_trap_policer_item *policer_item;
 9338	u32 portid = NETLINK_CB(cb->skb).portid;
 9339	struct devlink *devlink;
 9340	int start = cb->args[0];
 9341	unsigned long index;
 9342	int idx = 0;
 9343	int err;
 9344
 9345	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
 9346		devl_lock(devlink);
 9347		list_for_each_entry(policer_item, &devlink->trap_policer_list,
 9348				    list) {
 9349			if (idx < start) {
 9350				idx++;
 9351				continue;
 9352			}
 9353			err = devlink_nl_trap_policer_fill(msg, devlink,
 9354							   policer_item, cmd,
 9355							   portid,
 9356							   cb->nlh->nlmsg_seq,
 9357							   NLM_F_MULTI);
 9358			if (err) {
 9359				devl_unlock(devlink);
 9360				devlink_put(devlink);
 9361				goto out;
 9362			}
 9363			idx++;
 9364		}
 9365		devl_unlock(devlink);
 9366		devlink_put(devlink);
 9367	}
 9368out:
 9369	cb->args[0] = idx;
 9370	return msg->len;
 9371}
 9372
 9373static int
 9374devlink_trap_policer_set(struct devlink *devlink,
 9375			 struct devlink_trap_policer_item *policer_item,
 9376			 struct genl_info *info)
 9377{
 9378	struct netlink_ext_ack *extack = info->extack;
 9379	struct nlattr **attrs = info->attrs;
 9380	u64 rate, burst;
 9381	int err;
 9382
 9383	rate = policer_item->rate;
 9384	burst = policer_item->burst;
 9385
 9386	if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
 9387		rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
 9388
 9389	if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
 9390		burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
 9391
 9392	if (rate < policer_item->policer->min_rate) {
 9393		NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
 9394		return -EINVAL;
 9395	}
 9396
 9397	if (rate > policer_item->policer->max_rate) {
 9398		NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
 9399		return -EINVAL;
 9400	}
 9401
 9402	if (burst < policer_item->policer->min_burst) {
 9403		NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
 9404		return -EINVAL;
 9405	}
 9406
 9407	if (burst > policer_item->policer->max_burst) {
 9408		NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
 9409		return -EINVAL;
 9410	}
 9411
 9412	err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
 9413					     rate, burst, info->extack);
 9414	if (err)
 9415		return err;
 9416
 9417	policer_item->rate = rate;
 9418	policer_item->burst = burst;
 9419
 9420	return 0;
 9421}
 9422
 9423static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
 9424						struct genl_info *info)
 9425{
 9426	struct devlink_trap_policer_item *policer_item;
 9427	struct netlink_ext_ack *extack = info->extack;
 9428	struct devlink *devlink = info->user_ptr[0];
 9429
 9430	if (list_empty(&devlink->trap_policer_list))
 9431		return -EOPNOTSUPP;
 9432
 9433	if (!devlink->ops->trap_policer_set)
 9434		return -EOPNOTSUPP;
 9435
 9436	policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
 9437	if (!policer_item) {
 9438		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
 9439		return -ENOENT;
 9440	}
 9441
 9442	return devlink_trap_policer_set(devlink, policer_item, info);
 9443}
 9444
 9445static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
 9446	[DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
 9447		DEVLINK_ATTR_TRAP_POLICER_ID },
 9448	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
 9449	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
 9450	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
 9451	[DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO,
 9452						    DEVLINK_PORT_TYPE_IB),
 9453	[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
 9454	[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
 9455	[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
 9456	[DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
 9457	[DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
 9458	[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
 9459	[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
 9460	[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
 9461	[DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY,
 9462						       DEVLINK_ESWITCH_MODE_SWITCHDEV),
 9463	[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
 9464	[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
 9465	[DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
 9466	[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
 9467	[DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
 9468	[DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
 9469	[DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
 9470	[DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
 9471	[DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
 9472	[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
 9473	[DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
 9474	[DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
 9475	[DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
 9476	[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
 9477	[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
 9478	[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
 9479	[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
 9480	[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
 9481	[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
 9482		NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
 9483	[DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
 9484	[DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
 9485	[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
 9486	[DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
 9487	[DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
 9488	[DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
 9489	[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
 9490	[DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
 9491	[DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
 9492	[DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
 9493	[DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
 9494	[DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
 9495							DEVLINK_RELOAD_ACTION_MAX),
 9496	[DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
 9497	[DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 },
 9498	[DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 },
 9499	[DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 },
 9500	[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 },
 9501	[DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 },
 9502	[DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 },
 9503	[DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 },
 9504	[DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING },
 9505	[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING },
 9506	[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
 9507	[DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
 9508	[DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED },
 9509	[DEVLINK_ATTR_RATE_TX_PRIORITY] = { .type = NLA_U32 },
 9510	[DEVLINK_ATTR_RATE_TX_WEIGHT] = { .type = NLA_U32 },
 9511	[DEVLINK_ATTR_REGION_DIRECT] = { .type = NLA_FLAG },
 9512};
 9513
 9514static const struct genl_small_ops devlink_nl_ops[] = {
 9515	{
 9516		.cmd = DEVLINK_CMD_GET,
 9517		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9518		.doit = devlink_nl_cmd_get_doit,
 9519		.dumpit = devlink_nl_cmd_get_dumpit,
 
 9520		/* can be retrieved by unprivileged users */
 9521	},
 9522	{
 9523		.cmd = DEVLINK_CMD_PORT_GET,
 9524		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9525		.doit = devlink_nl_cmd_port_get_doit,
 9526		.dumpit = devlink_nl_cmd_port_get_dumpit,
 
 9527		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9528		/* can be retrieved by unprivileged users */
 9529	},
 9530	{
 9531		.cmd = DEVLINK_CMD_PORT_SET,
 9532		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9533		.doit = devlink_nl_cmd_port_set_doit,
 
 9534		.flags = GENL_ADMIN_PERM,
 9535		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9536	},
 9537	{
 9538		.cmd = DEVLINK_CMD_RATE_GET,
 9539		.doit = devlink_nl_cmd_rate_get_doit,
 9540		.dumpit = devlink_nl_cmd_rate_get_dumpit,
 9541		.internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
 9542		/* can be retrieved by unprivileged users */
 9543	},
 9544	{
 9545		.cmd = DEVLINK_CMD_RATE_SET,
 9546		.doit = devlink_nl_cmd_rate_set_doit,
 9547		.flags = GENL_ADMIN_PERM,
 9548		.internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
 9549	},
 9550	{
 9551		.cmd = DEVLINK_CMD_RATE_NEW,
 9552		.doit = devlink_nl_cmd_rate_new_doit,
 9553		.flags = GENL_ADMIN_PERM,
 9554	},
 9555	{
 9556		.cmd = DEVLINK_CMD_RATE_DEL,
 9557		.doit = devlink_nl_cmd_rate_del_doit,
 9558		.flags = GENL_ADMIN_PERM,
 9559		.internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
 9560	},
 9561	{
 9562		.cmd = DEVLINK_CMD_PORT_SPLIT,
 9563		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9564		.doit = devlink_nl_cmd_port_split_doit,
 
 9565		.flags = GENL_ADMIN_PERM,
 9566		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9567	},
 9568	{
 9569		.cmd = DEVLINK_CMD_PORT_UNSPLIT,
 9570		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9571		.doit = devlink_nl_cmd_port_unsplit_doit,
 9572		.flags = GENL_ADMIN_PERM,
 9573		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9574	},
 9575	{
 9576		.cmd = DEVLINK_CMD_PORT_NEW,
 9577		.doit = devlink_nl_cmd_port_new_doit,
 9578		.flags = GENL_ADMIN_PERM,
 9579	},
 9580	{
 9581		.cmd = DEVLINK_CMD_PORT_DEL,
 9582		.doit = devlink_nl_cmd_port_del_doit,
 9583		.flags = GENL_ADMIN_PERM,
 9584	},
 9585	{
 9586		.cmd = DEVLINK_CMD_LINECARD_GET,
 9587		.doit = devlink_nl_cmd_linecard_get_doit,
 9588		.dumpit = devlink_nl_cmd_linecard_get_dumpit,
 9589		.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
 9590		/* can be retrieved by unprivileged users */
 9591	},
 9592	{
 9593		.cmd = DEVLINK_CMD_LINECARD_SET,
 9594		.doit = devlink_nl_cmd_linecard_set_doit,
 9595		.flags = GENL_ADMIN_PERM,
 9596		.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
 9597	},
 9598	{
 9599		.cmd = DEVLINK_CMD_SB_GET,
 9600		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9601		.doit = devlink_nl_cmd_sb_get_doit,
 9602		.dumpit = devlink_nl_cmd_sb_get_dumpit,
 9603		/* can be retrieved by unprivileged users */
 9604	},
 9605	{
 9606		.cmd = DEVLINK_CMD_SB_POOL_GET,
 9607		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9608		.doit = devlink_nl_cmd_sb_pool_get_doit,
 9609		.dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
 9610		/* can be retrieved by unprivileged users */
 9611	},
 9612	{
 9613		.cmd = DEVLINK_CMD_SB_POOL_SET,
 9614		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9615		.doit = devlink_nl_cmd_sb_pool_set_doit,
 9616		.flags = GENL_ADMIN_PERM,
 9617	},
 9618	{
 9619		.cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
 9620		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9621		.doit = devlink_nl_cmd_sb_port_pool_get_doit,
 9622		.dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
 9623		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9624		/* can be retrieved by unprivileged users */
 9625	},
 9626	{
 9627		.cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
 9628		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9629		.doit = devlink_nl_cmd_sb_port_pool_set_doit,
 9630		.flags = GENL_ADMIN_PERM,
 9631		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9632	},
 9633	{
 9634		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
 9635		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9636		.doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
 9637		.dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
 9638		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9639		/* can be retrieved by unprivileged users */
 9640	},
 9641	{
 9642		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
 9643		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9644		.doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
 9645		.flags = GENL_ADMIN_PERM,
 9646		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9647	},
 9648	{
 9649		.cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
 9650		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9651		.doit = devlink_nl_cmd_sb_occ_snapshot_doit,
 9652		.flags = GENL_ADMIN_PERM,
 9653	},
 9654	{
 9655		.cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
 9656		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9657		.doit = devlink_nl_cmd_sb_occ_max_clear_doit,
 9658		.flags = GENL_ADMIN_PERM,
 9659	},
 9660	{
 9661		.cmd = DEVLINK_CMD_ESWITCH_GET,
 9662		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9663		.doit = devlink_nl_cmd_eswitch_get_doit,
 9664		.flags = GENL_ADMIN_PERM,
 9665	},
 9666	{
 9667		.cmd = DEVLINK_CMD_ESWITCH_SET,
 9668		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9669		.doit = devlink_nl_cmd_eswitch_set_doit,
 9670		.flags = GENL_ADMIN_PERM,
 9671	},
 9672	{
 9673		.cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
 9674		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9675		.doit = devlink_nl_cmd_dpipe_table_get,
 9676		/* can be retrieved by unprivileged users */
 9677	},
 9678	{
 9679		.cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
 9680		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9681		.doit = devlink_nl_cmd_dpipe_entries_get,
 9682		/* can be retrieved by unprivileged users */
 9683	},
 9684	{
 9685		.cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
 9686		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9687		.doit = devlink_nl_cmd_dpipe_headers_get,
 9688		/* can be retrieved by unprivileged users */
 9689	},
 9690	{
 9691		.cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
 9692		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9693		.doit = devlink_nl_cmd_dpipe_table_counters_set,
 9694		.flags = GENL_ADMIN_PERM,
 9695	},
 9696	{
 9697		.cmd = DEVLINK_CMD_RESOURCE_SET,
 9698		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9699		.doit = devlink_nl_cmd_resource_set,
 9700		.flags = GENL_ADMIN_PERM,
 9701	},
 9702	{
 9703		.cmd = DEVLINK_CMD_RESOURCE_DUMP,
 9704		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9705		.doit = devlink_nl_cmd_resource_dump,
 9706		/* can be retrieved by unprivileged users */
 9707	},
 9708	{
 9709		.cmd = DEVLINK_CMD_RELOAD,
 9710		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9711		.doit = devlink_nl_cmd_reload,
 9712		.flags = GENL_ADMIN_PERM,
 9713	},
 9714	{
 9715		.cmd = DEVLINK_CMD_PARAM_GET,
 9716		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9717		.doit = devlink_nl_cmd_param_get_doit,
 9718		.dumpit = devlink_nl_cmd_param_get_dumpit,
 9719		/* can be retrieved by unprivileged users */
 9720	},
 9721	{
 9722		.cmd = DEVLINK_CMD_PARAM_SET,
 9723		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9724		.doit = devlink_nl_cmd_param_set_doit,
 9725		.flags = GENL_ADMIN_PERM,
 9726	},
 9727	{
 9728		.cmd = DEVLINK_CMD_PORT_PARAM_GET,
 9729		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9730		.doit = devlink_nl_cmd_port_param_get_doit,
 9731		.dumpit = devlink_nl_cmd_port_param_get_dumpit,
 9732		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9733		/* can be retrieved by unprivileged users */
 9734	},
 9735	{
 9736		.cmd = DEVLINK_CMD_PORT_PARAM_SET,
 9737		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9738		.doit = devlink_nl_cmd_port_param_set_doit,
 9739		.flags = GENL_ADMIN_PERM,
 9740		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
 9741	},
 9742	{
 9743		.cmd = DEVLINK_CMD_REGION_GET,
 9744		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9745		.doit = devlink_nl_cmd_region_get_doit,
 9746		.dumpit = devlink_nl_cmd_region_get_dumpit,
 9747		.flags = GENL_ADMIN_PERM,
 9748	},
 9749	{
 9750		.cmd = DEVLINK_CMD_REGION_NEW,
 9751		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9752		.doit = devlink_nl_cmd_region_new,
 9753		.flags = GENL_ADMIN_PERM,
 9754	},
 9755	{
 9756		.cmd = DEVLINK_CMD_REGION_DEL,
 9757		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9758		.doit = devlink_nl_cmd_region_del,
 9759		.flags = GENL_ADMIN_PERM,
 9760	},
 9761	{
 9762		.cmd = DEVLINK_CMD_REGION_READ,
 9763		.validate = GENL_DONT_VALIDATE_STRICT |
 9764			    GENL_DONT_VALIDATE_DUMP_STRICT,
 9765		.dumpit = devlink_nl_cmd_region_read_dumpit,
 9766		.flags = GENL_ADMIN_PERM,
 9767	},
 9768	{
 9769		.cmd = DEVLINK_CMD_INFO_GET,
 9770		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9771		.doit = devlink_nl_cmd_info_get_doit,
 9772		.dumpit = devlink_nl_cmd_info_get_dumpit,
 9773		/* can be retrieved by unprivileged users */
 9774	},
 9775	{
 9776		.cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
 9777		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9778		.doit = devlink_nl_cmd_health_reporter_get_doit,
 9779		.dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
 9780		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 9781		/* can be retrieved by unprivileged users */
 9782	},
 9783	{
 9784		.cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
 9785		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9786		.doit = devlink_nl_cmd_health_reporter_set_doit,
 9787		.flags = GENL_ADMIN_PERM,
 9788		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 9789	},
 9790	{
 9791		.cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
 9792		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9793		.doit = devlink_nl_cmd_health_reporter_recover_doit,
 9794		.flags = GENL_ADMIN_PERM,
 9795		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 9796	},
 9797	{
 9798		.cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
 9799		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9800		.doit = devlink_nl_cmd_health_reporter_diagnose_doit,
 9801		.flags = GENL_ADMIN_PERM,
 9802		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 9803	},
 9804	{
 9805		.cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
 9806		.validate = GENL_DONT_VALIDATE_STRICT |
 9807			    GENL_DONT_VALIDATE_DUMP_STRICT,
 9808		.dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
 9809		.flags = GENL_ADMIN_PERM,
 9810	},
 9811	{
 9812		.cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
 9813		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9814		.doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
 9815		.flags = GENL_ADMIN_PERM,
 9816		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 9817	},
 9818	{
 9819		.cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
 9820		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9821		.doit = devlink_nl_cmd_health_reporter_test_doit,
 9822		.flags = GENL_ADMIN_PERM,
 9823		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 9824	},
 9825	{
 9826		.cmd = DEVLINK_CMD_FLASH_UPDATE,
 9827		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 9828		.doit = devlink_nl_cmd_flash_update,
 9829		.flags = GENL_ADMIN_PERM,
 9830	},
 9831	{
 9832		.cmd = DEVLINK_CMD_TRAP_GET,
 9833		.doit = devlink_nl_cmd_trap_get_doit,
 9834		.dumpit = devlink_nl_cmd_trap_get_dumpit,
 9835		/* can be retrieved by unprivileged users */
 9836	},
 9837	{
 9838		.cmd = DEVLINK_CMD_TRAP_SET,
 9839		.doit = devlink_nl_cmd_trap_set_doit,
 9840		.flags = GENL_ADMIN_PERM,
 9841	},
 9842	{
 9843		.cmd = DEVLINK_CMD_TRAP_GROUP_GET,
 9844		.doit = devlink_nl_cmd_trap_group_get_doit,
 9845		.dumpit = devlink_nl_cmd_trap_group_get_dumpit,
 9846		/* can be retrieved by unprivileged users */
 9847	},
 9848	{
 9849		.cmd = DEVLINK_CMD_TRAP_GROUP_SET,
 9850		.doit = devlink_nl_cmd_trap_group_set_doit,
 9851		.flags = GENL_ADMIN_PERM,
 9852	},
 9853	{
 9854		.cmd = DEVLINK_CMD_TRAP_POLICER_GET,
 9855		.doit = devlink_nl_cmd_trap_policer_get_doit,
 9856		.dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
 9857		/* can be retrieved by unprivileged users */
 9858	},
 9859	{
 9860		.cmd = DEVLINK_CMD_TRAP_POLICER_SET,
 9861		.doit = devlink_nl_cmd_trap_policer_set_doit,
 9862		.flags = GENL_ADMIN_PERM,
 9863	},
 9864	{
 9865		.cmd = DEVLINK_CMD_SELFTESTS_GET,
 9866		.doit = devlink_nl_cmd_selftests_get_doit,
 9867		.dumpit = devlink_nl_cmd_selftests_get_dumpit
 9868		/* can be retrieved by unprivileged users */
 9869	},
 9870	{
 9871		.cmd = DEVLINK_CMD_SELFTESTS_RUN,
 9872		.doit = devlink_nl_cmd_selftests_run,
 9873		.flags = GENL_ADMIN_PERM,
 9874	},
 9875};
 9876
 9877static struct genl_family devlink_nl_family __ro_after_init = {
 9878	.name		= DEVLINK_GENL_NAME,
 9879	.version	= DEVLINK_GENL_VERSION,
 9880	.maxattr	= DEVLINK_ATTR_MAX,
 9881	.policy = devlink_nl_policy,
 9882	.netnsok	= true,
 9883	.parallel_ops	= true,
 9884	.pre_doit	= devlink_nl_pre_doit,
 9885	.post_doit	= devlink_nl_post_doit,
 9886	.module		= THIS_MODULE,
 9887	.small_ops	= devlink_nl_ops,
 9888	.n_small_ops	= ARRAY_SIZE(devlink_nl_ops),
 9889	.resv_start_op	= DEVLINK_CMD_SELFTESTS_RUN + 1,
 9890	.mcgrps		= devlink_nl_mcgrps,
 9891	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
 9892};
 9893
 9894static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
 9895{
 9896	const struct devlink_reload_combination *comb;
 9897	int i;
 9898
 9899	if (!devlink_reload_supported(ops)) {
 9900		if (WARN_ON(ops->reload_actions))
 9901			return false;
 9902		return true;
 9903	}
 9904
 9905	if (WARN_ON(!ops->reload_actions ||
 9906		    ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
 9907		    ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
 9908		return false;
 9909
 9910	if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
 9911		    ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
 9912		return false;
 9913
 9914	for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)  {
 9915		comb = &devlink_reload_invalid_combinations[i];
 9916		if (ops->reload_actions == BIT(comb->action) &&
 9917		    ops->reload_limits == BIT(comb->limit))
 9918			return false;
 9919	}
 9920	return true;
 9921}
 9922
 9923/**
 9924 *	devlink_set_features - Set devlink supported features
 9925 *
 9926 *	@devlink: devlink
 9927 *	@features: devlink support features
 9928 *
 9929 *	This interface allows us to set reload ops separatelly from
 9930 *	the devlink_alloc.
 9931 */
 9932void devlink_set_features(struct devlink *devlink, u64 features)
 9933{
 9934	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
 9935
 9936	WARN_ON(features & DEVLINK_F_RELOAD &&
 9937		!devlink_reload_supported(devlink->ops));
 9938	devlink->features = features;
 9939}
 9940EXPORT_SYMBOL_GPL(devlink_set_features);
 9941
 9942static int devlink_netdevice_event(struct notifier_block *nb,
 9943				   unsigned long event, void *ptr);
 9944
 9945/**
 9946 *	devlink_alloc_ns - Allocate new devlink instance resources
 9947 *	in specific namespace
 9948 *
 9949 *	@ops: ops
 9950 *	@priv_size: size of user private data
 9951 *	@net: net namespace
 9952 *	@dev: parent device
 9953 *
 9954 *	Allocate new devlink instance resources, including devlink index
 9955 *	and name.
 9956 */
 9957struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
 9958				 size_t priv_size, struct net *net,
 9959				 struct device *dev)
 9960{
 9961	struct devlink *devlink;
 9962	static u32 last_id;
 9963	int ret;
 9964
 9965	WARN_ON(!ops || !dev);
 9966	if (!devlink_reload_actions_valid(ops))
 9967		return NULL;
 9968
 9969	devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
 9970	if (!devlink)
 9971		return NULL;
 9972
 9973	ret = xa_alloc_cyclic(&devlinks, &devlink->index, devlink, xa_limit_31b,
 9974			      &last_id, GFP_KERNEL);
 9975	if (ret < 0)
 9976		goto err_xa_alloc;
 9977
 9978	devlink->netdevice_nb.notifier_call = devlink_netdevice_event;
 9979	ret = register_netdevice_notifier(&devlink->netdevice_nb);
 9980	if (ret)
 9981		goto err_register_netdevice_notifier;
 9982
 9983	devlink->dev = dev;
 9984	devlink->ops = ops;
 9985	xa_init_flags(&devlink->ports, XA_FLAGS_ALLOC);
 9986	xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
 9987	write_pnet(&devlink->_net, net);
 9988	INIT_LIST_HEAD(&devlink->rate_list);
 9989	INIT_LIST_HEAD(&devlink->linecard_list);
 9990	INIT_LIST_HEAD(&devlink->sb_list);
 9991	INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
 9992	INIT_LIST_HEAD(&devlink->resource_list);
 9993	INIT_LIST_HEAD(&devlink->param_list);
 9994	INIT_LIST_HEAD(&devlink->region_list);
 9995	INIT_LIST_HEAD(&devlink->reporter_list);
 9996	INIT_LIST_HEAD(&devlink->trap_list);
 9997	INIT_LIST_HEAD(&devlink->trap_group_list);
 9998	INIT_LIST_HEAD(&devlink->trap_policer_list);
 9999	lockdep_register_key(&devlink->lock_key);
10000	mutex_init(&devlink->lock);
10001	lockdep_set_class(&devlink->lock, &devlink->lock_key);
10002	mutex_init(&devlink->reporters_lock);
10003	mutex_init(&devlink->linecards_lock);
10004	refcount_set(&devlink->refcount, 1);
10005	init_completion(&devlink->comp);
10006
10007	return devlink;
10008
10009err_register_netdevice_notifier:
10010	xa_erase(&devlinks, devlink->index);
10011err_xa_alloc:
10012	kfree(devlink);
10013	return NULL;
10014}
10015EXPORT_SYMBOL_GPL(devlink_alloc_ns);
10016
10017static void
10018devlink_trap_policer_notify(struct devlink *devlink,
10019			    const struct devlink_trap_policer_item *policer_item,
10020			    enum devlink_command cmd);
10021static void
10022devlink_trap_group_notify(struct devlink *devlink,
10023			  const struct devlink_trap_group_item *group_item,
10024			  enum devlink_command cmd);
10025static void devlink_trap_notify(struct devlink *devlink,
10026				const struct devlink_trap_item *trap_item,
10027				enum devlink_command cmd);
10028
10029static void devlink_notify_register(struct devlink *devlink)
10030{
10031	struct devlink_trap_policer_item *policer_item;
10032	struct devlink_trap_group_item *group_item;
10033	struct devlink_param_item *param_item;
10034	struct devlink_trap_item *trap_item;
10035	struct devlink_port *devlink_port;
10036	struct devlink_linecard *linecard;
10037	struct devlink_rate *rate_node;
10038	struct devlink_region *region;
10039	unsigned long port_index;
10040
10041	devlink_notify(devlink, DEVLINK_CMD_NEW);
10042	list_for_each_entry(linecard, &devlink->linecard_list, list)
10043		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10044
10045	xa_for_each(&devlink->ports, port_index, devlink_port)
10046		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
10047
10048	list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
10049		devlink_trap_policer_notify(devlink, policer_item,
10050					    DEVLINK_CMD_TRAP_POLICER_NEW);
10051
10052	list_for_each_entry(group_item, &devlink->trap_group_list, list)
10053		devlink_trap_group_notify(devlink, group_item,
10054					  DEVLINK_CMD_TRAP_GROUP_NEW);
10055
10056	list_for_each_entry(trap_item, &devlink->trap_list, list)
10057		devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
10058
10059	list_for_each_entry(rate_node, &devlink->rate_list, list)
10060		devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
10061
10062	list_for_each_entry(region, &devlink->region_list, list)
10063		devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
10064
10065	list_for_each_entry(param_item, &devlink->param_list, list)
10066		devlink_param_notify(devlink, 0, param_item,
10067				     DEVLINK_CMD_PARAM_NEW);
10068}
10069
10070static void devlink_notify_unregister(struct devlink *devlink)
10071{
10072	struct devlink_trap_policer_item *policer_item;
10073	struct devlink_trap_group_item *group_item;
10074	struct devlink_param_item *param_item;
10075	struct devlink_trap_item *trap_item;
10076	struct devlink_port *devlink_port;
10077	struct devlink_rate *rate_node;
10078	struct devlink_region *region;
10079	unsigned long port_index;
10080
10081	list_for_each_entry_reverse(param_item, &devlink->param_list, list)
10082		devlink_param_notify(devlink, 0, param_item,
10083				     DEVLINK_CMD_PARAM_DEL);
10084
10085	list_for_each_entry_reverse(region, &devlink->region_list, list)
10086		devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
10087
10088	list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
10089		devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
10090
10091	list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
10092		devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
10093
10094	list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
10095		devlink_trap_group_notify(devlink, group_item,
10096					  DEVLINK_CMD_TRAP_GROUP_DEL);
10097	list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
10098				    list)
10099		devlink_trap_policer_notify(devlink, policer_item,
10100					    DEVLINK_CMD_TRAP_POLICER_DEL);
10101
10102	xa_for_each(&devlink->ports, port_index, devlink_port)
10103		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
10104	devlink_notify(devlink, DEVLINK_CMD_DEL);
10105}
 
10106
10107/**
10108 *	devlink_register - Register devlink instance
10109 *
10110 *	@devlink: devlink
10111 */
10112void devlink_register(struct devlink *devlink)
10113{
10114	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
10115	/* Make sure that we are in .probe() routine */
10116
10117	xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
10118	devlink_notify_register(devlink);
 
10119}
10120EXPORT_SYMBOL_GPL(devlink_register);
10121
10122/**
10123 *	devlink_unregister - Unregister devlink instance
10124 *
10125 *	@devlink: devlink
10126 */
10127void devlink_unregister(struct devlink *devlink)
10128{
10129	ASSERT_DEVLINK_REGISTERED(devlink);
10130	/* Make sure that we are in .remove() routine */
10131
10132	xa_set_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING);
10133	devlink_put(devlink);
10134	wait_for_completion(&devlink->comp);
10135
10136	devlink_notify_unregister(devlink);
10137	xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
10138	xa_clear_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING);
10139}
10140EXPORT_SYMBOL_GPL(devlink_unregister);
10141
10142/**
10143 *	devlink_free - Free devlink instance resources
10144 *
10145 *	@devlink: devlink
10146 */
10147void devlink_free(struct devlink *devlink)
10148{
10149	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
10150
10151	mutex_destroy(&devlink->linecards_lock);
10152	mutex_destroy(&devlink->reporters_lock);
10153	mutex_destroy(&devlink->lock);
10154	lockdep_unregister_key(&devlink->lock_key);
10155	WARN_ON(!list_empty(&devlink->trap_policer_list));
10156	WARN_ON(!list_empty(&devlink->trap_group_list));
10157	WARN_ON(!list_empty(&devlink->trap_list));
10158	WARN_ON(!list_empty(&devlink->reporter_list));
10159	WARN_ON(!list_empty(&devlink->region_list));
10160	WARN_ON(!list_empty(&devlink->param_list));
10161	WARN_ON(!list_empty(&devlink->resource_list));
10162	WARN_ON(!list_empty(&devlink->dpipe_table_list));
10163	WARN_ON(!list_empty(&devlink->sb_list));
10164	WARN_ON(!list_empty(&devlink->rate_list));
10165	WARN_ON(!list_empty(&devlink->linecard_list));
10166	WARN_ON(!xa_empty(&devlink->ports));
10167
10168	xa_destroy(&devlink->snapshot_ids);
10169	xa_destroy(&devlink->ports);
10170
10171	WARN_ON_ONCE(unregister_netdevice_notifier(&devlink->netdevice_nb));
10172
10173	xa_erase(&devlinks, devlink->index);
10174
10175	kfree(devlink);
10176}
10177EXPORT_SYMBOL_GPL(devlink_free);
10178
10179static void devlink_port_type_warn(struct work_struct *work)
10180{
10181	WARN(true, "Type was not set for devlink port.");
10182}
10183
10184static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
10185{
10186	/* Ignore CPU and DSA flavours. */
10187	return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
10188	       devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
10189	       devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
10190}
10191
10192#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
10193
10194static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
10195{
10196	if (!devlink_port_type_should_warn(devlink_port))
10197		return;
10198	/* Schedule a work to WARN in case driver does not set port
10199	 * type within timeout.
10200	 */
10201	schedule_delayed_work(&devlink_port->type_warn_dw,
10202			      DEVLINK_PORT_TYPE_WARN_TIMEOUT);
10203}
10204
10205static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
10206{
10207	if (!devlink_port_type_should_warn(devlink_port))
10208		return;
10209	cancel_delayed_work_sync(&devlink_port->type_warn_dw);
10210}
10211
10212/**
10213 * devlink_port_init() - Init devlink port
10214 *
10215 * @devlink: devlink
10216 * @devlink_port: devlink port
10217 *
10218 * Initialize essencial stuff that is needed for functions
10219 * that may be called before devlink port registration.
10220 * Call to this function is optional and not needed
10221 * in case the driver does not use such functions.
10222 */
10223void devlink_port_init(struct devlink *devlink,
10224		       struct devlink_port *devlink_port)
10225{
10226	if (devlink_port->initialized)
10227		return;
10228	devlink_port->devlink = devlink;
10229	INIT_LIST_HEAD(&devlink_port->region_list);
10230	devlink_port->initialized = true;
10231}
10232EXPORT_SYMBOL_GPL(devlink_port_init);
10233
10234/**
10235 * devlink_port_fini() - Deinitialize devlink port
10236 *
10237 * @devlink_port: devlink port
10238 *
10239 * Deinitialize essencial stuff that is in use for functions
10240 * that may be called after devlink port unregistration.
10241 * Call to this function is optional and not needed
10242 * in case the driver does not use such functions.
10243 */
10244void devlink_port_fini(struct devlink_port *devlink_port)
10245{
10246	WARN_ON(!list_empty(&devlink_port->region_list));
10247}
10248EXPORT_SYMBOL_GPL(devlink_port_fini);
10249
10250/**
10251 * devl_port_register() - Register devlink port
10252 *
10253 * @devlink: devlink
10254 * @devlink_port: devlink port
10255 * @port_index: driver-specific numerical identifier of the port
10256 *
10257 * Register devlink port with provided port index. User can use
10258 * any indexing, even hw-related one. devlink_port structure
10259 * is convenient to be embedded inside user driver private structure.
10260 * Note that the caller should take care of zeroing the devlink_port
10261 * structure.
10262 */
10263int devl_port_register(struct devlink *devlink,
10264		       struct devlink_port *devlink_port,
10265		       unsigned int port_index)
10266{
10267	int err;
10268
10269	devl_assert_locked(devlink);
10270
10271	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10272
10273	devlink_port_init(devlink, devlink_port);
10274	devlink_port->registered = true;
10275	devlink_port->index = port_index;
10276	spin_lock_init(&devlink_port->type_lock);
10277	INIT_LIST_HEAD(&devlink_port->reporter_list);
10278	mutex_init(&devlink_port->reporters_lock);
10279	err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
10280	if (err) {
10281		mutex_destroy(&devlink_port->reporters_lock);
10282		return err;
10283	}
10284
10285	INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
10286	devlink_port_type_warn_schedule(devlink_port);
10287	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
10288	return 0;
10289}
10290EXPORT_SYMBOL_GPL(devl_port_register);
10291
10292/**
10293 *	devlink_port_register - Register devlink port
10294 *
10295 *	@devlink: devlink
10296 *	@devlink_port: devlink port
10297 *	@port_index: driver-specific numerical identifier of the port
10298 *
10299 *	Register devlink port with provided port index. User can use
10300 *	any indexing, even hw-related one. devlink_port structure
10301 *	is convenient to be embedded inside user driver private structure.
10302 *	Note that the caller should take care of zeroing the devlink_port
10303 *	structure.
10304 *
10305 *	Context: Takes and release devlink->lock <mutex>.
10306 */
10307int devlink_port_register(struct devlink *devlink,
10308			  struct devlink_port *devlink_port,
10309			  unsigned int port_index)
10310{
10311	int err;
10312
10313	devl_lock(devlink);
10314	err = devl_port_register(devlink, devlink_port, port_index);
10315	devl_unlock(devlink);
10316	return err;
 
 
 
 
 
 
 
10317}
10318EXPORT_SYMBOL_GPL(devlink_port_register);
10319
10320/**
10321 * devl_port_unregister() - Unregister devlink port
10322 *
10323 * @devlink_port: devlink port
10324 */
10325void devl_port_unregister(struct devlink_port *devlink_port)
10326{
10327	lockdep_assert_held(&devlink_port->devlink->lock);
10328	WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
10329
10330	devlink_port_type_warn_cancel(devlink_port);
10331	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
10332	xa_erase(&devlink_port->devlink->ports, devlink_port->index);
10333	WARN_ON(!list_empty(&devlink_port->reporter_list));
10334	mutex_destroy(&devlink_port->reporters_lock);
10335	devlink_port->registered = false;
10336}
10337EXPORT_SYMBOL_GPL(devl_port_unregister);
10338
10339/**
10340 *	devlink_port_unregister - Unregister devlink port
10341 *
10342 *	@devlink_port: devlink port
10343 *
10344 *	Context: Takes and release devlink->lock <mutex>.
10345 */
10346void devlink_port_unregister(struct devlink_port *devlink_port)
10347{
10348	struct devlink *devlink = devlink_port->devlink;
10349
10350	devl_lock(devlink);
10351	devl_port_unregister(devlink_port);
10352	devl_unlock(devlink);
10353}
10354EXPORT_SYMBOL_GPL(devlink_port_unregister);
10355
10356static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
10357					    struct net_device *netdev)
10358{
10359	const struct net_device_ops *ops = netdev->netdev_ops;
10360
10361	/* If driver registers devlink port, it should set devlink port
10362	 * attributes accordingly so the compat functions are called
10363	 * and the original ops are not used.
10364	 */
10365	if (ops->ndo_get_phys_port_name) {
10366		/* Some drivers use the same set of ndos for netdevs
10367		 * that have devlink_port registered and also for
10368		 * those who don't. Make sure that ndo_get_phys_port_name
10369		 * returns -EOPNOTSUPP here in case it is defined.
10370		 * Warn if not.
10371		 */
10372		char name[IFNAMSIZ];
10373		int err;
10374
10375		err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
10376		WARN_ON(err != -EOPNOTSUPP);
10377	}
10378	if (ops->ndo_get_port_parent_id) {
10379		/* Some drivers use the same set of ndos for netdevs
10380		 * that have devlink_port registered and also for
10381		 * those who don't. Make sure that ndo_get_port_parent_id
10382		 * returns -EOPNOTSUPP here in case it is defined.
10383		 * Warn if not.
10384		 */
10385		struct netdev_phys_item_id ppid;
10386		int err;
10387
10388		err = ops->ndo_get_port_parent_id(netdev, &ppid);
10389		WARN_ON(err != -EOPNOTSUPP);
10390	}
10391}
10392
10393static void __devlink_port_type_set(struct devlink_port *devlink_port,
10394				    enum devlink_port_type type,
10395				    void *type_dev)
10396{
10397	struct net_device *netdev = type_dev;
10398
10399	ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
10400
10401	if (type == DEVLINK_PORT_TYPE_NOTSET) {
10402		devlink_port_type_warn_schedule(devlink_port);
10403	} else {
10404		devlink_port_type_warn_cancel(devlink_port);
10405		if (type == DEVLINK_PORT_TYPE_ETH && netdev)
10406			devlink_port_type_netdev_checks(devlink_port, netdev);
10407	}
10408
10409	spin_lock_bh(&devlink_port->type_lock);
10410	devlink_port->type = type;
10411	switch (type) {
10412	case DEVLINK_PORT_TYPE_ETH:
10413		devlink_port->type_eth.netdev = netdev;
10414		if (netdev) {
10415			ASSERT_RTNL();
10416			devlink_port->type_eth.ifindex = netdev->ifindex;
10417			BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
10418				     sizeof(netdev->name));
10419			strcpy(devlink_port->type_eth.ifname, netdev->name);
10420		}
10421		break;
10422	case DEVLINK_PORT_TYPE_IB:
10423		devlink_port->type_ib.ibdev = type_dev;
10424		break;
10425	default:
10426		break;
10427	}
10428	spin_unlock_bh(&devlink_port->type_lock);
10429	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
10430}
10431
10432/**
10433 *	devlink_port_type_eth_set - Set port type to Ethernet
10434 *
10435 *	@devlink_port: devlink port
10436 *
10437 *	If driver is calling this, most likely it is doing something wrong.
10438 */
10439void devlink_port_type_eth_set(struct devlink_port *devlink_port)
 
10440{
10441	dev_warn(devlink_port->devlink->dev,
10442		 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
10443		 devlink_port->index);
10444	__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
10445}
10446EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
10447
10448/**
10449 *	devlink_port_type_ib_set - Set port type to InfiniBand
10450 *
10451 *	@devlink_port: devlink port
10452 *	@ibdev: related IB device
10453 */
10454void devlink_port_type_ib_set(struct devlink_port *devlink_port,
10455			      struct ib_device *ibdev)
10456{
10457	__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
 
10458}
10459EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
10460
10461/**
10462 *	devlink_port_type_clear - Clear port type
10463 *
10464 *	@devlink_port: devlink port
10465 *
10466 *	If driver is calling this for clearing Ethernet type, most likely
10467 *	it is doing something wrong.
10468 */
10469void devlink_port_type_clear(struct devlink_port *devlink_port)
10470{
10471	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
10472		dev_warn(devlink_port->devlink->dev,
10473			 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
10474			 devlink_port->index);
10475	__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
10476}
10477EXPORT_SYMBOL_GPL(devlink_port_type_clear);
10478
10479static int devlink_netdevice_event(struct notifier_block *nb,
10480				   unsigned long event, void *ptr)
10481{
10482	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
10483	struct devlink_port *devlink_port = netdev->devlink_port;
10484	struct devlink *devlink;
10485
10486	devlink = container_of(nb, struct devlink, netdevice_nb);
10487
10488	if (!devlink_port || devlink_port->devlink != devlink)
10489		return NOTIFY_OK;
10490
10491	switch (event) {
10492	case NETDEV_POST_INIT:
10493		/* Set the type but not netdev pointer. It is going to be set
10494		 * later on by NETDEV_REGISTER event. Happens once during
10495		 * netdevice register
10496		 */
10497		__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
10498					NULL);
10499		break;
10500	case NETDEV_REGISTER:
10501	case NETDEV_CHANGENAME:
10502		if (devlink_net(devlink) != dev_net(netdev))
10503			return NOTIFY_OK;
10504		/* Set the netdev on top of previously set type. Note this
10505		 * event happens also during net namespace change so here
10506		 * we take into account netdev pointer appearing in this
10507		 * namespace.
10508		 */
10509		__devlink_port_type_set(devlink_port, devlink_port->type,
10510					netdev);
10511		break;
10512	case NETDEV_UNREGISTER:
10513		if (devlink_net(devlink) != dev_net(netdev))
10514			return NOTIFY_OK;
10515		/* Clear netdev pointer, but not the type. This event happens
10516		 * also during net namespace change so we need to clear
10517		 * pointer to netdev that is going to another net namespace.
10518		 */
10519		__devlink_port_type_set(devlink_port, devlink_port->type,
10520					NULL);
10521		break;
10522	case NETDEV_PRE_UNINIT:
10523		/* Clear the type and the netdev pointer. Happens one during
10524		 * netdevice unregister.
10525		 */
10526		__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
10527					NULL);
10528		break;
10529	}
10530
10531	return NOTIFY_OK;
10532}
10533
10534static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
10535				    enum devlink_port_flavour flavour)
10536{
10537	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10538
10539	devlink_port->attrs_set = true;
10540	attrs->flavour = flavour;
10541	if (attrs->switch_id.id_len) {
10542		devlink_port->switch_port = true;
10543		if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
10544			attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
10545	} else {
10546		devlink_port->switch_port = false;
10547	}
10548	return 0;
10549}
10550
10551/**
10552 *	devlink_port_attrs_set - Set port attributes
10553 *
10554 *	@devlink_port: devlink port
10555 *	@attrs: devlink port attrs
10556 */
10557void devlink_port_attrs_set(struct devlink_port *devlink_port,
10558			    struct devlink_port_attrs *attrs)
10559{
10560	int ret;
10561
10562	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10563
10564	devlink_port->attrs = *attrs;
10565	ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
10566	if (ret)
10567		return;
10568	WARN_ON(attrs->splittable && attrs->split);
10569}
10570EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
10571
10572/**
10573 *	devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
10574 *
10575 *	@devlink_port: devlink port
10576 *	@controller: associated controller number for the devlink port instance
10577 *	@pf: associated PF for the devlink port instance
10578 *	@external: indicates if the port is for an external controller
10579 */
10580void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
10581				   u16 pf, bool external)
10582{
10583	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10584	int ret;
10585
10586	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10587
10588	ret = __devlink_port_attrs_set(devlink_port,
10589				       DEVLINK_PORT_FLAVOUR_PCI_PF);
10590	if (ret)
10591		return;
10592	attrs->pci_pf.controller = controller;
10593	attrs->pci_pf.pf = pf;
10594	attrs->pci_pf.external = external;
10595}
10596EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
10597
10598/**
10599 *	devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
10600 *
10601 *	@devlink_port: devlink port
10602 *	@controller: associated controller number for the devlink port instance
10603 *	@pf: associated PF for the devlink port instance
10604 *	@vf: associated VF of a PF for the devlink port instance
10605 *	@external: indicates if the port is for an external controller
10606 */
10607void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
10608				   u16 pf, u16 vf, bool external)
10609{
10610	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10611	int ret;
10612
10613	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10614
10615	ret = __devlink_port_attrs_set(devlink_port,
10616				       DEVLINK_PORT_FLAVOUR_PCI_VF);
10617	if (ret)
10618		return;
10619	attrs->pci_vf.controller = controller;
10620	attrs->pci_vf.pf = pf;
10621	attrs->pci_vf.vf = vf;
10622	attrs->pci_vf.external = external;
10623}
10624EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
10625
10626/**
10627 *	devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
10628 *
10629 *	@devlink_port: devlink port
10630 *	@controller: associated controller number for the devlink port instance
10631 *	@pf: associated PF for the devlink port instance
10632 *	@sf: associated SF of a PF for the devlink port instance
10633 *	@external: indicates if the port is for an external controller
10634 */
10635void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
10636				   u16 pf, u32 sf, bool external)
10637{
10638	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10639	int ret;
10640
10641	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10642
10643	ret = __devlink_port_attrs_set(devlink_port,
10644				       DEVLINK_PORT_FLAVOUR_PCI_SF);
10645	if (ret)
10646		return;
10647	attrs->pci_sf.controller = controller;
10648	attrs->pci_sf.pf = pf;
10649	attrs->pci_sf.sf = sf;
10650	attrs->pci_sf.external = external;
10651}
10652EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
10653
10654/**
10655 * devl_rate_node_create - create devlink rate node
10656 * @devlink: devlink instance
10657 * @priv: driver private data
10658 * @node_name: name of the resulting node
10659 * @parent: parent devlink_rate struct
10660 *
10661 * Create devlink rate object of type node
10662 */
10663struct devlink_rate *
10664devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
10665		      struct devlink_rate *parent)
10666{
10667	struct devlink_rate *rate_node;
10668
10669	rate_node = devlink_rate_node_get_by_name(devlink, node_name);
10670	if (!IS_ERR(rate_node))
10671		return ERR_PTR(-EEXIST);
10672
10673	rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
10674	if (!rate_node)
10675		return ERR_PTR(-ENOMEM);
10676
10677	if (parent) {
10678		rate_node->parent = parent;
10679		refcount_inc(&rate_node->parent->refcnt);
10680	}
10681
10682	rate_node->type = DEVLINK_RATE_TYPE_NODE;
10683	rate_node->devlink = devlink;
10684	rate_node->priv = priv;
10685
10686	rate_node->name = kstrdup(node_name, GFP_KERNEL);
10687	if (!rate_node->name) {
10688		kfree(rate_node);
10689		return ERR_PTR(-ENOMEM);
10690	}
10691
10692	refcount_set(&rate_node->refcnt, 1);
10693	list_add(&rate_node->list, &devlink->rate_list);
10694	devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
10695	return rate_node;
10696}
10697EXPORT_SYMBOL_GPL(devl_rate_node_create);
10698
10699/**
10700 * devl_rate_leaf_create - create devlink rate leaf
10701 * @devlink_port: devlink port object to create rate object on
10702 * @priv: driver private data
10703 * @parent: parent devlink_rate struct
10704 *
10705 * Create devlink rate object of type leaf on provided @devlink_port.
10706 */
10707int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
10708			  struct devlink_rate *parent)
10709{
10710	struct devlink *devlink = devlink_port->devlink;
10711	struct devlink_rate *devlink_rate;
10712
10713	devl_assert_locked(devlink_port->devlink);
10714
10715	if (WARN_ON(devlink_port->devlink_rate))
10716		return -EBUSY;
10717
10718	devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
10719	if (!devlink_rate)
10720		return -ENOMEM;
10721
10722	if (parent) {
10723		devlink_rate->parent = parent;
10724		refcount_inc(&devlink_rate->parent->refcnt);
10725	}
10726
10727	devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
10728	devlink_rate->devlink = devlink;
10729	devlink_rate->devlink_port = devlink_port;
10730	devlink_rate->priv = priv;
10731	list_add_tail(&devlink_rate->list, &devlink->rate_list);
10732	devlink_port->devlink_rate = devlink_rate;
10733	devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
10734
10735	return 0;
10736}
10737EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
10738
10739/**
10740 * devl_rate_leaf_destroy - destroy devlink rate leaf
10741 *
10742 * @devlink_port: devlink port linked to the rate object
10743 *
10744 * Destroy the devlink rate object of type leaf on provided @devlink_port.
10745 */
10746void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
10747{
10748	struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
10749
10750	devl_assert_locked(devlink_port->devlink);
10751	if (!devlink_rate)
10752		return;
10753
10754	devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
10755	if (devlink_rate->parent)
10756		refcount_dec(&devlink_rate->parent->refcnt);
10757	list_del(&devlink_rate->list);
10758	devlink_port->devlink_rate = NULL;
10759	kfree(devlink_rate);
10760}
10761EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
10762
10763/**
10764 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
10765 * @devlink: devlink instance
10766 *
10767 * Unset parent for all rate objects and destroy all rate nodes
10768 * on specified device.
10769 */
10770void devl_rate_nodes_destroy(struct devlink *devlink)
10771{
10772	static struct devlink_rate *devlink_rate, *tmp;
10773	const struct devlink_ops *ops = devlink->ops;
10774
10775	devl_assert_locked(devlink);
10776
10777	list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
10778		if (!devlink_rate->parent)
10779			continue;
10780
10781		refcount_dec(&devlink_rate->parent->refcnt);
10782		if (devlink_rate_is_leaf(devlink_rate))
10783			ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
10784						  NULL, NULL);
10785		else if (devlink_rate_is_node(devlink_rate))
10786			ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
10787						  NULL, NULL);
10788	}
10789	list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10790		if (devlink_rate_is_node(devlink_rate)) {
10791			ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10792			list_del(&devlink_rate->list);
10793			kfree(devlink_rate->name);
10794			kfree(devlink_rate);
10795		}
10796	}
10797}
10798EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10799
10800/**
10801 *	devlink_port_linecard_set - Link port with a linecard
10802 *
10803 *	@devlink_port: devlink port
10804 *	@linecard: devlink linecard
10805 */
10806void devlink_port_linecard_set(struct devlink_port *devlink_port,
10807			       struct devlink_linecard *linecard)
10808{
10809	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10810
10811	devlink_port->linecard = linecard;
10812}
10813EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10814
10815static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10816					     char *name, size_t len)
10817{
10818	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10819	int n = 0;
10820
10821	if (!devlink_port->attrs_set)
10822		return -EOPNOTSUPP;
10823
10824	switch (attrs->flavour) {
10825	case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10826		if (devlink_port->linecard)
10827			n = snprintf(name, len, "l%u",
10828				     devlink_port->linecard->index);
10829		if (n < len)
10830			n += snprintf(name + n, len - n, "p%u",
10831				      attrs->phys.port_number);
10832		if (n < len && attrs->split)
10833			n += snprintf(name + n, len - n, "s%u",
10834				      attrs->phys.split_subport_number);
10835		break;
10836	case DEVLINK_PORT_FLAVOUR_CPU:
10837	case DEVLINK_PORT_FLAVOUR_DSA:
10838	case DEVLINK_PORT_FLAVOUR_UNUSED:
10839		/* As CPU and DSA ports do not have a netdevice associated
10840		 * case should not ever happen.
10841		 */
10842		WARN_ON(1);
10843		return -EINVAL;
10844	case DEVLINK_PORT_FLAVOUR_PCI_PF:
10845		if (attrs->pci_pf.external) {
10846			n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10847			if (n >= len)
10848				return -EINVAL;
10849			len -= n;
10850			name += n;
10851		}
10852		n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10853		break;
10854	case DEVLINK_PORT_FLAVOUR_PCI_VF:
10855		if (attrs->pci_vf.external) {
10856			n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10857			if (n >= len)
10858				return -EINVAL;
10859			len -= n;
10860			name += n;
10861		}
10862		n = snprintf(name, len, "pf%uvf%u",
10863			     attrs->pci_vf.pf, attrs->pci_vf.vf);
10864		break;
10865	case DEVLINK_PORT_FLAVOUR_PCI_SF:
10866		if (attrs->pci_sf.external) {
10867			n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10868			if (n >= len)
10869				return -EINVAL;
10870			len -= n;
10871			name += n;
10872		}
10873		n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10874			     attrs->pci_sf.sf);
10875		break;
10876	case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10877		return -EOPNOTSUPP;
10878	}
10879
10880	if (n >= len)
10881		return -EINVAL;
10882
10883	return 0;
10884}
10885
10886static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10887{
10888	struct devlink_linecard_type *linecard_type;
10889	unsigned int count;
10890	int i;
10891
10892	count = linecard->ops->types_count(linecard, linecard->priv);
10893	linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10894					GFP_KERNEL);
10895	if (!linecard->types)
10896		return -ENOMEM;
10897	linecard->types_count = count;
10898
10899	for (i = 0; i < count; i++) {
10900		linecard_type = &linecard->types[i];
10901		linecard->ops->types_get(linecard, linecard->priv, i,
10902					 &linecard_type->type,
10903					 &linecard_type->priv);
10904	}
10905	return 0;
10906}
10907
10908static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10909{
10910	kfree(linecard->types);
10911}
10912
10913/**
10914 *	devlink_linecard_create - Create devlink linecard
10915 *
10916 *	@devlink: devlink
10917 *	@linecard_index: driver-specific numerical identifier of the linecard
10918 *	@ops: linecards ops
10919 *	@priv: user priv pointer
10920 *
10921 *	Create devlink linecard instance with provided linecard index.
10922 *	Caller can use any indexing, even hw-related one.
10923 *
10924 *	Return: Line card structure or an ERR_PTR() encoded error code.
10925 */
10926struct devlink_linecard *
10927devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10928			const struct devlink_linecard_ops *ops, void *priv)
10929{
10930	struct devlink_linecard *linecard;
10931	int err;
10932
10933	if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10934		    !ops->types_count || !ops->types_get))
10935		return ERR_PTR(-EINVAL);
10936
10937	mutex_lock(&devlink->linecards_lock);
10938	if (devlink_linecard_index_exists(devlink, linecard_index)) {
10939		mutex_unlock(&devlink->linecards_lock);
10940		return ERR_PTR(-EEXIST);
10941	}
10942
10943	linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10944	if (!linecard) {
10945		mutex_unlock(&devlink->linecards_lock);
10946		return ERR_PTR(-ENOMEM);
10947	}
10948
10949	linecard->devlink = devlink;
10950	linecard->index = linecard_index;
10951	linecard->ops = ops;
10952	linecard->priv = priv;
10953	linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10954	mutex_init(&linecard->state_lock);
10955
10956	err = devlink_linecard_types_init(linecard);
10957	if (err) {
10958		mutex_destroy(&linecard->state_lock);
10959		kfree(linecard);
10960		mutex_unlock(&devlink->linecards_lock);
10961		return ERR_PTR(err);
10962	}
10963
10964	list_add_tail(&linecard->list, &devlink->linecard_list);
10965	refcount_set(&linecard->refcount, 1);
10966	mutex_unlock(&devlink->linecards_lock);
10967	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10968	return linecard;
10969}
10970EXPORT_SYMBOL_GPL(devlink_linecard_create);
10971
10972/**
10973 *	devlink_linecard_destroy - Destroy devlink linecard
10974 *
10975 *	@linecard: devlink linecard
10976 */
10977void devlink_linecard_destroy(struct devlink_linecard *linecard)
10978{
10979	struct devlink *devlink = linecard->devlink;
10980
10981	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10982	mutex_lock(&devlink->linecards_lock);
10983	list_del(&linecard->list);
10984	devlink_linecard_types_fini(linecard);
10985	mutex_unlock(&devlink->linecards_lock);
10986	devlink_linecard_put(linecard);
10987}
10988EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
10989
10990/**
10991 *	devlink_linecard_provision_set - Set provisioning on linecard
10992 *
10993 *	@linecard: devlink linecard
10994 *	@type: linecard type
10995 *
10996 *	This is either called directly from the provision() op call or
10997 *	as a result of the provision() op call asynchronously.
10998 */
10999void devlink_linecard_provision_set(struct devlink_linecard *linecard,
11000				    const char *type)
11001{
11002	mutex_lock(&linecard->state_lock);
11003	WARN_ON(linecard->type && strcmp(linecard->type, type));
11004	linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
11005	linecard->type = type;
11006	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
11007	mutex_unlock(&linecard->state_lock);
11008}
11009EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
11010
11011/**
11012 *	devlink_linecard_provision_clear - Clear provisioning on linecard
11013 *
11014 *	@linecard: devlink linecard
11015 *
11016 *	This is either called directly from the unprovision() op call or
11017 *	as a result of the unprovision() op call asynchronously.
11018 */
11019void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
11020{
11021	mutex_lock(&linecard->state_lock);
11022	WARN_ON(linecard->nested_devlink);
11023	linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
11024	linecard->type = NULL;
11025	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
11026	mutex_unlock(&linecard->state_lock);
11027}
11028EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
11029
11030/**
11031 *	devlink_linecard_provision_fail - Fail provisioning on linecard
11032 *
11033 *	@linecard: devlink linecard
11034 *
11035 *	This is either called directly from the provision() op call or
11036 *	as a result of the provision() op call asynchronously.
11037 */
11038void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
11039{
11040	mutex_lock(&linecard->state_lock);
11041	WARN_ON(linecard->nested_devlink);
11042	linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
11043	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
11044	mutex_unlock(&linecard->state_lock);
11045}
11046EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
11047
11048/**
11049 *	devlink_linecard_activate - Set linecard active
11050 *
11051 *	@linecard: devlink linecard
11052 */
11053void devlink_linecard_activate(struct devlink_linecard *linecard)
11054{
11055	mutex_lock(&linecard->state_lock);
11056	WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
11057	linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
11058	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
11059	mutex_unlock(&linecard->state_lock);
11060}
11061EXPORT_SYMBOL_GPL(devlink_linecard_activate);
11062
11063/**
11064 *	devlink_linecard_deactivate - Set linecard inactive
11065 *
11066 *	@linecard: devlink linecard
11067 */
11068void devlink_linecard_deactivate(struct devlink_linecard *linecard)
11069{
11070	mutex_lock(&linecard->state_lock);
11071	switch (linecard->state) {
11072	case DEVLINK_LINECARD_STATE_ACTIVE:
11073		linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
11074		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
11075		break;
11076	case DEVLINK_LINECARD_STATE_UNPROVISIONING:
11077		/* Line card is being deactivated as part
11078		 * of unprovisioning flow.
11079		 */
11080		break;
11081	default:
11082		WARN_ON(1);
11083		break;
11084	}
11085	mutex_unlock(&linecard->state_lock);
11086}
11087EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
11088
11089/**
11090 *	devlink_linecard_nested_dl_set - Attach/detach nested devlink
11091 *					 instance to linecard.
11092 *
11093 *	@linecard: devlink linecard
11094 *	@nested_devlink: devlink instance to attach or NULL to detach
11095 */
11096void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
11097				    struct devlink *nested_devlink)
11098{
11099	mutex_lock(&linecard->state_lock);
11100	linecard->nested_devlink = nested_devlink;
11101	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
11102	mutex_unlock(&linecard->state_lock);
11103}
11104EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
11105
11106int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
11107		     u32 size, u16 ingress_pools_count,
11108		     u16 egress_pools_count, u16 ingress_tc_count,
11109		     u16 egress_tc_count)
11110{
11111	struct devlink_sb *devlink_sb;
11112
11113	lockdep_assert_held(&devlink->lock);
11114
11115	if (devlink_sb_index_exists(devlink, sb_index))
11116		return -EEXIST;
11117
11118	devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
11119	if (!devlink_sb)
11120		return -ENOMEM;
11121	devlink_sb->index = sb_index;
11122	devlink_sb->size = size;
11123	devlink_sb->ingress_pools_count = ingress_pools_count;
11124	devlink_sb->egress_pools_count = egress_pools_count;
11125	devlink_sb->ingress_tc_count = ingress_tc_count;
11126	devlink_sb->egress_tc_count = egress_tc_count;
11127	list_add_tail(&devlink_sb->list, &devlink->sb_list);
11128	return 0;
11129}
11130EXPORT_SYMBOL_GPL(devl_sb_register);
11131
11132int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
11133			u32 size, u16 ingress_pools_count,
11134			u16 egress_pools_count, u16 ingress_tc_count,
11135			u16 egress_tc_count)
11136{
11137	int err;
11138
11139	devl_lock(devlink);
11140	err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
11141			       egress_pools_count, ingress_tc_count,
11142			       egress_tc_count);
11143	devl_unlock(devlink);
11144	return err;
11145}
11146EXPORT_SYMBOL_GPL(devlink_sb_register);
11147
11148void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
11149{
11150	struct devlink_sb *devlink_sb;
11151
11152	lockdep_assert_held(&devlink->lock);
11153
11154	devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
11155	WARN_ON(!devlink_sb);
11156	list_del(&devlink_sb->list);
11157	kfree(devlink_sb);
11158}
11159EXPORT_SYMBOL_GPL(devl_sb_unregister);
11160
11161void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
11162{
11163	devl_lock(devlink);
11164	devl_sb_unregister(devlink, sb_index);
11165	devl_unlock(devlink);
11166}
11167EXPORT_SYMBOL_GPL(devlink_sb_unregister);
11168
11169/**
11170 * devl_dpipe_headers_register - register dpipe headers
11171 *
11172 * @devlink: devlink
11173 * @dpipe_headers: dpipe header array
11174 *
11175 * Register the headers supported by hardware.
11176 */
11177void devl_dpipe_headers_register(struct devlink *devlink,
11178				 struct devlink_dpipe_headers *dpipe_headers)
11179{
11180	lockdep_assert_held(&devlink->lock);
11181
11182	devlink->dpipe_headers = dpipe_headers;
11183}
11184EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
11185
11186/**
11187 * devl_dpipe_headers_unregister - unregister dpipe headers
11188 *
11189 * @devlink: devlink
11190 *
11191 * Unregister the headers supported by hardware.
11192 */
11193void devl_dpipe_headers_unregister(struct devlink *devlink)
11194{
11195	lockdep_assert_held(&devlink->lock);
11196
11197	devlink->dpipe_headers = NULL;
11198}
11199EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
11200
11201/**
11202 *	devlink_dpipe_table_counter_enabled - check if counter allocation
11203 *					      required
11204 *	@devlink: devlink
11205 *	@table_name: tables name
11206 *
11207 *	Used by driver to check if counter allocation is required.
11208 *	After counter allocation is turned on the table entries
11209 *	are updated to include counter statistics.
11210 *
11211 *	After that point on the driver must respect the counter
11212 *	state so that each entry added to the table is added
11213 *	with a counter.
11214 */
11215bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
11216					 const char *table_name)
11217{
11218	struct devlink_dpipe_table *table;
11219	bool enabled;
11220
11221	rcu_read_lock();
11222	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
11223					 table_name, devlink);
11224	enabled = false;
11225	if (table)
11226		enabled = table->counters_enabled;
11227	rcu_read_unlock();
11228	return enabled;
11229}
11230EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
11231
11232/**
11233 * devl_dpipe_table_register - register dpipe table
11234 *
11235 * @devlink: devlink
11236 * @table_name: table name
11237 * @table_ops: table ops
11238 * @priv: priv
11239 * @counter_control_extern: external control for counters
11240 */
11241int devl_dpipe_table_register(struct devlink *devlink,
11242			      const char *table_name,
11243			      struct devlink_dpipe_table_ops *table_ops,
11244			      void *priv, bool counter_control_extern)
11245{
11246	struct devlink_dpipe_table *table;
11247
11248	lockdep_assert_held(&devlink->lock);
11249
11250	if (WARN_ON(!table_ops->size_get))
11251		return -EINVAL;
11252
11253	if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
11254				     devlink))
11255		return -EEXIST;
11256
11257	table = kzalloc(sizeof(*table), GFP_KERNEL);
11258	if (!table)
11259		return -ENOMEM;
11260
11261	table->name = table_name;
11262	table->table_ops = table_ops;
11263	table->priv = priv;
11264	table->counter_control_extern = counter_control_extern;
11265
11266	list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
11267
11268	return 0;
11269}
11270EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
11271
11272/**
11273 * devl_dpipe_table_unregister - unregister dpipe table
11274 *
11275 * @devlink: devlink
11276 * @table_name: table name
11277 */
11278void devl_dpipe_table_unregister(struct devlink *devlink,
11279				 const char *table_name)
11280{
11281	struct devlink_dpipe_table *table;
11282
11283	lockdep_assert_held(&devlink->lock);
11284
11285	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
11286					 table_name, devlink);
11287	if (!table)
11288		return;
11289	list_del_rcu(&table->list);
11290	kfree_rcu(table, rcu);
11291}
11292EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
11293
11294/**
11295 * devl_resource_register - devlink resource register
11296 *
11297 * @devlink: devlink
11298 * @resource_name: resource's name
11299 * @resource_size: resource's size
11300 * @resource_id: resource's id
11301 * @parent_resource_id: resource's parent id
11302 * @size_params: size parameters
11303 *
11304 * Generic resources should reuse the same names across drivers.
11305 * Please see the generic resources list at:
11306 * Documentation/networking/devlink/devlink-resource.rst
11307 */
11308int devl_resource_register(struct devlink *devlink,
11309			   const char *resource_name,
11310			   u64 resource_size,
11311			   u64 resource_id,
11312			   u64 parent_resource_id,
11313			   const struct devlink_resource_size_params *size_params)
11314{
11315	struct devlink_resource *resource;
11316	struct list_head *resource_list;
11317	bool top_hierarchy;
11318
11319	lockdep_assert_held(&devlink->lock);
11320
11321	top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
11322
11323	resource = devlink_resource_find(devlink, NULL, resource_id);
11324	if (resource)
11325		return -EINVAL;
11326
11327	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
11328	if (!resource)
11329		return -ENOMEM;
11330
11331	if (top_hierarchy) {
11332		resource_list = &devlink->resource_list;
11333	} else {
11334		struct devlink_resource *parent_resource;
11335
11336		parent_resource = devlink_resource_find(devlink, NULL,
11337							parent_resource_id);
11338		if (parent_resource) {
11339			resource_list = &parent_resource->resource_list;
11340			resource->parent = parent_resource;
11341		} else {
11342			kfree(resource);
11343			return -EINVAL;
11344		}
11345	}
11346
11347	resource->name = resource_name;
11348	resource->size = resource_size;
11349	resource->size_new = resource_size;
11350	resource->id = resource_id;
11351	resource->size_valid = true;
11352	memcpy(&resource->size_params, size_params,
11353	       sizeof(resource->size_params));
11354	INIT_LIST_HEAD(&resource->resource_list);
11355	list_add_tail(&resource->list, resource_list);
11356
11357	return 0;
11358}
11359EXPORT_SYMBOL_GPL(devl_resource_register);
11360
11361/**
11362 *	devlink_resource_register - devlink resource register
11363 *
11364 *	@devlink: devlink
11365 *	@resource_name: resource's name
11366 *	@resource_size: resource's size
11367 *	@resource_id: resource's id
11368 *	@parent_resource_id: resource's parent id
11369 *	@size_params: size parameters
11370 *
11371 *	Generic resources should reuse the same names across drivers.
11372 *	Please see the generic resources list at:
11373 *	Documentation/networking/devlink/devlink-resource.rst
11374 *
11375 *	Context: Takes and release devlink->lock <mutex>.
11376 */
11377int devlink_resource_register(struct devlink *devlink,
11378			      const char *resource_name,
11379			      u64 resource_size,
11380			      u64 resource_id,
11381			      u64 parent_resource_id,
11382			      const struct devlink_resource_size_params *size_params)
11383{
11384	int err;
11385
11386	devl_lock(devlink);
11387	err = devl_resource_register(devlink, resource_name, resource_size,
11388				     resource_id, parent_resource_id, size_params);
11389	devl_unlock(devlink);
11390	return err;
11391}
11392EXPORT_SYMBOL_GPL(devlink_resource_register);
11393
11394static void devlink_resource_unregister(struct devlink *devlink,
11395					struct devlink_resource *resource)
11396{
11397	struct devlink_resource *tmp, *child_resource;
11398
11399	list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
11400				 list) {
11401		devlink_resource_unregister(devlink, child_resource);
11402		list_del(&child_resource->list);
11403		kfree(child_resource);
11404	}
11405}
11406
11407/**
11408 * devl_resources_unregister - free all resources
11409 *
11410 * @devlink: devlink
11411 */
11412void devl_resources_unregister(struct devlink *devlink)
11413{
11414	struct devlink_resource *tmp, *child_resource;
11415
11416	lockdep_assert_held(&devlink->lock);
11417
11418	list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
11419				 list) {
11420		devlink_resource_unregister(devlink, child_resource);
11421		list_del(&child_resource->list);
11422		kfree(child_resource);
11423	}
11424}
11425EXPORT_SYMBOL_GPL(devl_resources_unregister);
11426
11427/**
11428 *	devlink_resources_unregister - free all resources
11429 *
11430 *	@devlink: devlink
11431 *
11432 *	Context: Takes and release devlink->lock <mutex>.
11433 */
11434void devlink_resources_unregister(struct devlink *devlink)
11435{
11436	devl_lock(devlink);
11437	devl_resources_unregister(devlink);
11438	devl_unlock(devlink);
11439}
11440EXPORT_SYMBOL_GPL(devlink_resources_unregister);
11441
11442/**
11443 * devl_resource_size_get - get and update size
11444 *
11445 * @devlink: devlink
11446 * @resource_id: the requested resource id
11447 * @p_resource_size: ptr to update
11448 */
11449int devl_resource_size_get(struct devlink *devlink,
11450			   u64 resource_id,
11451			   u64 *p_resource_size)
11452{
11453	struct devlink_resource *resource;
11454
11455	lockdep_assert_held(&devlink->lock);
11456
11457	resource = devlink_resource_find(devlink, NULL, resource_id);
11458	if (!resource)
11459		return -EINVAL;
11460	*p_resource_size = resource->size_new;
11461	resource->size = resource->size_new;
11462	return 0;
11463}
11464EXPORT_SYMBOL_GPL(devl_resource_size_get);
11465
11466/**
11467 * devl_dpipe_table_resource_set - set the resource id
11468 *
11469 * @devlink: devlink
11470 * @table_name: table name
11471 * @resource_id: resource id
11472 * @resource_units: number of resource's units consumed per table's entry
11473 */
11474int devl_dpipe_table_resource_set(struct devlink *devlink,
11475				  const char *table_name, u64 resource_id,
11476				  u64 resource_units)
11477{
11478	struct devlink_dpipe_table *table;
11479
11480	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
11481					 table_name, devlink);
11482	if (!table)
11483		return -EINVAL;
11484
11485	table->resource_id = resource_id;
11486	table->resource_units = resource_units;
11487	table->resource_valid = true;
11488	return 0;
11489}
11490EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
11491
11492/**
11493 * devl_resource_occ_get_register - register occupancy getter
11494 *
11495 * @devlink: devlink
11496 * @resource_id: resource id
11497 * @occ_get: occupancy getter callback
11498 * @occ_get_priv: occupancy getter callback priv
11499 */
11500void devl_resource_occ_get_register(struct devlink *devlink,
11501				    u64 resource_id,
11502				    devlink_resource_occ_get_t *occ_get,
11503				    void *occ_get_priv)
11504{
11505	struct devlink_resource *resource;
11506
11507	lockdep_assert_held(&devlink->lock);
11508
11509	resource = devlink_resource_find(devlink, NULL, resource_id);
11510	if (WARN_ON(!resource))
11511		return;
11512	WARN_ON(resource->occ_get);
11513
11514	resource->occ_get = occ_get;
11515	resource->occ_get_priv = occ_get_priv;
11516}
11517EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
11518
11519/**
11520 *	devlink_resource_occ_get_register - register occupancy getter
11521 *
11522 *	@devlink: devlink
11523 *	@resource_id: resource id
11524 *	@occ_get: occupancy getter callback
11525 *	@occ_get_priv: occupancy getter callback priv
11526 *
11527 *	Context: Takes and release devlink->lock <mutex>.
11528 */
11529void devlink_resource_occ_get_register(struct devlink *devlink,
11530				       u64 resource_id,
11531				       devlink_resource_occ_get_t *occ_get,
11532				       void *occ_get_priv)
11533{
11534	devl_lock(devlink);
11535	devl_resource_occ_get_register(devlink, resource_id,
11536				       occ_get, occ_get_priv);
11537	devl_unlock(devlink);
11538}
11539EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
11540
11541/**
11542 * devl_resource_occ_get_unregister - unregister occupancy getter
11543 *
11544 * @devlink: devlink
11545 * @resource_id: resource id
11546 */
11547void devl_resource_occ_get_unregister(struct devlink *devlink,
11548				      u64 resource_id)
11549{
11550	struct devlink_resource *resource;
11551
11552	lockdep_assert_held(&devlink->lock);
11553
11554	resource = devlink_resource_find(devlink, NULL, resource_id);
11555	if (WARN_ON(!resource))
11556		return;
11557	WARN_ON(!resource->occ_get);
11558
11559	resource->occ_get = NULL;
11560	resource->occ_get_priv = NULL;
11561}
11562EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
11563
11564/**
11565 *	devlink_resource_occ_get_unregister - unregister occupancy getter
11566 *
11567 *	@devlink: devlink
11568 *	@resource_id: resource id
11569 *
11570 *	Context: Takes and release devlink->lock <mutex>.
11571 */
11572void devlink_resource_occ_get_unregister(struct devlink *devlink,
11573					 u64 resource_id)
11574{
11575	devl_lock(devlink);
11576	devl_resource_occ_get_unregister(devlink, resource_id);
11577	devl_unlock(devlink);
11578}
11579EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
11580
11581static int devlink_param_verify(const struct devlink_param *param)
11582{
11583	if (!param || !param->name || !param->supported_cmodes)
11584		return -EINVAL;
11585	if (param->generic)
11586		return devlink_param_generic_verify(param);
11587	else
11588		return devlink_param_driver_verify(param);
11589}
11590
11591/**
11592 *	devlink_params_register - register configuration parameters
11593 *
11594 *	@devlink: devlink
11595 *	@params: configuration parameters array
11596 *	@params_count: number of parameters provided
11597 *
11598 *	Register the configuration parameters supported by the driver.
11599 */
11600int devlink_params_register(struct devlink *devlink,
11601			    const struct devlink_param *params,
11602			    size_t params_count)
11603{
11604	const struct devlink_param *param = params;
11605	int i, err;
11606
11607	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11608
11609	for (i = 0; i < params_count; i++, param++) {
11610		err = devlink_param_register(devlink, param);
11611		if (err)
11612			goto rollback;
11613	}
11614	return 0;
11615
11616rollback:
11617	if (!i)
11618		return err;
11619
11620	for (param--; i > 0; i--, param--)
11621		devlink_param_unregister(devlink, param);
11622	return err;
11623}
11624EXPORT_SYMBOL_GPL(devlink_params_register);
11625
11626/**
11627 *	devlink_params_unregister - unregister configuration parameters
11628 *	@devlink: devlink
11629 *	@params: configuration parameters to unregister
11630 *	@params_count: number of parameters provided
11631 */
11632void devlink_params_unregister(struct devlink *devlink,
11633			       const struct devlink_param *params,
11634			       size_t params_count)
11635{
11636	const struct devlink_param *param = params;
11637	int i;
11638
11639	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11640
11641	for (i = 0; i < params_count; i++, param++)
11642		devlink_param_unregister(devlink, param);
11643}
11644EXPORT_SYMBOL_GPL(devlink_params_unregister);
11645
11646/**
11647 * devlink_param_register - register one configuration parameter
11648 *
11649 * @devlink: devlink
11650 * @param: one configuration parameter
11651 *
11652 * Register the configuration parameter supported by the driver.
11653 * Return: returns 0 on successful registration or error code otherwise.
11654 */
11655int devlink_param_register(struct devlink *devlink,
11656			   const struct devlink_param *param)
11657{
11658	struct devlink_param_item *param_item;
11659
11660	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11661
11662	WARN_ON(devlink_param_verify(param));
11663	WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
11664
11665	if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
11666		WARN_ON(param->get || param->set);
11667	else
11668		WARN_ON(!param->get || !param->set);
11669
11670	param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
11671	if (!param_item)
11672		return -ENOMEM;
11673
11674	param_item->param = param;
11675
11676	list_add_tail(&param_item->list, &devlink->param_list);
11677	return 0;
11678}
11679EXPORT_SYMBOL_GPL(devlink_param_register);
11680
11681/**
11682 * devlink_param_unregister - unregister one configuration parameter
11683 * @devlink: devlink
11684 * @param: configuration parameter to unregister
11685 */
11686void devlink_param_unregister(struct devlink *devlink,
11687			      const struct devlink_param *param)
11688{
11689	struct devlink_param_item *param_item;
11690
11691	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11692
11693	param_item =
11694		devlink_param_find_by_name(&devlink->param_list, param->name);
11695	WARN_ON(!param_item);
11696	list_del(&param_item->list);
11697	kfree(param_item);
11698}
11699EXPORT_SYMBOL_GPL(devlink_param_unregister);
11700
11701/**
11702 *	devlink_param_driverinit_value_get - get configuration parameter
11703 *					     value for driver initializing
11704 *
11705 *	@devlink: devlink
11706 *	@param_id: parameter ID
11707 *	@init_val: value of parameter in driverinit configuration mode
11708 *
11709 *	This function should be used by the driver to get driverinit
11710 *	configuration for initialization after reload command.
11711 */
11712int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
11713				       union devlink_param_value *init_val)
11714{
11715	struct devlink_param_item *param_item;
11716
11717	if (!devlink_reload_supported(devlink->ops))
11718		return -EOPNOTSUPP;
11719
11720	param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11721	if (!param_item)
11722		return -EINVAL;
11723
11724	if (!param_item->driverinit_value_valid ||
11725	    !devlink_param_cmode_is_supported(param_item->param,
11726					      DEVLINK_PARAM_CMODE_DRIVERINIT))
11727		return -EOPNOTSUPP;
11728
11729	if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11730		strcpy(init_val->vstr, param_item->driverinit_value.vstr);
11731	else
11732		*init_val = param_item->driverinit_value;
11733
11734	return 0;
11735}
11736EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
11737
11738/**
11739 *	devlink_param_driverinit_value_set - set value of configuration
11740 *					     parameter for driverinit
11741 *					     configuration mode
11742 *
11743 *	@devlink: devlink
11744 *	@param_id: parameter ID
11745 *	@init_val: value of parameter to set for driverinit configuration mode
11746 *
11747 *	This function should be used by the driver to set driverinit
11748 *	configuration mode default value.
11749 */
11750int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
11751				       union devlink_param_value init_val)
11752{
11753	struct devlink_param_item *param_item;
11754
11755	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11756
11757	param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11758	if (!param_item)
11759		return -EINVAL;
11760
11761	if (!devlink_param_cmode_is_supported(param_item->param,
11762					      DEVLINK_PARAM_CMODE_DRIVERINIT))
11763		return -EOPNOTSUPP;
11764
11765	if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11766		strcpy(param_item->driverinit_value.vstr, init_val.vstr);
11767	else
11768		param_item->driverinit_value = init_val;
11769	param_item->driverinit_value_valid = true;
11770	return 0;
11771}
11772EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
11773
11774/**
11775 *	devlink_param_value_changed - notify devlink on a parameter's value
11776 *				      change. Should be called by the driver
11777 *				      right after the change.
11778 *
11779 *	@devlink: devlink
11780 *	@param_id: parameter ID
11781 *
11782 *	This function should be used by the driver to notify devlink on value
11783 *	change, excluding driverinit configuration mode.
11784 *	For driverinit configuration mode driver should use the function
11785 */
11786void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
11787{
11788	struct devlink_param_item *param_item;
11789
11790	param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11791	WARN_ON(!param_item);
11792
11793	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11794}
11795EXPORT_SYMBOL_GPL(devlink_param_value_changed);
11796
11797/**
11798 * devl_region_create - create a new address region
11799 *
11800 * @devlink: devlink
11801 * @ops: region operations and name
11802 * @region_max_snapshots: Maximum supported number of snapshots for region
11803 * @region_size: size of region
11804 */
11805struct devlink_region *devl_region_create(struct devlink *devlink,
11806					  const struct devlink_region_ops *ops,
11807					  u32 region_max_snapshots,
11808					  u64 region_size)
11809{
11810	struct devlink_region *region;
11811
11812	devl_assert_locked(devlink);
11813
11814	if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11815		return ERR_PTR(-EINVAL);
11816
11817	if (devlink_region_get_by_name(devlink, ops->name))
11818		return ERR_PTR(-EEXIST);
11819
11820	region = kzalloc(sizeof(*region), GFP_KERNEL);
11821	if (!region)
11822		return ERR_PTR(-ENOMEM);
11823
11824	region->devlink = devlink;
11825	region->max_snapshots = region_max_snapshots;
11826	region->ops = ops;
11827	region->size = region_size;
11828	INIT_LIST_HEAD(&region->snapshot_list);
11829	mutex_init(&region->snapshot_lock);
11830	list_add_tail(&region->list, &devlink->region_list);
11831	devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11832
11833	return region;
11834}
11835EXPORT_SYMBOL_GPL(devl_region_create);
11836
11837/**
11838 *	devlink_region_create - create a new address region
11839 *
11840 *	@devlink: devlink
11841 *	@ops: region operations and name
11842 *	@region_max_snapshots: Maximum supported number of snapshots for region
11843 *	@region_size: size of region
11844 *
11845 *	Context: Takes and release devlink->lock <mutex>.
11846 */
11847struct devlink_region *
11848devlink_region_create(struct devlink *devlink,
11849		      const struct devlink_region_ops *ops,
11850		      u32 region_max_snapshots, u64 region_size)
11851{
11852	struct devlink_region *region;
11853
11854	devl_lock(devlink);
11855	region = devl_region_create(devlink, ops, region_max_snapshots,
11856				    region_size);
11857	devl_unlock(devlink);
11858	return region;
11859}
11860EXPORT_SYMBOL_GPL(devlink_region_create);
11861
11862/**
11863 *	devlink_port_region_create - create a new address region for a port
11864 *
11865 *	@port: devlink port
11866 *	@ops: region operations and name
11867 *	@region_max_snapshots: Maximum supported number of snapshots for region
11868 *	@region_size: size of region
11869 *
11870 *	Context: Takes and release devlink->lock <mutex>.
11871 */
11872struct devlink_region *
11873devlink_port_region_create(struct devlink_port *port,
11874			   const struct devlink_port_region_ops *ops,
11875			   u32 region_max_snapshots, u64 region_size)
11876{
11877	struct devlink *devlink = port->devlink;
11878	struct devlink_region *region;
11879	int err = 0;
11880
11881	ASSERT_DEVLINK_PORT_INITIALIZED(port);
11882
11883	if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11884		return ERR_PTR(-EINVAL);
11885
11886	devl_lock(devlink);
11887
11888	if (devlink_port_region_get_by_name(port, ops->name)) {
11889		err = -EEXIST;
11890		goto unlock;
11891	}
11892
11893	region = kzalloc(sizeof(*region), GFP_KERNEL);
11894	if (!region) {
11895		err = -ENOMEM;
11896		goto unlock;
11897	}
11898
11899	region->devlink = devlink;
11900	region->port = port;
11901	region->max_snapshots = region_max_snapshots;
11902	region->port_ops = ops;
11903	region->size = region_size;
11904	INIT_LIST_HEAD(&region->snapshot_list);
11905	mutex_init(&region->snapshot_lock);
11906	list_add_tail(&region->list, &port->region_list);
11907	devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11908
11909	devl_unlock(devlink);
11910	return region;
11911
11912unlock:
11913	devl_unlock(devlink);
11914	return ERR_PTR(err);
11915}
11916EXPORT_SYMBOL_GPL(devlink_port_region_create);
11917
11918/**
11919 * devl_region_destroy - destroy address region
11920 *
11921 * @region: devlink region to destroy
11922 */
11923void devl_region_destroy(struct devlink_region *region)
11924{
11925	struct devlink *devlink = region->devlink;
11926	struct devlink_snapshot *snapshot, *ts;
11927
11928	devl_assert_locked(devlink);
11929
11930	/* Free all snapshots of region */
11931	mutex_lock(&region->snapshot_lock);
11932	list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
11933		devlink_region_snapshot_del(region, snapshot);
11934	mutex_unlock(&region->snapshot_lock);
11935
11936	list_del(&region->list);
11937	mutex_destroy(&region->snapshot_lock);
11938
11939	devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11940	kfree(region);
11941}
11942EXPORT_SYMBOL_GPL(devl_region_destroy);
11943
11944/**
11945 *	devlink_region_destroy - destroy address region
11946 *
11947 *	@region: devlink region to destroy
11948 *
11949 *	Context: Takes and release devlink->lock <mutex>.
11950 */
11951void devlink_region_destroy(struct devlink_region *region)
11952{
11953	struct devlink *devlink = region->devlink;
11954
11955	devl_lock(devlink);
11956	devl_region_destroy(region);
11957	devl_unlock(devlink);
11958}
11959EXPORT_SYMBOL_GPL(devlink_region_destroy);
11960
11961/**
11962 *	devlink_region_snapshot_id_get - get snapshot ID
11963 *
11964 *	This callback should be called when adding a new snapshot,
11965 *	Driver should use the same id for multiple snapshots taken
11966 *	on multiple regions at the same time/by the same trigger.
11967 *
11968 *	The caller of this function must use devlink_region_snapshot_id_put
11969 *	when finished creating regions using this id.
11970 *
11971 *	Returns zero on success, or a negative error code on failure.
11972 *
11973 *	@devlink: devlink
11974 *	@id: storage to return id
11975 */
11976int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11977{
11978	return __devlink_region_snapshot_id_get(devlink, id);
11979}
11980EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11981
11982/**
11983 *	devlink_region_snapshot_id_put - put snapshot ID reference
11984 *
11985 *	This should be called by a driver after finishing creating snapshots
11986 *	with an id. Doing so ensures that the ID can later be released in the
11987 *	event that all snapshots using it have been destroyed.
11988 *
11989 *	@devlink: devlink
11990 *	@id: id to release reference on
11991 */
11992void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11993{
11994	__devlink_snapshot_id_decrement(devlink, id);
11995}
11996EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11997
11998/**
11999 *	devlink_region_snapshot_create - create a new snapshot
12000 *	This will add a new snapshot of a region. The snapshot
12001 *	will be stored on the region struct and can be accessed
12002 *	from devlink. This is useful for future analyses of snapshots.
12003 *	Multiple snapshots can be created on a region.
12004 *	The @snapshot_id should be obtained using the getter function.
12005 *
12006 *	@region: devlink region of the snapshot
12007 *	@data: snapshot data
12008 *	@snapshot_id: snapshot id to be created
12009 */
12010int devlink_region_snapshot_create(struct devlink_region *region,
12011				   u8 *data, u32 snapshot_id)
12012{
12013	int err;
12014
12015	mutex_lock(&region->snapshot_lock);
12016	err = __devlink_region_snapshot_create(region, data, snapshot_id);
12017	mutex_unlock(&region->snapshot_lock);
12018	return err;
12019}
12020EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
12021
12022#define DEVLINK_TRAP(_id, _type)					      \
12023	{								      \
12024		.type = DEVLINK_TRAP_TYPE_##_type,			      \
12025		.id = DEVLINK_TRAP_GENERIC_ID_##_id,			      \
12026		.name = DEVLINK_TRAP_GENERIC_NAME_##_id,		      \
12027	}
12028
12029static const struct devlink_trap devlink_trap_generic[] = {
12030	DEVLINK_TRAP(SMAC_MC, DROP),
12031	DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
12032	DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
12033	DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
12034	DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
12035	DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
12036	DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
12037	DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
12038	DEVLINK_TRAP(TAIL_DROP, DROP),
12039	DEVLINK_TRAP(NON_IP_PACKET, DROP),
12040	DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
12041	DEVLINK_TRAP(DIP_LB, DROP),
12042	DEVLINK_TRAP(SIP_MC, DROP),
12043	DEVLINK_TRAP(SIP_LB, DROP),
12044	DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
12045	DEVLINK_TRAP(IPV4_SIP_BC, DROP),
12046	DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
12047	DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
12048	DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
12049	DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
12050	DEVLINK_TRAP(RPF, EXCEPTION),
12051	DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
12052	DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
12053	DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
12054	DEVLINK_TRAP(NON_ROUTABLE, DROP),
12055	DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
12056	DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
12057	DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
12058	DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
12059	DEVLINK_TRAP(STP, CONTROL),
12060	DEVLINK_TRAP(LACP, CONTROL),
12061	DEVLINK_TRAP(LLDP, CONTROL),
12062	DEVLINK_TRAP(IGMP_QUERY, CONTROL),
12063	DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
12064	DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
12065	DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
12066	DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
12067	DEVLINK_TRAP(MLD_QUERY, CONTROL),
12068	DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
12069	DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
12070	DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
12071	DEVLINK_TRAP(IPV4_DHCP, CONTROL),
12072	DEVLINK_TRAP(IPV6_DHCP, CONTROL),
12073	DEVLINK_TRAP(ARP_REQUEST, CONTROL),
12074	DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
12075	DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
12076	DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
12077	DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
12078	DEVLINK_TRAP(IPV4_BFD, CONTROL),
12079	DEVLINK_TRAP(IPV6_BFD, CONTROL),
12080	DEVLINK_TRAP(IPV4_OSPF, CONTROL),
12081	DEVLINK_TRAP(IPV6_OSPF, CONTROL),
12082	DEVLINK_TRAP(IPV4_BGP, CONTROL),
12083	DEVLINK_TRAP(IPV6_BGP, CONTROL),
12084	DEVLINK_TRAP(IPV4_VRRP, CONTROL),
12085	DEVLINK_TRAP(IPV6_VRRP, CONTROL),
12086	DEVLINK_TRAP(IPV4_PIM, CONTROL),
12087	DEVLINK_TRAP(IPV6_PIM, CONTROL),
12088	DEVLINK_TRAP(UC_LB, CONTROL),
12089	DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
12090	DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
12091	DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
12092	DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
12093	DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
12094	DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
12095	DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
12096	DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
12097	DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
12098	DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
12099	DEVLINK_TRAP(PTP_EVENT, CONTROL),
12100	DEVLINK_TRAP(PTP_GENERAL, CONTROL),
12101	DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
12102	DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
12103	DEVLINK_TRAP(EARLY_DROP, DROP),
12104	DEVLINK_TRAP(VXLAN_PARSING, DROP),
12105	DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
12106	DEVLINK_TRAP(VLAN_PARSING, DROP),
12107	DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
12108	DEVLINK_TRAP(MPLS_PARSING, DROP),
12109	DEVLINK_TRAP(ARP_PARSING, DROP),
12110	DEVLINK_TRAP(IP_1_PARSING, DROP),
12111	DEVLINK_TRAP(IP_N_PARSING, DROP),
12112	DEVLINK_TRAP(GRE_PARSING, DROP),
12113	DEVLINK_TRAP(UDP_PARSING, DROP),
12114	DEVLINK_TRAP(TCP_PARSING, DROP),
12115	DEVLINK_TRAP(IPSEC_PARSING, DROP),
12116	DEVLINK_TRAP(SCTP_PARSING, DROP),
12117	DEVLINK_TRAP(DCCP_PARSING, DROP),
12118	DEVLINK_TRAP(GTP_PARSING, DROP),
12119	DEVLINK_TRAP(ESP_PARSING, DROP),
12120	DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
12121	DEVLINK_TRAP(DMAC_FILTER, DROP),
12122	DEVLINK_TRAP(EAPOL, CONTROL),
12123	DEVLINK_TRAP(LOCKED_PORT, DROP),
12124};
12125
12126#define DEVLINK_TRAP_GROUP(_id)						      \
12127	{								      \
12128		.id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id,		      \
12129		.name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id,		      \
12130	}
12131
12132static const struct devlink_trap_group devlink_trap_group_generic[] = {
12133	DEVLINK_TRAP_GROUP(L2_DROPS),
12134	DEVLINK_TRAP_GROUP(L3_DROPS),
12135	DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
12136	DEVLINK_TRAP_GROUP(BUFFER_DROPS),
12137	DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
12138	DEVLINK_TRAP_GROUP(ACL_DROPS),
12139	DEVLINK_TRAP_GROUP(STP),
12140	DEVLINK_TRAP_GROUP(LACP),
12141	DEVLINK_TRAP_GROUP(LLDP),
12142	DEVLINK_TRAP_GROUP(MC_SNOOPING),
12143	DEVLINK_TRAP_GROUP(DHCP),
12144	DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
12145	DEVLINK_TRAP_GROUP(BFD),
12146	DEVLINK_TRAP_GROUP(OSPF),
12147	DEVLINK_TRAP_GROUP(BGP),
12148	DEVLINK_TRAP_GROUP(VRRP),
12149	DEVLINK_TRAP_GROUP(PIM),
12150	DEVLINK_TRAP_GROUP(UC_LB),
12151	DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
12152	DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
12153	DEVLINK_TRAP_GROUP(IPV6),
12154	DEVLINK_TRAP_GROUP(PTP_EVENT),
12155	DEVLINK_TRAP_GROUP(PTP_GENERAL),
12156	DEVLINK_TRAP_GROUP(ACL_SAMPLE),
12157	DEVLINK_TRAP_GROUP(ACL_TRAP),
12158	DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
12159	DEVLINK_TRAP_GROUP(EAPOL),
12160};
12161
12162static int devlink_trap_generic_verify(const struct devlink_trap *trap)
12163{
12164	if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
12165		return -EINVAL;
12166
12167	if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
12168		return -EINVAL;
12169
12170	if (trap->type != devlink_trap_generic[trap->id].type)
12171		return -EINVAL;
12172
12173	return 0;
12174}
12175
12176static int devlink_trap_driver_verify(const struct devlink_trap *trap)
12177{
12178	int i;
12179
12180	if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
12181		return -EINVAL;
12182
12183	for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
12184		if (!strcmp(trap->name, devlink_trap_generic[i].name))
12185			return -EEXIST;
12186	}
12187
12188	return 0;
12189}
12190
12191static int devlink_trap_verify(const struct devlink_trap *trap)
12192{
12193	if (!trap || !trap->name)
12194		return -EINVAL;
12195
12196	if (trap->generic)
12197		return devlink_trap_generic_verify(trap);
12198	else
12199		return devlink_trap_driver_verify(trap);
12200}
12201
12202static int
12203devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
12204{
12205	if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
12206		return -EINVAL;
12207
12208	if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
12209		return -EINVAL;
12210
12211	return 0;
12212}
12213
12214static int
12215devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
12216{
12217	int i;
12218
12219	if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
12220		return -EINVAL;
12221
12222	for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
12223		if (!strcmp(group->name, devlink_trap_group_generic[i].name))
12224			return -EEXIST;
12225	}
12226
12227	return 0;
12228}
12229
12230static int devlink_trap_group_verify(const struct devlink_trap_group *group)
12231{
12232	if (group->generic)
12233		return devlink_trap_group_generic_verify(group);
12234	else
12235		return devlink_trap_group_driver_verify(group);
12236}
12237
12238static void
12239devlink_trap_group_notify(struct devlink *devlink,
12240			  const struct devlink_trap_group_item *group_item,
12241			  enum devlink_command cmd)
12242{
12243	struct sk_buff *msg;
12244	int err;
12245
12246	WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
12247		     cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
12248	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
12249		return;
12250
12251	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12252	if (!msg)
12253		return;
12254
12255	err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
12256					 0);
12257	if (err) {
12258		nlmsg_free(msg);
12259		return;
12260	}
12261
12262	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
12263				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
12264}
12265
12266static int
12267devlink_trap_item_group_link(struct devlink *devlink,
12268			     struct devlink_trap_item *trap_item)
12269{
12270	u16 group_id = trap_item->trap->init_group_id;
12271	struct devlink_trap_group_item *group_item;
12272
12273	group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
12274	if (WARN_ON_ONCE(!group_item))
12275		return -EINVAL;
12276
12277	trap_item->group_item = group_item;
12278
12279	return 0;
12280}
12281
12282static void devlink_trap_notify(struct devlink *devlink,
12283				const struct devlink_trap_item *trap_item,
12284				enum devlink_command cmd)
12285{
12286	struct sk_buff *msg;
12287	int err;
12288
12289	WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
12290		     cmd != DEVLINK_CMD_TRAP_DEL);
12291	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
12292		return;
12293
12294	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12295	if (!msg)
12296		return;
12297
12298	err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
12299	if (err) {
12300		nlmsg_free(msg);
12301		return;
12302	}
12303
12304	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
12305				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
12306}
12307
12308static int
12309devlink_trap_register(struct devlink *devlink,
12310		      const struct devlink_trap *trap, void *priv)
12311{
12312	struct devlink_trap_item *trap_item;
12313	int err;
12314
12315	if (devlink_trap_item_lookup(devlink, trap->name))
12316		return -EEXIST;
12317
12318	trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
12319	if (!trap_item)
12320		return -ENOMEM;
12321
12322	trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
12323	if (!trap_item->stats) {
12324		err = -ENOMEM;
12325		goto err_stats_alloc;
12326	}
12327
12328	trap_item->trap = trap;
12329	trap_item->action = trap->init_action;
12330	trap_item->priv = priv;
12331
12332	err = devlink_trap_item_group_link(devlink, trap_item);
12333	if (err)
12334		goto err_group_link;
12335
12336	err = devlink->ops->trap_init(devlink, trap, trap_item);
12337	if (err)
12338		goto err_trap_init;
12339
12340	list_add_tail(&trap_item->list, &devlink->trap_list);
12341	devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
12342
12343	return 0;
12344
12345err_trap_init:
12346err_group_link:
12347	free_percpu(trap_item->stats);
12348err_stats_alloc:
12349	kfree(trap_item);
12350	return err;
12351}
 
12352
12353static void devlink_trap_unregister(struct devlink *devlink,
12354				    const struct devlink_trap *trap)
12355{
12356	struct devlink_trap_item *trap_item;
12357
12358	trap_item = devlink_trap_item_lookup(devlink, trap->name);
12359	if (WARN_ON_ONCE(!trap_item))
12360		return;
12361
12362	devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
12363	list_del(&trap_item->list);
12364	if (devlink->ops->trap_fini)
12365		devlink->ops->trap_fini(devlink, trap, trap_item);
12366	free_percpu(trap_item->stats);
12367	kfree(trap_item);
12368}
12369
12370static void devlink_trap_disable(struct devlink *devlink,
12371				 const struct devlink_trap *trap)
12372{
12373	struct devlink_trap_item *trap_item;
12374
12375	trap_item = devlink_trap_item_lookup(devlink, trap->name);
12376	if (WARN_ON_ONCE(!trap_item))
12377		return;
12378
12379	devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
12380				      NULL);
12381	trap_item->action = DEVLINK_TRAP_ACTION_DROP;
12382}
12383
12384/**
12385 * devl_traps_register - Register packet traps with devlink.
12386 * @devlink: devlink.
12387 * @traps: Packet traps.
12388 * @traps_count: Count of provided packet traps.
12389 * @priv: Driver private information.
12390 *
12391 * Return: Non-zero value on failure.
12392 */
12393int devl_traps_register(struct devlink *devlink,
12394			const struct devlink_trap *traps,
12395			size_t traps_count, void *priv)
12396{
12397	int i, err;
12398
12399	if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
12400		return -EINVAL;
12401
12402	devl_assert_locked(devlink);
12403	for (i = 0; i < traps_count; i++) {
12404		const struct devlink_trap *trap = &traps[i];
12405
12406		err = devlink_trap_verify(trap);
12407		if (err)
12408			goto err_trap_verify;
12409
12410		err = devlink_trap_register(devlink, trap, priv);
12411		if (err)
12412			goto err_trap_register;
12413	}
12414
12415	return 0;
12416
12417err_trap_register:
12418err_trap_verify:
12419	for (i--; i >= 0; i--)
12420		devlink_trap_unregister(devlink, &traps[i]);
12421	return err;
12422}
12423EXPORT_SYMBOL_GPL(devl_traps_register);
12424
12425/**
12426 * devlink_traps_register - Register packet traps with devlink.
12427 * @devlink: devlink.
12428 * @traps: Packet traps.
12429 * @traps_count: Count of provided packet traps.
12430 * @priv: Driver private information.
12431 *
12432 * Context: Takes and release devlink->lock <mutex>.
12433 *
12434 * Return: Non-zero value on failure.
12435 */
12436int devlink_traps_register(struct devlink *devlink,
12437			   const struct devlink_trap *traps,
12438			   size_t traps_count, void *priv)
12439{
12440	int err;
12441
12442	devl_lock(devlink);
12443	err = devl_traps_register(devlink, traps, traps_count, priv);
12444	devl_unlock(devlink);
12445	return err;
12446}
12447EXPORT_SYMBOL_GPL(devlink_traps_register);
12448
12449/**
12450 * devl_traps_unregister - Unregister packet traps from devlink.
12451 * @devlink: devlink.
12452 * @traps: Packet traps.
12453 * @traps_count: Count of provided packet traps.
12454 */
12455void devl_traps_unregister(struct devlink *devlink,
12456			   const struct devlink_trap *traps,
12457			   size_t traps_count)
12458{
12459	int i;
12460
12461	devl_assert_locked(devlink);
12462	/* Make sure we do not have any packets in-flight while unregistering
12463	 * traps by disabling all of them and waiting for a grace period.
12464	 */
12465	for (i = traps_count - 1; i >= 0; i--)
12466		devlink_trap_disable(devlink, &traps[i]);
12467	synchronize_rcu();
12468	for (i = traps_count - 1; i >= 0; i--)
12469		devlink_trap_unregister(devlink, &traps[i]);
12470}
12471EXPORT_SYMBOL_GPL(devl_traps_unregister);
12472
12473/**
12474 * devlink_traps_unregister - Unregister packet traps from devlink.
12475 * @devlink: devlink.
12476 * @traps: Packet traps.
12477 * @traps_count: Count of provided packet traps.
12478 *
12479 * Context: Takes and release devlink->lock <mutex>.
12480 */
12481void devlink_traps_unregister(struct devlink *devlink,
12482			      const struct devlink_trap *traps,
12483			      size_t traps_count)
12484{
12485	devl_lock(devlink);
12486	devl_traps_unregister(devlink, traps, traps_count);
12487	devl_unlock(devlink);
12488}
12489EXPORT_SYMBOL_GPL(devlink_traps_unregister);
12490
12491static void
12492devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
12493			  size_t skb_len)
12494{
12495	struct devlink_stats *stats;
12496
12497	stats = this_cpu_ptr(trap_stats);
12498	u64_stats_update_begin(&stats->syncp);
12499	u64_stats_add(&stats->rx_bytes, skb_len);
12500	u64_stats_inc(&stats->rx_packets);
12501	u64_stats_update_end(&stats->syncp);
12502}
12503
12504static void
12505devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
12506				 const struct devlink_trap_item *trap_item,
12507				 struct devlink_port *in_devlink_port,
12508				 const struct flow_action_cookie *fa_cookie)
12509{
12510	metadata->trap_name = trap_item->trap->name;
12511	metadata->trap_group_name = trap_item->group_item->group->name;
12512	metadata->fa_cookie = fa_cookie;
12513	metadata->trap_type = trap_item->trap->type;
12514
12515	spin_lock(&in_devlink_port->type_lock);
12516	if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
12517		metadata->input_dev = in_devlink_port->type_eth.netdev;
12518	spin_unlock(&in_devlink_port->type_lock);
12519}
12520
12521/**
12522 * devlink_trap_report - Report trapped packet to drop monitor.
12523 * @devlink: devlink.
12524 * @skb: Trapped packet.
12525 * @trap_ctx: Trap context.
12526 * @in_devlink_port: Input devlink port.
12527 * @fa_cookie: Flow action cookie. Could be NULL.
12528 */
12529void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
12530			 void *trap_ctx, struct devlink_port *in_devlink_port,
12531			 const struct flow_action_cookie *fa_cookie)
12532
12533{
12534	struct devlink_trap_item *trap_item = trap_ctx;
12535
12536	devlink_trap_stats_update(trap_item->stats, skb->len);
12537	devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
12538
12539	if (trace_devlink_trap_report_enabled()) {
12540		struct devlink_trap_metadata metadata = {};
12541
12542		devlink_trap_report_metadata_set(&metadata, trap_item,
12543						 in_devlink_port, fa_cookie);
12544		trace_devlink_trap_report(devlink, skb, &metadata);
12545	}
12546}
12547EXPORT_SYMBOL_GPL(devlink_trap_report);
12548
12549/**
12550 * devlink_trap_ctx_priv - Trap context to driver private information.
12551 * @trap_ctx: Trap context.
12552 *
12553 * Return: Driver private information passed during registration.
12554 */
12555void *devlink_trap_ctx_priv(void *trap_ctx)
12556{
12557	struct devlink_trap_item *trap_item = trap_ctx;
12558
12559	return trap_item->priv;
12560}
12561EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
12562
12563static int
12564devlink_trap_group_item_policer_link(struct devlink *devlink,
12565				     struct devlink_trap_group_item *group_item)
12566{
12567	u32 policer_id = group_item->group->init_policer_id;
12568	struct devlink_trap_policer_item *policer_item;
12569
12570	if (policer_id == 0)
12571		return 0;
12572
12573	policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
12574	if (WARN_ON_ONCE(!policer_item))
12575		return -EINVAL;
12576
12577	group_item->policer_item = policer_item;
12578
12579	return 0;
12580}
12581
12582static int
12583devlink_trap_group_register(struct devlink *devlink,
12584			    const struct devlink_trap_group *group)
12585{
12586	struct devlink_trap_group_item *group_item;
12587	int err;
12588
12589	if (devlink_trap_group_item_lookup(devlink, group->name))
12590		return -EEXIST;
12591
12592	group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
12593	if (!group_item)
12594		return -ENOMEM;
12595
12596	group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
12597	if (!group_item->stats) {
12598		err = -ENOMEM;
12599		goto err_stats_alloc;
12600	}
12601
12602	group_item->group = group;
12603
12604	err = devlink_trap_group_item_policer_link(devlink, group_item);
12605	if (err)
12606		goto err_policer_link;
12607
12608	if (devlink->ops->trap_group_init) {
12609		err = devlink->ops->trap_group_init(devlink, group);
12610		if (err)
12611			goto err_group_init;
12612	}
12613
12614	list_add_tail(&group_item->list, &devlink->trap_group_list);
12615	devlink_trap_group_notify(devlink, group_item,
12616				  DEVLINK_CMD_TRAP_GROUP_NEW);
12617
12618	return 0;
12619
12620err_group_init:
12621err_policer_link:
12622	free_percpu(group_item->stats);
12623err_stats_alloc:
12624	kfree(group_item);
12625	return err;
12626}
12627
12628static void
12629devlink_trap_group_unregister(struct devlink *devlink,
12630			      const struct devlink_trap_group *group)
12631{
12632	struct devlink_trap_group_item *group_item;
12633
12634	group_item = devlink_trap_group_item_lookup(devlink, group->name);
12635	if (WARN_ON_ONCE(!group_item))
12636		return;
12637
12638	devlink_trap_group_notify(devlink, group_item,
12639				  DEVLINK_CMD_TRAP_GROUP_DEL);
12640	list_del(&group_item->list);
12641	free_percpu(group_item->stats);
12642	kfree(group_item);
12643}
12644
12645/**
12646 * devl_trap_groups_register - Register packet trap groups with devlink.
12647 * @devlink: devlink.
12648 * @groups: Packet trap groups.
12649 * @groups_count: Count of provided packet trap groups.
12650 *
12651 * Return: Non-zero value on failure.
12652 */
12653int devl_trap_groups_register(struct devlink *devlink,
12654			      const struct devlink_trap_group *groups,
12655			      size_t groups_count)
12656{
12657	int i, err;
12658
12659	devl_assert_locked(devlink);
12660	for (i = 0; i < groups_count; i++) {
12661		const struct devlink_trap_group *group = &groups[i];
12662
12663		err = devlink_trap_group_verify(group);
12664		if (err)
12665			goto err_trap_group_verify;
12666
12667		err = devlink_trap_group_register(devlink, group);
12668		if (err)
12669			goto err_trap_group_register;
12670	}
12671
12672	return 0;
12673
12674err_trap_group_register:
12675err_trap_group_verify:
12676	for (i--; i >= 0; i--)
12677		devlink_trap_group_unregister(devlink, &groups[i]);
12678	return err;
12679}
12680EXPORT_SYMBOL_GPL(devl_trap_groups_register);
12681
12682/**
12683 * devlink_trap_groups_register - Register packet trap groups with devlink.
12684 * @devlink: devlink.
12685 * @groups: Packet trap groups.
12686 * @groups_count: Count of provided packet trap groups.
12687 *
12688 * Context: Takes and release devlink->lock <mutex>.
12689 *
12690 * Return: Non-zero value on failure.
12691 */
12692int devlink_trap_groups_register(struct devlink *devlink,
12693				 const struct devlink_trap_group *groups,
12694				 size_t groups_count)
12695{
12696	int err;
12697
12698	devl_lock(devlink);
12699	err = devl_trap_groups_register(devlink, groups, groups_count);
12700	devl_unlock(devlink);
12701	return err;
12702}
12703EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
12704
12705/**
12706 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
12707 * @devlink: devlink.
12708 * @groups: Packet trap groups.
12709 * @groups_count: Count of provided packet trap groups.
12710 */
12711void devl_trap_groups_unregister(struct devlink *devlink,
12712				 const struct devlink_trap_group *groups,
12713				 size_t groups_count)
12714{
12715	int i;
12716
12717	devl_assert_locked(devlink);
12718	for (i = groups_count - 1; i >= 0; i--)
12719		devlink_trap_group_unregister(devlink, &groups[i]);
12720}
12721EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
12722
12723/**
12724 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
12725 * @devlink: devlink.
12726 * @groups: Packet trap groups.
12727 * @groups_count: Count of provided packet trap groups.
12728 *
12729 * Context: Takes and release devlink->lock <mutex>.
12730 */
12731void devlink_trap_groups_unregister(struct devlink *devlink,
12732				    const struct devlink_trap_group *groups,
12733				    size_t groups_count)
12734{
12735	devl_lock(devlink);
12736	devl_trap_groups_unregister(devlink, groups, groups_count);
12737	devl_unlock(devlink);
12738}
12739EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
12740
12741static void
12742devlink_trap_policer_notify(struct devlink *devlink,
12743			    const struct devlink_trap_policer_item *policer_item,
12744			    enum devlink_command cmd)
12745{
12746	struct sk_buff *msg;
12747	int err;
12748
12749	WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
12750		     cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
12751	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
12752		return;
12753
12754	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12755	if (!msg)
12756		return;
12757
12758	err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
12759					   0, 0);
12760	if (err) {
12761		nlmsg_free(msg);
12762		return;
12763	}
12764
12765	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
12766				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
12767}
12768
12769static int
12770devlink_trap_policer_register(struct devlink *devlink,
12771			      const struct devlink_trap_policer *policer)
12772{
12773	struct devlink_trap_policer_item *policer_item;
12774	int err;
12775
12776	if (devlink_trap_policer_item_lookup(devlink, policer->id))
12777		return -EEXIST;
12778
12779	policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
12780	if (!policer_item)
12781		return -ENOMEM;
12782
12783	policer_item->policer = policer;
12784	policer_item->rate = policer->init_rate;
12785	policer_item->burst = policer->init_burst;
12786
12787	if (devlink->ops->trap_policer_init) {
12788		err = devlink->ops->trap_policer_init(devlink, policer);
12789		if (err)
12790			goto err_policer_init;
12791	}
12792
12793	list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12794	devlink_trap_policer_notify(devlink, policer_item,
12795				    DEVLINK_CMD_TRAP_POLICER_NEW);
12796
12797	return 0;
12798
12799err_policer_init:
12800	kfree(policer_item);
12801	return err;
12802}
12803
12804static void
12805devlink_trap_policer_unregister(struct devlink *devlink,
12806				const struct devlink_trap_policer *policer)
12807{
12808	struct devlink_trap_policer_item *policer_item;
12809
12810	policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12811	if (WARN_ON_ONCE(!policer_item))
12812		return;
12813
12814	devlink_trap_policer_notify(devlink, policer_item,
12815				    DEVLINK_CMD_TRAP_POLICER_DEL);
12816	list_del(&policer_item->list);
12817	if (devlink->ops->trap_policer_fini)
12818		devlink->ops->trap_policer_fini(devlink, policer);
12819	kfree(policer_item);
12820}
12821
12822/**
12823 * devl_trap_policers_register - Register packet trap policers with devlink.
12824 * @devlink: devlink.
12825 * @policers: Packet trap policers.
12826 * @policers_count: Count of provided packet trap policers.
12827 *
12828 * Return: Non-zero value on failure.
12829 */
12830int
12831devl_trap_policers_register(struct devlink *devlink,
12832			    const struct devlink_trap_policer *policers,
12833			    size_t policers_count)
12834{
12835	int i, err;
12836
12837	devl_assert_locked(devlink);
12838	for (i = 0; i < policers_count; i++) {
12839		const struct devlink_trap_policer *policer = &policers[i];
12840
12841		if (WARN_ON(policer->id == 0 ||
12842			    policer->max_rate < policer->min_rate ||
12843			    policer->max_burst < policer->min_burst)) {
12844			err = -EINVAL;
12845			goto err_trap_policer_verify;
12846		}
12847
12848		err = devlink_trap_policer_register(devlink, policer);
12849		if (err)
12850			goto err_trap_policer_register;
12851	}
12852	return 0;
12853
12854err_trap_policer_register:
12855err_trap_policer_verify:
12856	for (i--; i >= 0; i--)
12857		devlink_trap_policer_unregister(devlink, &policers[i]);
12858	return err;
12859}
12860EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12861
12862/**
12863 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12864 * @devlink: devlink.
12865 * @policers: Packet trap policers.
12866 * @policers_count: Count of provided packet trap policers.
12867 */
12868void
12869devl_trap_policers_unregister(struct devlink *devlink,
12870			      const struct devlink_trap_policer *policers,
12871			      size_t policers_count)
12872{
12873	int i;
12874
12875	devl_assert_locked(devlink);
12876	for (i = policers_count - 1; i >= 0; i--)
12877		devlink_trap_policer_unregister(devlink, &policers[i]);
12878}
12879EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12880
12881static void __devlink_compat_running_version(struct devlink *devlink,
12882					     char *buf, size_t len)
12883{
12884	struct devlink_info_req req = {};
12885	const struct nlattr *nlattr;
12886	struct sk_buff *msg;
12887	int rem, err;
12888
12889	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12890	if (!msg)
12891		return;
12892
12893	req.msg = msg;
12894	err = devlink->ops->info_get(devlink, &req, NULL);
12895	if (err)
12896		goto free_msg;
12897
12898	nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12899		const struct nlattr *kv;
12900		int rem_kv;
12901
12902		if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12903			continue;
12904
12905		nla_for_each_nested(kv, nlattr, rem_kv) {
12906			if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12907				continue;
12908
12909			strlcat(buf, nla_data(kv), len);
12910			strlcat(buf, " ", len);
12911		}
12912	}
12913free_msg:
12914	nlmsg_free(msg);
12915}
12916
12917void devlink_compat_running_version(struct devlink *devlink,
12918				    char *buf, size_t len)
12919{
12920	if (!devlink->ops->info_get)
12921		return;
12922
12923	devl_lock(devlink);
12924	__devlink_compat_running_version(devlink, buf, len);
12925	devl_unlock(devlink);
12926}
12927
12928int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12929{
12930	struct devlink_flash_update_params params = {};
12931	int ret;
12932
12933	if (!devlink->ops->flash_update)
12934		return -EOPNOTSUPP;
12935
12936	ret = request_firmware(&params.fw, file_name, devlink->dev);
12937	if (ret)
12938		return ret;
12939
12940	devl_lock(devlink);
12941	devlink_flash_update_begin_notify(devlink);
12942	ret = devlink->ops->flash_update(devlink, &params, NULL);
12943	devlink_flash_update_end_notify(devlink);
12944	devl_unlock(devlink);
12945
12946	release_firmware(params.fw);
12947
12948	return ret;
12949}
12950
12951int devlink_compat_phys_port_name_get(struct net_device *dev,
12952				      char *name, size_t len)
12953{
12954	struct devlink_port *devlink_port;
12955
12956	/* RTNL mutex is held here which ensures that devlink_port
12957	 * instance cannot disappear in the middle. No need to take
12958	 * any devlink lock as only permanent values are accessed.
12959	 */
12960	ASSERT_RTNL();
12961
12962	devlink_port = dev->devlink_port;
12963	if (!devlink_port)
12964		return -EOPNOTSUPP;
12965
12966	return __devlink_port_phys_port_name_get(devlink_port, name, len);
12967}
12968
12969int devlink_compat_switch_id_get(struct net_device *dev,
12970				 struct netdev_phys_item_id *ppid)
12971{
12972	struct devlink_port *devlink_port;
12973
12974	/* Caller must hold RTNL mutex or reference to dev, which ensures that
12975	 * devlink_port instance cannot disappear in the middle. No need to take
12976	 * any devlink lock as only permanent values are accessed.
12977	 */
12978	devlink_port = dev->devlink_port;
12979	if (!devlink_port || !devlink_port->switch_port)
12980		return -EOPNOTSUPP;
12981
12982	memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
12983
12984	return 0;
12985}
12986
12987static void __net_exit devlink_pernet_pre_exit(struct net *net)
12988{
12989	struct devlink *devlink;
12990	u32 actions_performed;
12991	unsigned long index;
12992	int err;
12993
12994	/* In case network namespace is getting destroyed, reload
12995	 * all devlink instances from this namespace into init_net.
12996	 */
12997	devlinks_xa_for_each_registered_get(net, index, devlink) {
12998		WARN_ON(!(devlink->features & DEVLINK_F_RELOAD));
12999		mutex_lock(&devlink->lock);
13000		err = devlink_reload(devlink, &init_net,
13001				     DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
13002				     DEVLINK_RELOAD_LIMIT_UNSPEC,
13003				     &actions_performed, NULL);
13004		mutex_unlock(&devlink->lock);
13005		if (err && err != -EOPNOTSUPP)
13006			pr_warn("Failed to reload devlink instance into init_net\n");
13007		devlink_put(devlink);
13008	}
13009}
13010
13011static struct pernet_operations devlink_pernet_ops __net_initdata = {
13012	.pre_exit = devlink_pernet_pre_exit,
13013};
13014
13015static int __init devlink_init(void)
13016{
13017	int err;
13018
13019	err = genl_register_family(&devlink_nl_family);
13020	if (err)
13021		goto out;
13022	err = register_pernet_subsys(&devlink_pernet_ops);
13023
13024out:
13025	WARN_ON(err);
13026	return err;
13027}
13028
13029subsys_initcall(devlink_init);