cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

devlink.c (321827B)


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